// 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; using System.Collections.Generic; using System.Linq; using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using RepoTasks.ProjectModel; using RepoTasks.Utilities; namespace RepoTasks { public class AnalyzeBuildGraph : Task, ICancelableTask { private readonly CancellationTokenSource _cts = new CancellationTokenSource(); /// /// Repositories that we are building new versions of. /// [Required] public ITaskItem[] Solutions { get; set; } [Required] public string Properties { 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 /// [Output] public ITaskItem[] RepositoryBuildOrder { get; set; } public void Cancel() { _cts.Cancel(); } public override bool Execute() { var factory = new SolutionInfoFactory(Log, BuildEngine5); var props = MSBuildListSplitter.GetNamedProperties(Properties); Log.LogMessage(MessageImportance.High, $"Beginning cross-repo analysis on {Solutions.Length} solutions. Hang tight..."); var solutions = factory.Create(Solutions, props, _cts.Token); Log.LogMessage($"Found {solutions.Count} and {solutions.Sum(p => p.Projects.Count)} projects"); if (_cts.IsCancellationRequested) { return false; } PackagesProduced = solutions .Where(s => s.ShouldBuild) .SelectMany(p => p.Projects) .Where(p => p.IsPackable) .Select(p => new TaskItem(p.PackageId, new Hashtable { ["Version"] = p.PackageVersion })) .ToArray(); return !Log.HasLoggedErrors; } } }