diff --git a/global.json b/global.json index 6f51da4..4d464e8 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "2.1.500" + "version": "2.1.505" }, "msbuild-sdks": { "Microsoft.Build.Traversal": "1.0.45" diff --git a/src/Xamarin.MSBuild.Sdk/Sdk.targets b/src/Xamarin.MSBuild.Sdk/Sdk.targets index 2f83b18..aa3d3e9 100644 --- a/src/Xamarin.MSBuild.Sdk/Sdk.targets +++ b/src/Xamarin.MSBuild.Sdk/Sdk.targets @@ -37,6 +37,10 @@ + + + + @@ -49,6 +53,7 @@ + diff --git a/src/Xamarin.MSBuild.Sdk/Tasks/PrepareConsolidationProject.cs b/src/Xamarin.MSBuild.Sdk/Tasks/PrepareConsolidationProject.cs index 8a77a40..a2357b2 100644 --- a/src/Xamarin.MSBuild.Sdk/Tasks/PrepareConsolidationProject.cs +++ b/src/Xamarin.MSBuild.Sdk/Tasks/PrepareConsolidationProject.cs @@ -33,6 +33,9 @@ public sealed class PrepareConsolidationProject : Task [Output] public TaskItem[] ReferenceItems { get; set; } + [Output] + public TaskItem[] PackageReferenceItems { get; set; } + [Output] public TaskItem[] EmbeddedResourceItems { get; set; } @@ -53,23 +56,49 @@ public override bool Execute () var compileItems = new List (); var projectReferenceItems = new List (); var referenceItems = new List (); + var packageReferenceItems = new List (); var embeddedResourceItems = new List (); - var projectsToConsolidate = dependencyGraph - .TopologicallySortedProjects - .Where (project => { - if (ResolveFullPath (project.ProjectPath) == projectPath) - return false; + var projectsToConsolidate = new List (); + foreach (var project in dependencyGraph.TopologicallySortedProjects) { + if (ResolveFullPath (project.ProjectPath) == projectPath) + continue; + + if (string.IsNullOrEmpty (ConsolidationConditionMetadataName) + || project.ProjectReferenceItems.Any ( + pr => bool.TryParse ( + pr.GetMetadataValue (ConsolidationConditionMetadataName), + out var consolidate) && consolidate)) { + projectsToConsolidate.Add (project); + } else { + // Keep top-level ProjectReferences that are not marked for + // consolidation. Otherwise they get lost due to the removal + // step in the PrepareConsolidationProject target. + var projectDirectory = Path.GetDirectoryName (project.ProjectPath); + foreach (var item in project.ProjectReferenceItems) { + var itemSpec = item.EvaluatedInclude; + var itemSpecFullPath = ResolveFullPath ( + projectDirectory, + itemSpec); + var itemMetadata = GetItemMetadata (item); + + if (itemMetadata.Count == 0) + continue; + + if (!File.Exists (itemSpecFullPath)) + continue; - if (string.IsNullOrEmpty (ConsolidationConditionMetadataName)) - return true; + if (allItemSpecs.Contains (itemSpecFullPath)) + continue; - return project.ProjectReferenceItems.Any ( - pr => bool.TryParse ( - pr.GetMetadataValue (ConsolidationConditionMetadataName), - out var consolidate) && consolidate); - }) - .ToList (); + allItemSpecs.Add (itemSpecFullPath); + + projectReferenceItems.Add (new TaskItem ( + itemSpecFullPath, + itemMetadata)); + } + } + } foreach (var project in projectsToConsolidate) { var projectDirectory = Path.GetDirectoryName (project.ProjectPath); @@ -85,11 +114,7 @@ public override bool Execute () var itemSpecFullPath = ResolveFullPath ( projectDirectory, itemSpec); - - var itemMetadata = new Dictionary (StringComparer.OrdinalIgnoreCase); - - foreach (var metadata in item.Metadata) - itemMetadata.Add (metadata.Name, metadata.EvaluatedValue); + var itemMetadata = GetItemMetadata (item); switch (item.ItemType.ToLowerInvariant()) { case "compile": @@ -106,8 +131,15 @@ public override bool Execute () break; case "reference": + // Skip netstandard facades + if (itemMetadata.TryGetValue ("NuGetPackageId", out var packageId) + && packageId == "NETStandard.Library") + continue; collection = referenceItems; break; + case "packagereference": + collection = packageReferenceItems; + break; case "embeddedresource": collection = embeddedResourceItems; useItemSpecFullPath = true; @@ -150,10 +182,16 @@ public override bool Execute () CompileItems = compileItems.ToArray (); ProjectReferenceItems = projectReferenceItems.ToArray (); ReferenceItems = referenceItems.ToArray (); + PackageReferenceItems = packageReferenceItems.ToArray (); EmbeddedResourceItems = embeddedResourceItems.ToArray (); return true; + Dictionary GetItemMetadata (ProjectItem item) + => item.Metadata.ToDictionary ( + i => i.Name, + i => i.EvaluatedValue); + bool ShouldExcludeItem (ProjectItem item) => ConsolidateRemoveItemsRegex ?.Where (regexItem => string.Equals (