78 lines
2.9 KiB
C#
78 lines
2.9 KiB
C#
// 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.Linq;
|
|
using RepoTools.BuildGraph;
|
|
using Microsoft.Build.Framework;
|
|
using Microsoft.Build.Utilities;
|
|
|
|
namespace RepoTasks
|
|
{
|
|
public class CalculateBuildGraph : Task
|
|
{
|
|
[Required]
|
|
public ITaskItem[] Repositories { get; set; }
|
|
|
|
/// <summary>
|
|
/// Directory that contains the package spec files.
|
|
/// </summary>
|
|
[Required]
|
|
public string PackageSpecsDirectory { get; set; }
|
|
|
|
/// <summary>
|
|
/// Default to use for packages that may be produced from nuspec, not csproj. (e.g. .Sources packages).
|
|
/// </summary>
|
|
[Required]
|
|
public string DefaultPackageVersion { get; set; }
|
|
|
|
/// <summary>
|
|
/// The repository at which to root the graph at
|
|
/// </summary>
|
|
public string StartGraphAt { get; set; }
|
|
|
|
[Output]
|
|
public ITaskItem[] RepositoriesToBuildInOrder { get; set; }
|
|
|
|
public override bool Execute()
|
|
{
|
|
var graphSpecProvider = new DependencyGraphSpecProvider(PackageSpecsDirectory.Trim());
|
|
|
|
var repositoryPaths = Repositories.Select(r => r.GetMetadata("RootPath")).ToList();
|
|
var repositories = Repository.ReadAllRepositories(repositoryPaths, graphSpecProvider);
|
|
|
|
var graph = GraphBuilder.Generate(repositories, StartGraphAt, Log);
|
|
var repositoriesWithOrder = new List<(ITaskItem repository, int order)>();
|
|
foreach (var repositoryTaskItem in Repositories)
|
|
{
|
|
var repositoryName = repositoryTaskItem.ItemSpec;
|
|
var graphNodeRepository = graph.FirstOrDefault(g => g.Repository.Name == repositoryName);
|
|
if (graphNodeRepository == null)
|
|
{
|
|
// StartGraphAt was specified so the graph is incomplete.
|
|
continue;
|
|
}
|
|
|
|
var order = TopologicalSort.GetOrder(graphNodeRepository);
|
|
repositoryTaskItem.SetMetadata("Order", order.ToString());
|
|
repositoriesWithOrder.Add((repositoryTaskItem, order));
|
|
}
|
|
|
|
Log.LogMessage(MessageImportance.High, "Repository build order:");
|
|
foreach (var buildGroup in repositoriesWithOrder.GroupBy(r => r.order).OrderBy(g => g.Key))
|
|
{
|
|
var buildGroupRepos = buildGroup.Select(b => b.repository.ItemSpec);
|
|
Log.LogMessage(MessageImportance.High, $"{buildGroup.Key.ToString().PadLeft(2, ' ')}: {string.Join(", ", buildGroupRepos)}");
|
|
}
|
|
|
|
RepositoriesToBuildInOrder = repositoriesWithOrder
|
|
.OrderBy(r => r.order)
|
|
.Select(r => r.repository)
|
|
.ToArray();
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|