diff --git a/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture.cs b/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture.cs index 56a5fa470d..300a6a2d8d 100644 --- a/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture.cs +++ b/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -27,6 +27,7 @@ internal sealed class AssemblyInfoParserFixture public string Guid { get; set; } public string InformationalVersion { get; set; } public List InternalsVisibleTo { get; set; } + public List SupportedOSPlatform { get; set; } public string Product { get; set; } public string Title { get; set; } public string Trademark { get; set; } @@ -101,6 +102,10 @@ private void CreateAssemblyInfoOnDisk(FilePath path) { settings.InternalsVisibleTo = InternalsVisibleTo; } + if (SupportedOSPlatform != null) + { + settings.SupportedOSPlatform = SupportedOSPlatform; + } if (Product != null) { settings.Product = Product; diff --git a/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture_VB.cs b/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture_VB.cs index 4b780eb997..8df2b1114e 100644 --- a/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture_VB.cs +++ b/src/Cake.Common.Tests/Fixtures/AssemblyInfoParserFixture_VB.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -27,6 +27,7 @@ internal sealed class AssemblyInfoParserFixture_VB public string Guid { get; set; } public string InformationalVersion { get; set; } public List InternalsVisibleTo { get; set; } + public List SupportedOSPlatform { get; set; } public string Product { get; set; } public string Title { get; set; } public string Trademark { get; set; } @@ -101,6 +102,10 @@ private void CreateAssemblyInfoOnDisk(FilePath path) { settings.InternalsVisibleTo = InternalsVisibleTo; } + if (SupportedOSPlatform != null) + { + settings.SupportedOSPlatform = SupportedOSPlatform; + } if (Product != null) { settings.Product = Product; diff --git a/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoCreatorTests.cs b/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoCreatorTests.cs index 8c7ca3530c..fb2ba317a9 100644 --- a/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoCreatorTests.cs +++ b/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoCreatorTests.cs @@ -317,6 +317,38 @@ public void Should_Add_Multiple_InternalsVisibleTo_Attribute_If_Set() Assert.Contains("[assembly: InternalsVisibleTo(\"Assembly3.Tests\")]", result); } + [Fact] + public void Should_Add_SupportedOSPlatform_Attribute_If_Set() + { + // Given + var fixture = new AssemblyInfoFixture(); + fixture.Settings.SupportedOSPlatform = new List { "windows" }; + + // When + var result = fixture.CreateAndReturnContent(); + + // Then + Assert.Contains("using System.Runtime.Versioning;", result); + Assert.Contains("[assembly: SupportedOSPlatform(\"windows\")]", result); + } + + [Fact] + public void Should_Add_Multiple_SupportedOSPlatform_Attribute_If_Set() + { + // Given + var fixture = new AssemblyInfoFixture(); + fixture.Settings.SupportedOSPlatform = new Collection { "windows", "linux", "macos" }; + + // When + var result = fixture.CreateAndReturnContent(); + + // Then + Assert.Contains("using System.Runtime.Versioning;", result); + Assert.Contains("[assembly: SupportedOSPlatform(\"windows\")]", result); + Assert.Contains("[assembly: SupportedOSPlatform(\"linux\")]", result); + Assert.Contains("[assembly: SupportedOSPlatform(\"macos\")]", result); + } + [Fact] public void Should_Add_Configuration_Attribute_If_Set() { diff --git a/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoParserTests.cs b/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoParserTests.cs index bb009c530f..e69e8e29f4 100644 --- a/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoParserTests.cs +++ b/src/Cake.Common.Tests/Unit/Solution/Project/Properties/AssemblyInfoParserTests.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -301,6 +301,44 @@ public void Should_Read_InternalsVisibleTo(bool extraWhiteSpaces) Assert.Equal("Cake.Common.Tests", result.InternalsVisibleTo.ElementAt(1)); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Should_Read_SupportedOSPlatform(bool extraWhiteSpaces) + { + // Given + var fixture = new AssemblyInfoParserFixture(); + fixture.ExtraWhiteSpaces = extraWhiteSpaces; + fixture.SupportedOSPlatform = new List { "windows" }; + + // When + var result = fixture.Parse(); + + // Then + Assert.Single(result.SupportedOSPlatform, x => x == "windows"); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Should_Read_Multiple_SupportedOSPlatform(bool extraWhiteSpaces) + { + // Given + var fixture = new AssemblyInfoParserFixture(); + fixture.ExtraWhiteSpaces = extraWhiteSpaces; + fixture.SupportedOSPlatform = new List { "windows", "linux", "macos" }; + + // When + var result = fixture.Parse(); + + // Then + Assert.Collection( + result.SupportedOSPlatform, + item => Assert.Equal("windows", item), + item => Assert.Equal("linux", item), + item => Assert.Equal("macos", item)); + } + [Theory] [InlineData("Cake", "Cake", true)] [InlineData("Cake", "Cake", false)] diff --git a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreator.cs b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreator.cs index f5d323bbdb..c3fe9a551e 100644 --- a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreator.cs +++ b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreator.cs @@ -126,6 +126,14 @@ public void Create(FilePath outputPath, AssemblyInfoSettings settings, writer.WriteLine(); } + if (data.SupportedOSPlatform.Count > 0) + { + foreach (var attribute in data.SupportedOSPlatform) + { + writer.WriteLine(string.Format(attributeFormat, attribute)); + } + } + if (data.CustomAttributes.Count > 0) { writer.WriteLine(comment + " Custom Attributes"); diff --git a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreatorData.cs b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreatorData.cs index ae9ea91319..2146be54a3 100644 --- a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreatorData.cs +++ b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoCreatorData.cs @@ -17,6 +17,7 @@ internal sealed class AssemblyInfoCreatorData private readonly Dictionary _metadatattributes; private readonly HashSet _namespaces; private readonly HashSet _internalVisibleTo; + private readonly HashSet _supportedOSPlatform; private readonly string _trueStringValue; private readonly string _falseStringValue; @@ -30,6 +31,8 @@ internal sealed class AssemblyInfoCreatorData public ISet InternalVisibleTo => _internalVisibleTo; + public ISet SupportedOSPlatform => _supportedOSPlatform; + public AssemblyInfoCreatorData(AssemblyInfoSettings settings, bool isVisualBasicAssemblyInfoFile) { _dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -37,6 +40,7 @@ public AssemblyInfoCreatorData(AssemblyInfoSettings settings, bool isVisualBasic _metadatattributes = new Dictionary(StringComparer.OrdinalIgnoreCase); _namespaces = new HashSet(StringComparer.OrdinalIgnoreCase); _internalVisibleTo = new HashSet(StringComparer.OrdinalIgnoreCase); + _supportedOSPlatform = new HashSet(StringComparer.OrdinalIgnoreCase); _falseStringValue = isVisualBasicAssemblyInfoFile ? "False" : "false"; _trueStringValue = isVisualBasicAssemblyInfoFile ? "True" : "true"; @@ -68,6 +72,18 @@ public AssemblyInfoCreatorData(AssemblyInfoSettings settings, bool isVisualBasic _namespaces.Add("System.Runtime.CompilerServices"); } } + if (settings.SupportedOSPlatform != null) + { + foreach (var item in settings.SupportedOSPlatform.Where(item => item != null)) + { + _supportedOSPlatform.Add(string.Concat("SupportedOSPlatform(\"", item.UnQuote(), "\")")); + } + + if (_supportedOSPlatform.Count > 0) + { + _namespaces.Add("System.Runtime.Versioning"); + } + } if (settings.CustomAttributes != null) { foreach (var item in settings.CustomAttributes.Where(item => item != null)) diff --git a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParseResult.cs b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParseResult.cs index 68625181f1..0f7de9a642 100644 --- a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParseResult.cs +++ b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParseResult.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -13,6 +13,7 @@ namespace Cake.Common.Solution.Project.Properties public sealed class AssemblyInfoParseResult { private readonly List _internalsVisibleTo; + private readonly List _supportedOSPlatform; /// /// Gets a value indicating whether the assembly is CLS compliant. @@ -102,6 +103,12 @@ public sealed class AssemblyInfoParseResult /// The assemblies that internals are visible to. public ICollection InternalsVisibleTo => _internalsVisibleTo; + /// + /// Gets the operating system(s) or platform(s) which this assembly supports. + /// + /// The name(s), and optional version(s), of the supported platform(s). + public ICollection SupportedOSPlatform => _supportedOSPlatform; + /// /// Initializes a new instance of the class. /// @@ -119,6 +126,7 @@ public sealed class AssemblyInfoParseResult /// The assembly trademark attribute. /// The assembly version. /// The assemblies that internals are visible to. + /// The operating system(s) or platform(s) which this assembly supports. public AssemblyInfoParseResult(string clsCompliant, string company, string comVisible, @@ -132,7 +140,8 @@ public AssemblyInfoParseResult(string clsCompliant, string title, string trademark, string assemblyVersion, - IEnumerable internalsVisibleTo) + IEnumerable internalsVisibleTo, + IEnumerable supportedOSPlatform) { ClsCompliant = !string.IsNullOrWhiteSpace(clsCompliant) && bool.Parse(clsCompliant); Company = company ?? string.Empty; @@ -148,6 +157,7 @@ public AssemblyInfoParseResult(string clsCompliant, Trademark = trademark ?? string.Empty; AssemblyVersion = assemblyVersion ?? string.Empty; _internalsVisibleTo = new List(internalsVisibleTo ?? Enumerable.Empty()); + _supportedOSPlatform = new List(supportedOSPlatform ?? Enumerable.Empty()); } } } \ No newline at end of file diff --git a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParser.cs b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParser.cs index 4fe4f8be1d..3fd0de5415 100644 --- a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParser.cs +++ b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoParser.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -88,7 +88,8 @@ public AssemblyInfoParseResult Parse(FilePath assemblyInfoPath) ParseSingle(quotedPattern, "AssemblyTitle", content), ParseSingle(quotedPattern, "AssemblyTrademark", content), ParseSingle(quotedPattern, "AssemblyVersion", content) ?? DefaultVersion, - ParseMultiple(quotedPattern, "InternalsVisibleTo", content)); + ParseMultiple(quotedPattern, "InternalsVisibleTo", content), + ParseMultiple(quotedPattern, "SupportedOSPlatform", content)); } } diff --git a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoSettings.cs b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoSettings.cs index 356aa89eb1..e8593a957b 100644 --- a/src/Cake.Common/Solution/Project/Properties/AssemblyInfoSettings.cs +++ b/src/Cake.Common/Solution/Project/Properties/AssemblyInfoSettings.cs @@ -89,6 +89,12 @@ public sealed class AssemblyInfoSettings /// The name(s) of the assembly(s). public ICollection InternalsVisibleTo { get; set; } + /// + /// Gets or sets the operating system(s) or platform(s) which this assembly supports. + /// + /// The name(s), and optional version(s), of the supported platform(s). + public ICollection SupportedOSPlatform { get; set; } + /// /// Gets or sets the configuration of the assembly. /// diff --git a/tests/integration/Cake.Common/Solution/Project/Properties/AssemblyInfoAliases.cake b/tests/integration/Cake.Common/Solution/Project/Properties/AssemblyInfoAliases.cake index b43e7ca11c..f7ad04cd12 100644 --- a/tests/integration/Cake.Common/Solution/Project/Properties/AssemblyInfoAliases.cake +++ b/tests/integration/Cake.Common/Solution/Project/Properties/AssemblyInfoAliases.cake @@ -28,7 +28,8 @@ Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.ParseAssemblyI "Miny", "Moe", "Spacey" - } + }, + supportedOSPlatform: new string[] { } ); // When @@ -49,6 +50,7 @@ Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.ParseAssemblyI Assert.Equal(expect.Trademark, result.Trademark); Assert.Equal(expect.AssemblyVersion, result.AssemblyVersion); Assert.Equal(expect.InternalsVisibleTo, result.InternalsVisibleTo); + Assert.Equal(expect.SupportedOSPlatform, result.SupportedOSPlatform); }); Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfo") @@ -89,6 +91,58 @@ Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssembly Assert.True(FileHashEquals(expectFile, file)); }); +Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfoWithSupportedOSPlatform") + .Does(() => +{ + // Given + var path = Paths.Temp.Combine("./Cake.Common/Solution/Project/Properties/SupportedOSPlatform"); + var file = path.CombineWithFilePath("AssemblyInfoWithSupportedOSPlatform.cs"); + EnsureDirectoryExist(path); + var settings = new AssemblyInfoSettings { + Company = "The Company", + Product = "The Product", + Version = "1.0", + SupportedOSPlatform = new [] { "windows" } + }; + + // When + CreateAssemblyInfo(file, settings); + + // Then + Assert.True(System.IO.File.Exists(file.FullPath)); + var content = System.IO.File.ReadAllText(file.FullPath); + Assert.Contains("using System.Runtime.Versioning;", content); + Assert.Contains("[assembly: SupportedOSPlatform(\"windows\")]", content); +}); + +Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfoWithMultipleSupportedOSPlatform") + .Does(() => +{ + // Given + var path = Paths.Temp.Combine("./Cake.Common/Solution/Project/Properties/MultipleSupportedOSPlatform"); + var file = path.CombineWithFilePath("AssemblyInfoWithMultipleSupportedOSPlatform.cs"); + EnsureDirectoryExist(path); + var settings = new AssemblyInfoSettings { + Company = "The Company", + Product = "The Product", + Version = "1.0", + SupportedOSPlatform = new [] { "windows", "linux", "macos" } + }; + + // When + CreateAssemblyInfo(file, settings); + + // Then + Assert.True(System.IO.File.Exists(file.FullPath)); + var content = System.IO.File.ReadAllText(file.FullPath); + Assert.Contains("using System.Runtime.Versioning;", content); + Assert.Contains("[assembly: SupportedOSPlatform(\"windows\")]", content); + Assert.Contains("[assembly: SupportedOSPlatform(\"linux\")]", content); + Assert.Contains("[assembly: SupportedOSPlatform(\"macos\")]", content); +}); + Task("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases") .IsDependentOn("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.ParseAssemblyInfo") - .IsDependentOn("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfo"); \ No newline at end of file + .IsDependentOn("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfo") + .IsDependentOn("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfoWithSupportedOSPlatform") + .IsDependentOn("Cake.Common.Solution.Project.Properties.AssemblyInfoAliases.CreateAssemblyInfoWithMultipleSupportedOSPlatform"); \ No newline at end of file