From a43fb2271e88fe19034fb9b922c6637d85b8fb6a Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 15 Sep 2017 13:17:49 -0700 Subject: [PATCH] Use artifact info to correctly analyze the packages produced from a repository --- build/repo.targets | 15 +++- build/tasks/AnalyzeBuildGraph.cs | 75 ++++++++++--------- build/tasks/BuildGraph/Repository.cs | 4 +- build/tasks/ProjectModel/PackageInfo.cs | 45 +++++++++++ .../tasks/ProjectModel/SolutionInfoFactory.cs | 2 +- 5 files changed, 98 insertions(+), 43 deletions(-) create mode 100644 build/tasks/ProjectModel/PackageInfo.cs diff --git a/build/repo.targets b/build/repo.targets index 0d387361d4..eca755d4ba 100644 --- a/build/repo.targets +++ b/build/repo.targets @@ -108,7 +108,14 @@ - + + + + + - + - - + diff --git a/build/tasks/AnalyzeBuildGraph.cs b/build/tasks/AnalyzeBuildGraph.cs index 1c94093ac0..401b2c21b0 100644 --- a/build/tasks/AnalyzeBuildGraph.cs +++ b/build/tasks/AnalyzeBuildGraph.cs @@ -9,6 +9,7 @@ using System.IO; using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; +using NuGet.Frameworks; using RepoTools.BuildGraph; using RepoTasks.ProjectModel; using RepoTasks.Utilities; @@ -25,17 +26,14 @@ namespace RepoTasks [Required] public ITaskItem[] Solutions { get; set; } + [Required] + public ITaskItem[] Artifacts { get; set; } + [Required] public string Properties { get; set; } public string StartGraphAt { get; set; } - /// - /// New packages we are compiling. Used in the pin tool. - /// - [Output] - public ITaskItem[] PackagesProduced { get; set; } - /// /// The order in which to build repositories /// @@ -49,6 +47,8 @@ namespace RepoTasks public override bool Execute() { + var packageArtifacts = GetPackageInfo(Artifacts); + var factory = new SolutionInfoFactory(Log, BuildEngine5); var props = MSBuildListSplitter.GetNamedProperties(Properties); @@ -63,8 +63,7 @@ namespace RepoTasks } EnsureConsistentGraph(solutions); - PackagesProduced = GetPackagesProduced(solutions); - RepositoryBuildOrder = GetRepositoryBuildOrder(solutions.Where(s => s.ShouldBuild)); + RepositoryBuildOrder = GetRepositoryBuildOrder(packageArtifacts, solutions.Where(s => s.ShouldBuild)); return !Log.HasLoggedErrors; } @@ -74,43 +73,47 @@ namespace RepoTasks // TODO } - private ITaskItem[] GetPackagesProduced(IEnumerable solutions) + private IEnumerable<(PackageInfo, string repoName)> GetPackageInfo(IEnumerable items) { - return solutions - .Where(s => s.ShouldBuild) - .SelectMany(p => p.Projects) - .Where(p => p.IsPackable) - .Select(p => new TaskItem(p.PackageId, new Hashtable + return items + .Where(a => "NuGetPackage".Equals(a.GetMetadata("ArtifactType"), StringComparison.OrdinalIgnoreCase)) + .Select(a => { - ["Version"] = p.PackageVersion - })) - .ToArray(); + var info = new PackageInfo( + a.GetMetadata("PackageId"), + a.GetMetadata("Version"), + string.IsNullOrEmpty(a.GetMetadata("TargetFramework")) + ? MSBuildListSplitter.SplitItemList(a.GetMetadata("TargetFramework")).Select(s => NuGetFramework.Parse(s)).ToArray() + : new [] { NuGetFramework.Parse(a.GetMetadata("TargetFramework")) }, + Path.GetDirectoryName(a.ItemSpec), + a.GetMetadata("PackageType")); + + var repoName = Path.GetFileName(a.GetMetadata("RepositoryRoot").TrimEnd(new [] { '\\', '/' })); + return (info, repoName); + }); } - private ITaskItem[] GetRepositoryBuildOrder(IEnumerable solutions) + private ITaskItem[] GetRepositoryBuildOrder(IEnumerable<(PackageInfo pkg, string repoName)> artifacts, IEnumerable solutions) { var repositories = solutions.Select(s => { var repoName = Path.GetFileName(Path.GetDirectoryName(s.FullPath)); var repo = new Repository(repoName); - repo.Projects = s.Projects - .Where(p => p.IsPackable) - .Select(p => - new Project(p.PackageId) - { - Repository = repo, - PackageReferences = new HashSet(p.Frameworks.SelectMany(f => f.Dependencies.Keys), StringComparer.OrdinalIgnoreCase), - }) - .ToList(); - repo.SupportProjects = s.Projects - .Where(p => !p.IsPackable) - .Select(p => - new Project(p.PackageId) - { - Repository = repo, - PackageReferences = new HashSet(p.Frameworks.SelectMany(f => f.Dependencies.Keys), StringComparer.OrdinalIgnoreCase), - }) - .ToList(); + var packages = artifacts.Where(a => a.repoName.Equals(repoName, StringComparison.OrdinalIgnoreCase)).ToList(); + + foreach (var proj in s.Projects) + { + var projectGroup = packages.Any(p => p.pkg.Id == proj.PackageId) + ? repo.Projects + : repo.SupportProjects; + + projectGroup.Add(new Project(proj.PackageId) + { + Repository = repo, + PackageReferences = new HashSet(proj.Frameworks.SelectMany(f => f.Dependencies.Keys), StringComparer.OrdinalIgnoreCase), + }); + } + return repo; }).ToList(); diff --git a/build/tasks/BuildGraph/Repository.cs b/build/tasks/BuildGraph/Repository.cs index ed7135491c..c1e3e5c619 100644 --- a/build/tasks/BuildGraph/Repository.cs +++ b/build/tasks/BuildGraph/Repository.cs @@ -22,9 +22,9 @@ namespace RepoTools.BuildGraph public string Name { get; private set; } - public IList Projects { get; set; } = new List(); + public IList Projects { get; } = new List(); - public IList SupportProjects { get; set; } = new List(); + public IList SupportProjects { get; } = new List(); public IEnumerable AllProjects => Projects.Concat(SupportProjects); diff --git a/build/tasks/ProjectModel/PackageInfo.cs b/build/tasks/ProjectModel/PackageInfo.cs new file mode 100644 index 0000000000..7293546c61 --- /dev/null +++ b/build/tasks/ProjectModel/PackageInfo.cs @@ -0,0 +1,45 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using NuGet.Frameworks; + +namespace RepoTasks.ProjectModel +{ + internal class PackageInfo + { + public PackageInfo(string id, + string version, + IReadOnlyList frameworks, + string source, + string packageType = "Dependency") + { + if (string.IsNullOrEmpty(id)) + { + throw new ArgumentException(nameof(id)); + } + + if (string.IsNullOrEmpty(version)) + { + throw new ArgumentException(nameof(version)); + } + + Id = id; + Version = version; + Frameworks = frameworks; + PackageType = packageType; + Source = source; + } + + public string Id { get; } + public string Version { get; } + public string PackageType { get; } + /// + /// Can be a https feed or a file path. May be null. + /// + public string Source { get; } + public IReadOnlyList Frameworks { get; } + } +} diff --git a/build/tasks/ProjectModel/SolutionInfoFactory.cs b/build/tasks/ProjectModel/SolutionInfoFactory.cs index 72601be2dc..9ea368cc0a 100644 --- a/build/tasks/ProjectModel/SolutionInfoFactory.cs +++ b/build/tasks/ProjectModel/SolutionInfoFactory.cs @@ -98,7 +98,7 @@ namespace RepoTasks.ProjectModel }); timer.Stop(); - _logger.LogMessage(MessageImportance.Normal, $"Finished design-time build in {timer.ElapsedMilliseconds}ms"); + _logger.LogMessage(MessageImportance.High, $"Finished design-time build in {timer.ElapsedMilliseconds}ms"); return solutions.ToArray(); }