Use artifact info to correctly analyze the packages produced from a repository

This commit is contained in:
Nate McMaster 2017-09-15 13:17:49 -07:00
parent 8276bd163e
commit a43fb2271e
5 changed files with 98 additions and 43 deletions

View File

@ -108,7 +108,14 @@
<Target Name="BuildRepositories"
DependsOnTargets="_PrepareRepositories;_CreateRepositoriesListWithCommits;_UpdateNuGetConfig;Graph;_BuildRepositories" />
<Target Name="ResolveSolutions" DependsOnTargets="_PrepareRepositories">
<Target Name="ResolveRepoInfo" DependsOnTargets="_PrepareRepositories">
<MSBuild Projects="$(MSBuildProjectFullPath)"
Targets="GetArtifactInfo"
Properties="RepositoryRoot=$(_CloneRepositoryRoot)%(Repository.Identity)\;Configuration=$(Configuration);BuildNumber=$(BuildNumber)"
ContinueOnError="WarnAndContinue">
<Output TaskParameter="TargetOutputs" ItemName="ArtifactInfo" />
</MSBuild>
<MSBuild Projects="$(MSBuildProjectFullPath)"
Targets="ResolveSolutions"
Properties="RepositoryRoot=$(_CloneRepositoryRoot)%(Repository.Identity)\;Configuration=$(Configuration);BuildNumber=$(BuildNumber)"
@ -132,16 +139,16 @@
<Error Text="No solutions were found in '$(_CloneRepositoryRoot)'" Condition="@(Solution->Count()) == 0" />
</Target>
<Target Name="Graph" DependsOnTargets="ResolveSolutions">
<Target Name="Graph" DependsOnTargets="ResolveRepoInfo">
<RepoTasks.AnalyzeBuildGraph
Solutions="@(Solution)"
Artifacts="@(ArtifactInfo)"
Properties="Configuration=$(Configuration);BuildNumber=$(BuildNumber)">
<Output TaskParameter="PackagesProduced" ItemName="PackagesProduced" />
<Output TaskParameter="RepositoryBuildOrder" ItemName="RepositoryBuildOrder" />
</RepoTasks.AnalyzeBuildGraph>
<Message Text="Packages that will be produced:" Importance="High" />
<Message Text=" - %(PackagesProduced.Identity)/%(Version)" Importance="High" />
<Message Text=" - %(ArtifactInfo.PackageId)/%(Version)" Importance="High" Condition="'%(ArtifactType)' == 'NuGetPackage'" />
</Target>
<Target Name="_UpdateNuGetConfig">

View File

@ -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; }
/// <summary>
/// New packages we are compiling. Used in the pin tool.
/// </summary>
[Output]
public ITaskItem[] PackagesProduced { get; set; }
/// <summary>
/// The order in which to build repositories
/// </summary>
@ -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<SolutionInfo> solutions)
private IEnumerable<(PackageInfo, string repoName)> GetPackageInfo(IEnumerable<ITaskItem> 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<SolutionInfo> solutions)
private ITaskItem[] GetRepositoryBuildOrder(IEnumerable<(PackageInfo pkg, string repoName)> artifacts, IEnumerable<SolutionInfo> 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<string>(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<string>(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<string>(proj.Frameworks.SelectMany(f => f.Dependencies.Keys), StringComparer.OrdinalIgnoreCase),
});
}
return repo;
}).ToList();

View File

@ -22,9 +22,9 @@ namespace RepoTools.BuildGraph
public string Name { get; private set; }
public IList<Project> Projects { get; set; } = new List<Project>();
public IList<Project> Projects { get; } = new List<Project>();
public IList<Project> SupportProjects { get; set; } = new List<Project>();
public IList<Project> SupportProjects { get; } = new List<Project>();
public IEnumerable<Project> AllProjects => Projects.Concat(SupportProjects);

View File

@ -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<NuGetFramework> 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; }
/// <summary>
/// Can be a https feed or a file path. May be null.
/// </summary>
public string Source { get; }
public IReadOnlyList<NuGetFramework> Frameworks { get; }
}
}

View File

@ -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();
}