dotnet-installer/src/dotnet/commands/dotnet-build/ProjectGraphCollector.cs

80 lines
3.1 KiB
C#
Raw Normal View History

// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
2016-04-17 20:53:49 -07:00
using System;
using System.Collections.Generic;
using NuGet.Frameworks;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.DotNet.Tools.Build
{
internal class ProjectGraphCollector
2016-04-17 20:53:49 -07:00
{
private readonly bool _collectDependencies;
2016-04-17 20:53:49 -07:00
private readonly Func<string, NuGetFramework, ProjectContext> _projectContextFactory;
public ProjectGraphCollector(bool collectDependencies,
Func<string, NuGetFramework, ProjectContext> projectContextFactory)
2016-04-17 20:53:49 -07:00
{
_collectDependencies = collectDependencies;
2016-04-17 20:53:49 -07:00
_projectContextFactory = projectContextFactory;
}
public IEnumerable<ProjectGraphNode> Collect(IEnumerable<ProjectContext> contexts)
{
foreach (var context in contexts)
{
var libraries = context.LibraryManager.GetLibraries();
var lookup = libraries.ToDictionary(l => l.Identity.Name);
var root = lookup[context.ProjectFile.Name];
yield return TraverseProject((ProjectDescription) root, lookup, context);
2016-04-17 20:53:49 -07:00
}
}
private ProjectGraphNode TraverseProject(ProjectDescription project, IDictionary<string, LibraryDescription> lookup, ProjectContext context = null)
{
var deps = new List<ProjectGraphNode>();
if (_collectDependencies)
2016-04-17 20:53:49 -07:00
{
foreach (var dependency in project.Dependencies)
2016-04-17 20:53:49 -07:00
{
var libraryDescription = lookup[dependency.Name];
if (libraryDescription.Identity.Type.Equals(LibraryType.Project))
{
deps.Add(TraverseProject((ProjectDescription)libraryDescription, lookup));
}
else
{
deps.AddRange(TraverseNonProject(libraryDescription, lookup));
}
2016-04-17 20:53:49 -07:00
}
}
var task = context != null ? Task.FromResult(context) : Task.Run(() => _projectContextFactory(project.Path, project.Framework));
return new ProjectGraphNode(task, deps, context != null);
}
private IEnumerable<ProjectGraphNode> TraverseNonProject(LibraryDescription root, IDictionary<string, LibraryDescription> lookup)
{
foreach (var dependency in root.Dependencies)
{
var libraryDescription = lookup[dependency.Name];
if (libraryDescription.Identity.Type.Equals(LibraryType.Project))
{
yield return TraverseProject((ProjectDescription)libraryDescription, lookup);
}
else
{
foreach(var node in TraverseNonProject(libraryDescription, lookup))
{
yield return node;
}
}
}
}
}
}