133 lines
5.0 KiB
C#
133 lines
5.0 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.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using NuGet.LibraryModel;
|
|
using NuGet.ProjectModel;
|
|
|
|
namespace RepoTools.BuildGraph
|
|
{
|
|
[DebuggerDisplay("{Name}")]
|
|
public class Repository : IEquatable<Repository>
|
|
{
|
|
public Repository(string name)
|
|
{
|
|
Name = name;
|
|
}
|
|
|
|
public string Name { get; private set; }
|
|
|
|
public IList<Project> Projects { get; } = new List<Project>();
|
|
|
|
public IList<Project> SupportProjects { get; } = new List<Project>();
|
|
|
|
public IEnumerable<Project> AllProjects => Projects.Concat(SupportProjects);
|
|
|
|
public static IList<Repository> ReadAllRepositories(IList<string> repositoryPaths, DependencyGraphSpecProvider provider)
|
|
{
|
|
var repositories = new Repository[repositoryPaths.Count];
|
|
|
|
Parallel.For(0, repositoryPaths.Count, new ParallelOptions { MaxDegreeOfParallelism = 6 }, i =>
|
|
{
|
|
var repositoryPath = repositoryPaths[i];
|
|
var repositoryName = Path.GetFileName(repositoryPath.TrimEnd(new [] { '\\', '/' }));
|
|
var repository = Read(provider, repositoryName, repositoryPath);
|
|
repositories[i] = repository;
|
|
});
|
|
|
|
return repositories;
|
|
}
|
|
|
|
public bool Equals(Repository other) => string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
|
|
|
|
public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Name);
|
|
|
|
private static Repository Read(DependencyGraphSpecProvider provider, string name, string repositoryPath)
|
|
{
|
|
var repository = new Repository(name);
|
|
|
|
ReadSharedSourceProjects(Path.Combine(repositoryPath, "shared"), repository, repository.Projects);
|
|
|
|
var srcDirectory = Path.GetFullPath(Path.Combine(repositoryPath, "src"))
|
|
.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
|
|
|
var solutionFiles = Directory.EnumerateFiles(repositoryPath, "*.sln");
|
|
foreach (var file in solutionFiles)
|
|
{
|
|
var spec = provider.GetDependencyGraphSpec(name, file);
|
|
if (spec == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var projects = spec.Projects.OrderBy(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ? 0 : 1);
|
|
foreach (var specProject in projects)
|
|
{
|
|
var projectPath = Path.GetFullPath(specProject.FilePath)
|
|
.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
|
|
|
var projectGroup = projectPath.StartsWith(srcDirectory, StringComparison.OrdinalIgnoreCase) ?
|
|
repository.Projects :
|
|
repository.SupportProjects;
|
|
|
|
var project = projectGroup.FirstOrDefault(f => f.Path == specProject.FilePath);
|
|
if (project == null)
|
|
{
|
|
project = new Project(specProject.Name)
|
|
{
|
|
Repository = repository,
|
|
Path = specProject.FilePath,
|
|
Version = specProject.Version?.ToString(),
|
|
};
|
|
|
|
projectGroup.Add(project);
|
|
}
|
|
|
|
foreach (var package in GetPackageReferences(specProject))
|
|
{
|
|
project.PackageReferences.Add(package);
|
|
}
|
|
}
|
|
}
|
|
|
|
return repository;
|
|
}
|
|
|
|
private static List<string> GetPackageReferences(PackageSpec specProject)
|
|
{
|
|
var allDependencies = Enumerable.Concat(
|
|
specProject.Dependencies,
|
|
specProject.TargetFrameworks.SelectMany(tfm => tfm.Dependencies))
|
|
.Distinct();
|
|
|
|
var packageReferences = allDependencies
|
|
.Where(d => d.LibraryRange.TypeConstraintAllows(LibraryDependencyTarget.Package))
|
|
.Select(d => d.Name)
|
|
.ToList();
|
|
return packageReferences;
|
|
}
|
|
|
|
private static void ReadSharedSourceProjects(string sharedSourceProjectsRoot, Repository repository, IList<Project> projects)
|
|
{
|
|
if (!Directory.Exists(sharedSourceProjectsRoot))
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (var directory in new DirectoryInfo(sharedSourceProjectsRoot).EnumerateDirectories())
|
|
{
|
|
var project = new Project(directory.Name)
|
|
{
|
|
Repository = repository,
|
|
};
|
|
projects.Add(project);
|
|
}
|
|
}
|
|
}
|
|
}
|