Merge remote-tracking branch 'origin/rel/2.0.0' into dev
This commit is contained in:
Коммит
2936763647
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" />
|
||||
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
|
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildGraph", "tools\BuildGraph\BuildGraph.csproj", "{B0621D49-4770-4552-9425-D6BD2CF0FB50}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PinVersions", "tools\PinVersions\PinVersions.csproj", "{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{085280EC-7055-426A-BF9C-1B692B9599AB}"
|
||||
|
@ -18,10 +16,6 @@ Global
|
|||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B0621D49-4770-4552-9425-D6BD2CF0FB50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B0621D49-4770-4552-9425-D6BD2CF0FB50}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B0621D49-4770-4552-9425-D6BD2CF0FB50}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B0621D49-4770-4552-9425-D6BD2CF0FB50}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
|
@ -32,7 +32,7 @@ cd $PSScriptRoot
|
|||
|
||||
$repoFolder = $PSScriptRoot
|
||||
$env:REPO_FOLDER = $repoFolder
|
||||
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
||||
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip"
|
||||
if ($env:KOREBUILD_ZIP)
|
||||
{
|
||||
$koreBuildZip=$env:KOREBUILD_ZIP
|
||||
|
|
2
build.sh
2
build.sh
|
@ -2,7 +2,7 @@
|
|||
repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd $repoFolder
|
||||
|
||||
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
||||
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/rel/2.0.0.zip"
|
||||
if [ ! -z $KOREBUILD_ZIP ]; then
|
||||
koreBuildZip=$KOREBUILD_ZIP
|
||||
fi
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
<Project>
|
||||
<Import Project="$(_BuildGraphFile)" />
|
||||
|
||||
<Target Name="BuildRepositories">
|
||||
<Target Name="_BuildRepositories">
|
||||
<ItemGroup>
|
||||
<BatchedRepository Include="$(MSBuildProjectFullPath)">
|
||||
<BuildGroup>%(RepositoryToBuildInOrder.Order)</BuildGroup>
|
||||
<Repository>%(RepositoryToBuildInOrder.Identity)</Repository>
|
||||
<AdditionalProperties>
|
||||
RepositoryToBuild=%(RepositoryToBuildInOrder.Identity);
|
||||
BuildRepositoryRoot=$(_CloneRepositoryRoot)%(RepositoryToBuildInOrder.Identity)\
|
||||
BuildRepositoryRoot=%(RepositoryToBuildInOrder.RepositoryPath)\;
|
||||
CommitHash=%(RepositoryToBuildInOrder.Commit)
|
||||
</AdditionalProperties>
|
||||
</BatchedRepository>
|
||||
</ItemGroup>
|
||||
|
@ -18,26 +17,6 @@
|
|||
<BatchBuilds Condition="'$(BatchBuilds)'==''">false</BatchBuilds>
|
||||
</PropertyGroup>
|
||||
|
||||
<Message
|
||||
Text="Building repositories in the following batches:"
|
||||
Importance="High"
|
||||
Condition="'$(BatchBuilds)'=='true'" />
|
||||
|
||||
<Message
|
||||
Text="%(BatchedRepository.BuildGroup): @(BatchedRepository -> '%(Repository)', ', ')"
|
||||
Importance="High"
|
||||
Condition="'$(BatchBuilds)'=='true'" />
|
||||
|
||||
<Message
|
||||
Text="Building repositories in the following order:"
|
||||
Importance="High"
|
||||
Condition="'$(BatchBuilds)'!='true'" />
|
||||
|
||||
<Message
|
||||
Text="%(BatchedRepository.Repository)"
|
||||
Importance="High"
|
||||
Condition="'$(BatchBuilds)'!='true'" />
|
||||
|
||||
<MSBuild
|
||||
Projects="@(BatchedRepository)"
|
||||
BuildInParallel="$(BatchBuilds)"
|
||||
|
@ -48,6 +27,9 @@
|
|||
|
||||
<Target Name="_BuildRepository" DependsOnTargets="_PinVersions">
|
||||
<PropertyGroup>
|
||||
<!-- If there are duplicate properties, the properties which are defined later in the order would override the earlier ones -->
|
||||
<RepositoryBuildArguments>$(RepositoryBuildArguments) /p:BuildNumber=$(BuildNumber) /p:Configuration=$(Configuration) /p:CommitHash=$(CommitHash)</RepositoryBuildArguments>
|
||||
|
||||
<BuildArguments>$(_RepositoryBuildTargets) $(RepositoryBuildArguments)</BuildArguments>
|
||||
<RepositoryArtifactsRoot>$(BuildRepositoryRoot)artifacts</RepositoryArtifactsRoot>
|
||||
<RepositoryArtifactsBuildDirectory>$(RepositoryArtifactsRoot)\build\</RepositoryArtifactsBuildDirectory>
|
||||
|
@ -83,26 +65,27 @@
|
|||
|
||||
<Copy
|
||||
SourceFiles="@(RepositoryArtifacts)"
|
||||
DestinationFolder="$(UniverseBuildDir)" />
|
||||
DestinationFolder="$(BuildDir)" />
|
||||
|
||||
<Move
|
||||
SourceFiles="@(RepositoryMSBuildArtifacts)"
|
||||
DestinationFolder="$(UniverseMSBuildDir)\$(RepositoryToBuild)\%(RecursiveDir)" />
|
||||
DestinationFolder="$(ArtifactsDir)msbuild\$(RepositoryToBuild)\%(RecursiveDir)" />
|
||||
|
||||
<Message Text="Publishing the following packages to the volatile feed: @(RepositoryNupkgs -> '%(Filename)%(Extension)', ', ')"
|
||||
Condition="'$(PublishPackages)'=='true' AND '@(RepositoryNupkgs)' != ''" />
|
||||
|
||||
<Exec
|
||||
Command="$(DotNetPath) $(PackagePublisherPath) -d $(RepositoryArtifactsBuildDirectory) -f $(NuGetPublishVolatileFeed)"
|
||||
Command="$(DotNetPath) $(PackagePublisherNetCoreApp) -d $(RepositoryArtifactsBuildDirectory) -f $(NuGetPublishVolatileFeed)"
|
||||
Condition="'$(PublishPackages)'=='true' AND '@(RepositoryNupkgs)' != ''" />
|
||||
|
||||
<Message Text="============ Done building $(RepositoryToBuild) ============" Importance="High" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_PinVersions">
|
||||
<Target Name="_PinVersions" DependsOnTargets="_FindDotNetPath">
|
||||
|
||||
<PropertyGroup>
|
||||
<PinToolBinary>$(RepositoryRoot)tools\PinVersions\bin\$(Configuration)\netcoreapp1.1\PinVersions.dll</PinToolBinary>
|
||||
<PinVersionArgs>$(DotNetPath) $(PinToolBinary) --graph-specs-root "$(_RestoreGraphSpecsDirectory) " -s "$(UniverseBuildDir) " "$(BuildRepositoryRoot) "</PinVersionArgs>
|
||||
<PinVersionArgs>$(DotNetPath) $(PinToolBinary) --graph-specs-root "$(_RestoreGraphSpecsDirectory) " -s "$(BuildDir) " "$(BuildRepositoryRoot) "</PinVersionArgs>
|
||||
<PinVersionArgs Condition="Exists('$(_DependencyPackagesDirectory)')">$(PinVersionArgs) -s "$(_DependencyPackagesDirectory) "</PinVersionArgs>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<Project>
|
||||
<Import Project="RepositoryBuild.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<NuGetPublishVolatileFeed>https://dotnet.myget.org/F/aspnetcore-volatile-dev/api/v2/package</NuGetPublishVolatileFeed>
|
||||
|
||||
<_BuildGraphFile>$(BuildDir)BuildGraph.proj</_BuildGraphFile>
|
||||
<_CloneRepositoryRoot>$(RepositoryRoot).r\</_CloneRepositoryRoot>
|
||||
<_DependencyBuildDirectory>$(RepositoryRoot).deps\build\</_DependencyBuildDirectory>
|
||||
<_DependencyPackagesDirectory>$(_DependencyBuildDirectory)</_DependencyPackagesDirectory>
|
||||
|
@ -33,7 +34,7 @@
|
|||
<RemoveDir Directories="$(_CloneRepositoryRoot)" Condition="Exists('$(_CloneRepositoryRoot)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_FilterRepositories">
|
||||
<Target Name="_PrepareRepositories">
|
||||
<ItemGroup Condition="'$(KOREBUILD_REPOSITORY_INCLUDE)'!=''">
|
||||
<_RepositoriesToInclude Include="$(KOREBUILD_REPOSITORY_INCLUDE)" />
|
||||
<Repository
|
||||
|
@ -49,10 +50,12 @@
|
|||
<Error Text="KOREBUILD_REPOSITORY_EXCLUDE AND KOREBUILD_REPOSITORY_INCLUDE are specified."
|
||||
Condition="'$(KOREBUILD_REPOSITORY_INCLUDE)' != '' AND '$(KOREBUILD_REPOSITORY_EXCLUDE)' != ''" />
|
||||
|
||||
<Message Text="%(Repository.CloneUrl)" />
|
||||
<ItemGroup>
|
||||
<Repository Update="%(Identity)" RepositoryPath="$(_CloneRepositoryRoot)%(Identity)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="CloneRepositories" DependsOnTargets="_FilterRepositories">
|
||||
<Target Name="CloneRepositories" DependsOnTargets="_PrepareRepositories">
|
||||
<ItemGroup>
|
||||
<_CloneRepository Include="$(MSBuildProjectFullPath)">
|
||||
<AdditionalProperties>
|
||||
|
@ -72,6 +75,7 @@
|
|||
<MSBuild Projects="@(_CloneRepository)"
|
||||
Targets="_CloneRepository"
|
||||
BuildInParallel="$(BuildInParallel)" />
|
||||
|
||||
</Target>
|
||||
|
||||
<Target Name="_CloneRepository">
|
||||
|
@ -107,45 +111,9 @@
|
|||
</Target>
|
||||
|
||||
<Target Name="BuildRepositories"
|
||||
DependsOnTargets="_FilterRepositories;_FindDotNetPath;_GenerateRestoreGraphSpecs;_GenerateBuildGraph;_UpdateNuGetConfig;_CreateRepositoriesListWithCommits">
|
||||
DependsOnTargets="_PrepareRepositories;_FindDotNetPath;_CreateRepositoriesListWithCommits;_UpdateNuGetConfig;_GenerateBuildGraph;_BuildRepositories" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- If there are duplicate properties, the properties which are defined later in the order would override the earlier ones -->
|
||||
<RepositoryBuildArguments>$(RepositoryBuildArguments) /p:BuildNumber=$(BuildNumber) /p:Configuration=$(Configuration)</RepositoryBuildArguments>
|
||||
|
||||
<_BuildRepositoryProperties>
|
||||
UniverseBuildDir=$(BuildDir);
|
||||
UniverseMSBuildDir=$(ArtifactsDir)msbuild;
|
||||
BuildInParallel=$(BuildInParallel);
|
||||
Configuration=$(Configuration);
|
||||
DotNetPath=$(DotNetPath);
|
||||
KoreBuildDirectory=$(MSBuildProjectDirectory)\;
|
||||
KoreBuildProject=$(MSBuildProjectFile);
|
||||
RepositoryRoot=$(RepositoryRoot);
|
||||
_BuildGraphFile=$(_BuildGraphFile);
|
||||
_CloneRepositoryRoot=$(_CloneRepositoryRoot);
|
||||
_DependencyPackagesDirectory=$(_DependencyPackagesDirectory);
|
||||
_RepositoryBuildTargets=$(_RepositoryBuildTargets);
|
||||
RepositoryBuildArguments=$(RepositoryBuildArguments);
|
||||
_RestoreGraphSpecsDirectory=$(_RestoreGraphSpecsDirectory);
|
||||
PackagePublisherPath=$(PackagePublisherNetCoreApp)
|
||||
</_BuildRepositoryProperties>
|
||||
|
||||
<_BuildRepositoryProperties Condition="'$(PublishPackages)'=='true'">
|
||||
$(_BuildRepositoryProperties);
|
||||
APIKey=$(APIKey);
|
||||
NuGetPublishVolatileFeed=$(NuGetPublishVolatileFeed);
|
||||
PublishPackages=$(PublishPackages)
|
||||
</_BuildRepositoryProperties>
|
||||
</PropertyGroup>
|
||||
|
||||
<MSBuild
|
||||
Projects="$(MSBuildThisFileDirectory)RepositoryBuild.targets"
|
||||
Targets="BuildRepositories"
|
||||
Properties="$(_BuildRepositoryProperties)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_GenerateRestoreGraphSpecs" DependsOnTargets="_FindDotNetPath">
|
||||
<Target Name="_PrepareRestoreGraphSpecs" DependsOnTargets="_PrepareRepositories">
|
||||
<ItemGroup>
|
||||
<Solution Include="$(_CloneRepositoryRoot)%(Repository.Identity)\*.sln">
|
||||
<Repository>%(Repository.Identity)</Repository>
|
||||
|
@ -154,22 +122,26 @@
|
|||
<Solution>
|
||||
<AdditionalProperties>RestoreGraphOutputPath=$(_RestoreGraphSpecsDirectory)%(Solution.Repository)\%(Solution.FileName)%(Solution.Extension).json</AdditionalProperties>
|
||||
</Solution>
|
||||
</ItemGroup>
|
||||
|
||||
<GraphSpecInputs Include="
|
||||
@(Solution);
|
||||
$(_CloneRepositoryRoot)**\*.csproj;
|
||||
$(_CloneRepositoryRoot)**\dependencies.props" />
|
||||
<GraphSpecOutputs Include="$(_RestoreGraphSpecsDirectory)%(Solution.Repository)\%(Solution.FileName)%(Solution.Extension).json" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_GenerateRestoreGraphSpecs" DependsOnTargets="_PrepareRestoreGraphSpecs" Inputs="@(GraphSpecInputs)" Outputs="@(GraphSpecOutputs)">
|
||||
<MSBuild
|
||||
Projects="@(Solution)"
|
||||
Targets="GenerateRestoreGraphFile"
|
||||
BuildInParallel="$(BuildInParallel)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_GenerateBuildGraph" DependsOnTargets="_FindDotNetPath">
|
||||
<PropertyGroup>
|
||||
<BuildGrapArgs>$(DotNetPath) run -r "$(_CloneRepositoryRoot) " --graph-specs-root "$(_RestoreGraphSpecsDirectory) " "$(_BuildGraphFile)"</BuildGrapArgs>
|
||||
<BuildGrapArgs Condition="'$(BuildGraphOf)'!=''">$(BuildGrapArgs) --start-at $(BuildGraphOf)</BuildGrapArgs>
|
||||
</PropertyGroup>
|
||||
<Exec
|
||||
Command="$(BuildGrapArgs)"
|
||||
WorkingDirectory="$(RepositoryRoot)tools\BuildGraph\" />
|
||||
<Target Name="_GenerateBuildGraph" DependsOnTargets="_GenerateRestoreGraphSpecs">
|
||||
<RepoTasks.CalculateBuildGraph Repositories="@(Repository)" StartGraphAt="$(BuildGraphOf)" PackageSpecsDirectory="$(_RestoreGraphSpecsDirectory)">
|
||||
<Output TaskParameter="RepositoriesToBuildInOrder" ItemName="RepositoryToBuildInOrder" />
|
||||
</RepoTasks.CalculateBuildGraph>
|
||||
</Target>
|
||||
|
||||
<Target Name="_UpdateNuGetConfig">
|
||||
|
@ -211,21 +183,20 @@
|
|||
<PropertyGroup>
|
||||
<!--
|
||||
Attempt to read environment variables set up by the CI's VCS Root if available.
|
||||
* vcsroot.<RepositoryName>.url gives us the clone URL for a repository
|
||||
* build.vcs.number.<RepositoryName> gives us the commit hash for a repository.
|
||||
* BUILD_VCS_URL_<RepositoryName> gives us the clone URL for a repository
|
||||
* BUILD_VCS_NUMBER_<RepositoryName> gives us the commit hash for a repository.
|
||||
-->
|
||||
<_CloneUrl>$([System.Environment]::GetEnvironmentVariable("vcsroot.%(Repository.Identity).url"))</_CloneUrl>
|
||||
<_CommitHash>$([System.Environment]::GetEnvironmentVariable("build.vcs.number.%(Repository.Identity)"))</_CommitHash>
|
||||
|
||||
<RepositoryCloneDirectory>$(_CloneRepositoryRoot)%(Repository.Identity)</RepositoryCloneDirectory>
|
||||
<_RepositoryName>$([System.String]::new('%(Repository.Identity)').Replace('.', '_'))</_RepositoryName>
|
||||
<_CloneUrl>$([System.Environment]::GetEnvironmentVariable("BUILD_VCS_URL_$(_RepositoryName)"))</_CloneUrl>
|
||||
<_CommitHash>$([System.Environment]::GetEnvironmentVariable("BUILD_VCS_NUMBER_$(_RepositoryName)"))</_CommitHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<Warning Text="%(Repository.Identity) has not been cloned."
|
||||
Condition="!Exists('$(RepositoryCloneDirectory)')" />
|
||||
Condition="!Exists('%(Repository.RepositoryPath)')" />
|
||||
|
||||
<GetGitCommitInfo
|
||||
WorkingDirectory="$(RepositoryCloneDirectory)"
|
||||
Condition="'$(_CommitHash)'=='' AND Exists('$(RepositoryCloneDirectory)')">
|
||||
WorkingDirectory="%(Repository.RepositoryPath)"
|
||||
Condition="'$(_CommitHash)'=='' AND Exists('%(Repository.RepositoryPath)')">
|
||||
|
||||
<Output TaskParameter="CommitHash" PropertyName="_CommitHash" />
|
||||
</GetGitCommitInfo>
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
// 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; }
|
||||
|
||||
[Output]
|
||||
public ITaskItem[] RepositoriesToBuildInOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The repository at which to root the graph at
|
||||
/// </summary>
|
||||
public string StartGraphAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Directory that contains the package spec files.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string PackageSpecsDirectory { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var graphSpecProvider = new DependencyGraphSpecProvider(PackageSpecsDirectory.Trim());
|
||||
|
||||
var repositoryPaths = Repositories.Select(r => r.GetMetadata("RepositoryPath")).ToList();
|
||||
var repositories = Repository.ReadAllRepositories(repositoryPaths, graphSpecProvider);
|
||||
|
||||
var graph = GraphBuilder.Generate(repositories, StartGraphAt);
|
||||
var repositoriesWithOrder = new List<(ITaskItem repository, int order)>();
|
||||
foreach (var repositoryTaskItem in Repositories)
|
||||
{
|
||||
var repositoryName = repositoryTaskItem.ItemSpec;
|
||||
var graphNodeRepository = graph.First(g => g.Repository.Name == repositoryName);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System.IO;
|
||||
using NuGet.ProjectModel;
|
||||
|
||||
namespace RepoTools.BuildGraph
|
||||
{
|
||||
public class DependencyGraphSpecProvider
|
||||
{
|
||||
readonly string _packageSpecDirectory;
|
||||
|
||||
public DependencyGraphSpecProvider(string packageSpecDirectory)
|
||||
{
|
||||
_packageSpecDirectory = packageSpecDirectory;
|
||||
}
|
||||
|
||||
public DependencyGraphSpec GetDependencyGraphSpec(string repositoryName, string solutionPath)
|
||||
{
|
||||
var outputFile = Path.Combine(_packageSpecDirectory, repositoryName, Path.GetFileName(solutionPath) + ".json");
|
||||
return DependencyGraphSpec.Load(outputFile);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BuildGraph
|
||||
namespace RepoTools.BuildGraph
|
||||
{
|
||||
public static class GraphBuilder
|
||||
{
|
||||
|
@ -19,7 +19,7 @@ namespace BuildGraph
|
|||
foreach (var project in repositories.SelectMany(r => r.AllProjects))
|
||||
{
|
||||
var thisProjectRepositoryNode = graphNodes[project.Repository];
|
||||
if (root != null && string.Equals(root, project.Repository.Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (!string.IsNullOrEmpty(root) && string.Equals(root, project.Repository.Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
searchRoot = thisProjectRepositoryNode;
|
||||
}
|
||||
|
@ -58,4 +58,4 @@ namespace BuildGraph
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BuildGraph
|
||||
namespace RepoTools.BuildGraph
|
||||
{
|
||||
[DebuggerDisplay("{Repository.Name}")]
|
||||
public class GraphNode
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BuildGraph
|
||||
namespace RepoTools.BuildGraph
|
||||
{
|
||||
[DebuggerDisplay("{Name}")]
|
||||
public class Project
|
||||
|
@ -20,4 +20,4 @@ namespace BuildGraph
|
|||
|
||||
public ISet<string> PackageReferences { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,9 +6,8 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using NuGet.LibraryModel;
|
||||
using NuGet.ProjectModel;
|
||||
using UniverseTools;
|
||||
|
||||
namespace BuildGraph
|
||||
namespace RepoTools.BuildGraph
|
||||
{
|
||||
[DebuggerDisplay("{Name}")]
|
||||
public class Repository : IEquatable<Repository>
|
||||
|
@ -26,25 +25,17 @@ namespace BuildGraph
|
|||
|
||||
public IEnumerable<Project> AllProjects => Projects.Concat(SupportProjects);
|
||||
|
||||
public static IList<Repository> ReadAllRepositories(string repositoriesRoot, DependencyGraphSpecProvider provider)
|
||||
public static IList<Repository> ReadAllRepositories(IList<string> repositoryPaths, DependencyGraphSpecProvider provider)
|
||||
{
|
||||
var directories = new DirectoryInfo(repositoriesRoot).GetDirectories();
|
||||
var repositories = new Repository[directories.Length];
|
||||
var repositories = new Repository[repositoryPaths.Count];
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
Parallel.For(0, directories.Length, new ParallelOptions { MaxDegreeOfParallelism = 6 }, i =>
|
||||
Parallel.For(0, repositoryPaths.Count, new ParallelOptions { MaxDegreeOfParallelism = 6 }, i =>
|
||||
{
|
||||
var directoryInfo = directories[i];
|
||||
Console.WriteLine($"Gathering dependency information from {directoryInfo.Name}.");
|
||||
|
||||
var repository = Read(provider, directoryInfo.Name, directoryInfo.FullName);
|
||||
var repositoryPath = repositoryPaths[i];
|
||||
var repositoryName = Path.GetFileName(repositoryPath);
|
||||
var repository = Read(provider, repositoryName, repositoryPath);
|
||||
repositories[i] = repository;
|
||||
|
||||
Console.WriteLine($"Done gathering dependency information from {directoryInfo.Name}.");
|
||||
});
|
||||
sw.Stop();
|
||||
|
||||
Console.WriteLine($"Done reading dependency information for all repos in {sw.Elapsed}.");
|
||||
|
||||
return repositories;
|
||||
}
|
||||
|
@ -58,7 +49,8 @@ namespace BuildGraph
|
|||
var repository = new Repository(name);
|
||||
|
||||
ReadSharedSourceProjects(Path.Combine(repositoryPath, "shared"), repository, repository.Projects);
|
||||
var srcDirectory = Path.Combine(repositoryPath, "src");
|
||||
var srcDirectory = Path.GetFullPath(Path.Combine(repositoryPath, "src"))
|
||||
.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
|
||||
var solutionFiles = Directory.EnumerateFiles(repositoryPath, "*.sln");
|
||||
foreach (var file in solutionFiles)
|
||||
|
@ -67,7 +59,8 @@ namespace BuildGraph
|
|||
var projects = spec.Projects.OrderBy(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ? 0 : 1);
|
||||
foreach (var specProject in projects)
|
||||
{
|
||||
var projectPath = Path.GetFullPath(specProject.FilePath);
|
||||
var projectPath = Path.GetFullPath(specProject.FilePath)
|
||||
.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
|
||||
var projectGroup = projectPath.StartsWith(srcDirectory, StringComparison.OrdinalIgnoreCase) ?
|
||||
repository.Projects :
|
||||
|
@ -126,4 +119,4 @@ namespace BuildGraph
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BuildGraph
|
||||
namespace RepoTools.BuildGraph
|
||||
{
|
||||
public class TopologicalSort : IComparer<GraphNode>
|
||||
{
|
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(RepoTasksSdkPath)\Sdk.props" Condition="'$(RepoTasksSdkPath)' != '' "/>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NuGet.ProjectModel" Version="4.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(RepoTasksSdkPath)\Sdk.targets" Condition="'$(RepoTasksSdkPath)' != '' "/>
|
||||
</Project>
|
|
@ -0,0 +1,7 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<_RepoTaskAssembly>$(MSBuildThisFileDirectory)bin\publish\RepoTasks.dll</_RepoTaskAssembly>
|
||||
</PropertyGroup>
|
||||
|
||||
<UsingTask TaskName="RepoTasks.CalculateBuildGraph" AssemblyFile="$(_RepoTaskAssembly)" />
|
||||
</Project>
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\shared\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.DotNet.Cli.Utils" Version="1.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.CommandLineUtils" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,56 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace BuildGraph
|
||||
{
|
||||
public class DGMLFormatter : GraphFormatter
|
||||
{
|
||||
public override void Format(IList<GraphNode> nodes, string outputPath)
|
||||
{
|
||||
var xmlns = XNamespace.Get("http://schemas.microsoft.com/vs/2009/dgml");
|
||||
var xdoc = new XDocument(
|
||||
new XElement(xmlns + "DirectedGraph",
|
||||
new XElement(xmlns + "Nodes", GetNodes(xmlns, nodes).ToArray()),
|
||||
new XElement(xmlns + "Links", GetLinks(xmlns, nodes).ToArray()),
|
||||
new XElement(xmlns + "Properties", GetProperties(xmlns).ToArray())));
|
||||
|
||||
using (var writer = File.OpenWrite(outputPath))
|
||||
{
|
||||
xdoc.Save(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<XElement> GetLinks(XNamespace xmlns, IEnumerable<GraphNode> nodes)
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
foreach (var outgoing in node.Outgoing)
|
||||
{
|
||||
yield return new XElement(xmlns + "Link",
|
||||
new XAttribute("Source", node.Repository.Name),
|
||||
new XAttribute("Target", outgoing.Repository.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<XElement> GetNodes(XNamespace xmlns, IEnumerable<GraphNode> nodes)
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
yield return new XElement(xmlns + "Node",
|
||||
new XAttribute("Id", node.Repository.Name),
|
||||
new XAttribute("Label", $"{node.Repository.Name}"));
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<XElement> GetProperties(XNamespace xmlns)
|
||||
{
|
||||
yield return new XElement(xmlns + "Property",
|
||||
new XAttribute("Id", "Label"),
|
||||
new XAttribute("Label", "Label"),
|
||||
new XAttribute("DataType", "String"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BuildGraph
|
||||
{
|
||||
public abstract class GraphFormatter
|
||||
{
|
||||
public abstract void Format(IList<GraphNode> nodes, string outputPath);
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace BuildGraph
|
||||
{
|
||||
public class MSBuildGraphFormatter : GraphFormatter
|
||||
{
|
||||
public override void Format(IList<GraphNode> nodes, string outputPath)
|
||||
{
|
||||
var sortedNodes = nodes.Select(node => new { Repository = node.Repository, Order = TopologicalSort.GetOrder(node) })
|
||||
.OrderBy(item => item.Order);
|
||||
var projectElement = new XElement("Project",
|
||||
new XElement("ItemGroup",
|
||||
sortedNodes.Select(item => new XElement("RepositoryToBuildInOrder",
|
||||
new XAttribute("Include", item.Repository.Name),
|
||||
new XAttribute("Order", item.Order)))));
|
||||
|
||||
File.WriteAllText(outputPath, projectElement.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
using UniverseTools;
|
||||
|
||||
namespace BuildGraph
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandLineApplication();
|
||||
var outputTypeOption = app.Option("--output-type",
|
||||
"Output type of generated graph. Valid values are: msbuild, and dgml.",
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
var repositoriesRootOption = app.Option("-r|--repositories-root",
|
||||
"Directory containing repositories to calculate graph for.",
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
var packageSpecsDirectoryOption = app.Option("--graph-specs-root",
|
||||
"Directory containing package specs. (Optional)",
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
var graphRoot = app.Option("--start-at",
|
||||
"Calculate the build graph starting at the specified repo. (Optional)",
|
||||
CommandOptionType.SingleValue);
|
||||
|
||||
var outputPathArgument = app.Argument("Output path", "Output path");
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
if (!repositoriesRootOption.HasValue())
|
||||
{
|
||||
Console.Error.WriteLine($"Option {repositoriesRootOption.Template} must have a value.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var outputPath = outputPathArgument.Value;
|
||||
if (string.IsNullOrEmpty(outputPath))
|
||||
{
|
||||
Console.Error.WriteLine($"Output path not specified.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
var outputDirectory = Path.GetDirectoryName(outputPath);
|
||||
Directory.CreateDirectory(outputDirectory);
|
||||
|
||||
var outputType = outputTypeOption.Value() ?? "msbuild";
|
||||
|
||||
var graphSpecProvider = packageSpecsDirectoryOption.HasValue()
|
||||
? new DependencyGraphSpecProvider(packageSpecsDirectoryOption.Value().Trim())
|
||||
: DependencyGraphSpecProvider.Default;
|
||||
IList<Repository> repositories;
|
||||
using (graphSpecProvider)
|
||||
{
|
||||
repositories = Repository.ReadAllRepositories(repositoriesRootOption.Value().Trim(), graphSpecProvider);
|
||||
}
|
||||
|
||||
var graph = GraphBuilder.Generate(repositories, graphRoot.Value());
|
||||
GraphFormatter formatter;
|
||||
switch (outputType)
|
||||
{
|
||||
case "msbuild":
|
||||
formatter = new MSBuildGraphFormatter();
|
||||
break;
|
||||
case "dgml":
|
||||
formatter = new DGMLFormatter();
|
||||
break;
|
||||
default:
|
||||
app.Error.WriteLine($"Unknown output type: {outputType}.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
formatter.Format(graph, outputPathArgument.Value);
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return app.Execute(args);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче