diff --git a/src/installer/pkg/projects/Directory.Build.targets b/src/installer/pkg/projects/Directory.Build.targets index 8d9d6a8e880a6c71fcf4714de7dff9945ec0fd97..a205a1744603ce1116ac9d0e8d53f1fa274b109c 100644 --- a/src/installer/pkg/projects/Directory.Build.targets +++ b/src/installer/pkg/projects/Directory.Build.targets @@ -297,7 +297,7 @@ diff --git a/src/installer/pkg/projects/windowsdesktop/pkg/Directory.Build.props b/src/installer/pkg/projects/windowsdesktop/pkg/Directory.Build.props index ad2d5e57756fc1d8e46bebd91533925ad12961b4..03937b9ac6c39df4bf2ec4b4f77dbb2002d5587e 100644 --- a/src/installer/pkg/projects/windowsdesktop/pkg/Directory.Build.props +++ b/src/installer/pkg/projects/windowsdesktop/pkg/Directory.Build.props @@ -19,48 +19,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs b/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs index db9b4f3b21087a5bf26f8a45fc1d25a98d60cfdf..dc5deffccb95c9148c640dfe90a0fa946acb7267 100644 --- a/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs +++ b/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs @@ -122,6 +122,16 @@ public void HasGoodPlatformManifest() Assert.Contains(".dll", platformManifestContent); } + public string ReadEntryContent(string entry) + { + return ReadEntryContent(_reader.GetEntry(entry)); + } + + public XDocument ReadEntryXDocument(string entry) + { + return ReadEntryXDocument(_reader.GetEntry(entry)); + } + private void IsFrameworkPack() { Assert.Empty(_reader.GetPackageDependencies()); diff --git a/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/WindowsDesktopTests.cs b/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/WindowsDesktopTests.cs index 243e400da5454505adebb989751949ff1e7ea12a..375539d9a00feb636a8cfee01e571418df2c5ab1 100644 --- a/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/WindowsDesktopTests.cs +++ b/src/installer/test/Microsoft.DotNet.CoreSetup.Packaging.Tests/WindowsDesktopTests.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information. using Microsoft.DotNet.CoreSetup.Test; +using System; using System.Linq; +using System.Xml.Linq; using Xunit; namespace Microsoft.DotNet.CoreSetup.Packaging.Tests @@ -39,6 +41,32 @@ public void WindowsDesktopTargetingPackIsValid() } } + [Fact] + public void WindowsDesktopFrameworkListHasClassifications() + { + using (var tester = NuGetArtifactTester.OpenOrNull( + dirs, + "Microsoft.WindowsDesktop.App.Ref")) + { + // Let other test case handle if this is OK. + if (tester == null) + { + return; + } + + XDocument fxList = tester.ReadEntryXDocument("data/FrameworkList.xml"); + var files = fxList.Element("FileList").Elements("File").ToArray(); + + // Sanity check: did any elements we expect make it into the final file? + foreach (var attributeName in new[] { "Profile", "ReferencedByDefault" }) + { + Assert.True( + files.Any(x => !string.IsNullOrEmpty(x.Attribute(attributeName)?.Value)), + $"Can't find a non-empty '{attributeName}' attribute in framework list."); + } + } + } + [Fact] public void WindowsDesktopRuntimePackIsValid() { diff --git a/tools-local/tasks/CreateFrameworkListFile.cs b/tools-local/tasks/CreateFrameworkListFile.cs index 22d4e41ead5d08ae71076c3fa6512ec47a83e903..36a3dd59386c08416d9cc599c6d7b34aac3d09f4 100644 --- a/tools-local/tasks/CreateFrameworkListFile.cs +++ b/tools-local/tasks/CreateFrameworkListFile.cs @@ -20,23 +20,26 @@ public class CreateFrameworkListFile : BuildTask public ITaskItem[] Files { get; set; } /// - /// A list of assembly names with Profile classifications. A Profile="%(Profile)" attribute - /// is set in the framework list for the matching Files item if %(Profile) contains text. + /// A list of assembly names with classification info such as Profile. A + /// Profile="%(Profile)" attribute is included in the framework list for the matching Files + /// item if %(Profile) contains text. /// - /// If *any* FileProfiles are passed: + /// If *any* FileClassifications are passed: /// /// *Every* file that ends up listed in the framework list must have a matching - /// FileProfile, even if %(Profile) is not set. + /// FileClassification. /// - /// Additionally, every FileProfile must find exactly one File. + /// Additionally, every FileClassification must find exactly one File. /// /// This task fails if the conditions aren't met. This ensures the classification doesn't /// become out of date when the list of files changes. /// /// %(Identity): Assembly name (including ".dll"). /// %(Profile): List of profiles that apply, semicolon-delimited. + /// %(ReferencedByDefault): Empty (default) or "true"/"false". Indicates whether this file + /// should be referenced by default when the SDK uses this framework. /// - public ITaskItem[] FileProfiles { get; set; } + public ITaskItem[] FileClassifications { get; set; } [Required] public string TargetFile { get; set; } @@ -59,13 +62,13 @@ public override bool Execute() var frameworkManifest = new XElement("FileList", rootAttributes); - Dictionary fileProfileLookup = FileProfiles + Dictionary fileClassLookup = FileClassifications ?.ToDictionary( item => item.ItemSpec, - item => item.GetMetadata("Profile"), + item => item, StringComparer.OrdinalIgnoreCase); - var usedFileProfiles = new HashSet(); + var usedFileClasses = new HashSet(); foreach (var f in Files .Where(IsTargetPathIncluded) @@ -157,31 +160,40 @@ public override bool Execute() element.Add(new XAttribute("FileVersion", f.FileVersion)); - if (fileProfileLookup != null) + if (fileClassLookup != null) { - if (fileProfileLookup.TryGetValue(f.Filename, out string profile)) + if (fileClassLookup.TryGetValue(f.Filename, out ITaskItem classItem)) { + string profile = classItem.GetMetadata("Profile"); + if (!string.IsNullOrEmpty(profile)) { element.Add(new XAttribute("Profile", profile)); } - usedFileProfiles.Add(f.Filename); + string referencedByDefault = classItem.GetMetadata("ReferencedByDefault"); + + if (!string.IsNullOrEmpty(referencedByDefault)) + { + element.Add(new XAttribute("ReferencedByDefault", referencedByDefault)); + } + + usedFileClasses.Add(f.Filename); } else { - Log.LogError($"File matches no profile classification: {f.Filename}"); + Log.LogError($"File matches no classification: {f.Filename}"); } } frameworkManifest.Add(element); } - foreach (var unused in fileProfileLookup - ?.Keys.Except(usedFileProfiles).OrderBy(p => p) + foreach (var unused in fileClassLookup + ?.Keys.Except(usedFileClasses).OrderBy(p => p) ?? Enumerable.Empty()) { - Log.LogError($"Profile classification matches no files: {unused}"); + Log.LogError($"Classification matches no files: {unused}"); } Directory.CreateDirectory(Path.GetDirectoryName(TargetFile));