Make the calculation of the build graph a task so we can pass metadata around
This commit is contained in:
parent
d8a897bada
commit
aa25401a50
|
|
@ -2,6 +2,7 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<clear />
|
<clear />
|
||||||
|
<add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-release/api/v3/index.json" />
|
||||||
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
<add key="NuGet" value="https://api.nuget.org/v3/index.json" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26228.0
|
VisualStudioVersion = 15.0.26228.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
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}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PinVersions", "tools\PinVersions\PinVersions.csproj", "{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{085280EC-7055-426A-BF9C-1B692B9599AB}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{085280EC-7055-426A-BF9C-1B692B9599AB}"
|
||||||
|
|
@ -18,10 +16,6 @@ Global
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
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.ActiveCfg = Debug|Any CPU
|
||||||
{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}.Debug|Any CPU.Build.0 = 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
|
{DACA9DFB-508E-45EA-A5CF-C0F5C2BA181B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
<Project>
|
<Project>
|
||||||
<Import Project="$(_BuildGraphFile)" />
|
<Target Name="_BuildRepositories">
|
||||||
|
|
||||||
<Target Name="BuildRepositories">
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BatchedRepository Include="$(MSBuildProjectFullPath)">
|
<BatchedRepository Include="$(MSBuildProjectFullPath)">
|
||||||
<BuildGroup>%(RepositoryToBuildInOrder.Order)</BuildGroup>
|
<BuildGroup>%(RepositoryToBuildInOrder.Order)</BuildGroup>
|
||||||
<Repository>%(RepositoryToBuildInOrder.Identity)</Repository>
|
<Repository>%(RepositoryToBuildInOrder.Identity)</Repository>
|
||||||
<AdditionalProperties>
|
<AdditionalProperties>
|
||||||
RepositoryToBuild=%(RepositoryToBuildInOrder.Identity);
|
RepositoryToBuild=%(RepositoryToBuildInOrder.Identity);
|
||||||
BuildRepositoryRoot=$(_CloneRepositoryRoot)%(RepositoryToBuildInOrder.Identity)\
|
BuildRepositoryRoot=%(RepositoryToBuildInOrder.RepositoryPath)\;
|
||||||
|
CommitHash=%(RepositoryToBuildInOrder.Commit)
|
||||||
</AdditionalProperties>
|
</AdditionalProperties>
|
||||||
</BatchedRepository>
|
</BatchedRepository>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
@ -18,26 +17,6 @@
|
||||||
<BatchBuilds Condition="'$(BatchBuilds)'==''">false</BatchBuilds>
|
<BatchBuilds Condition="'$(BatchBuilds)'==''">false</BatchBuilds>
|
||||||
</PropertyGroup>
|
</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
|
<MSBuild
|
||||||
Projects="@(BatchedRepository)"
|
Projects="@(BatchedRepository)"
|
||||||
BuildInParallel="$(BatchBuilds)"
|
BuildInParallel="$(BatchBuilds)"
|
||||||
|
|
@ -48,6 +27,9 @@
|
||||||
|
|
||||||
<Target Name="_BuildRepository" DependsOnTargets="_PinVersions">
|
<Target Name="_BuildRepository" DependsOnTargets="_PinVersions">
|
||||||
<PropertyGroup>
|
<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>
|
<BuildArguments>$(_RepositoryBuildTargets) $(RepositoryBuildArguments)</BuildArguments>
|
||||||
<RepositoryArtifactsRoot>$(BuildRepositoryRoot)artifacts</RepositoryArtifactsRoot>
|
<RepositoryArtifactsRoot>$(BuildRepositoryRoot)artifacts</RepositoryArtifactsRoot>
|
||||||
<RepositoryArtifactsBuildDirectory>$(RepositoryArtifactsRoot)\build\</RepositoryArtifactsBuildDirectory>
|
<RepositoryArtifactsBuildDirectory>$(RepositoryArtifactsRoot)\build\</RepositoryArtifactsBuildDirectory>
|
||||||
|
|
@ -83,26 +65,27 @@
|
||||||
|
|
||||||
<Copy
|
<Copy
|
||||||
SourceFiles="@(RepositoryArtifacts)"
|
SourceFiles="@(RepositoryArtifacts)"
|
||||||
DestinationFolder="$(UniverseBuildDir)" />
|
DestinationFolder="$(BuildDir)" />
|
||||||
|
|
||||||
<Move
|
<Move
|
||||||
SourceFiles="@(RepositoryMSBuildArtifacts)"
|
SourceFiles="@(RepositoryMSBuildArtifacts)"
|
||||||
DestinationFolder="$(UniverseMSBuildDir)\$(RepositoryToBuild)\%(RecursiveDir)" />
|
DestinationFolder="$(ArtifactsDir)msbuild\$(RepositoryToBuild)\%(RecursiveDir)" />
|
||||||
|
|
||||||
<Message Text="Publishing the following packages to the volatile feed: @(RepositoryNupkgs -> '%(Filename)%(Extension)', ', ')"
|
<Message Text="Publishing the following packages to the volatile feed: @(RepositoryNupkgs -> '%(Filename)%(Extension)', ', ')"
|
||||||
Condition="'$(PublishPackages)'=='true' AND '@(RepositoryNupkgs)' != ''" />
|
Condition="'$(PublishPackages)'=='true' AND '@(RepositoryNupkgs)' != ''" />
|
||||||
|
|
||||||
<Exec
|
<Exec
|
||||||
Command="$(DotNetPath) $(PackagePublisherPath) -d $(RepositoryArtifactsBuildDirectory) -f $(NuGetPublishVolatileFeed)"
|
Command="$(DotNetPath) $(PackagePublisherNetCoreApp) -d $(RepositoryArtifactsBuildDirectory) -f $(NuGetPublishVolatileFeed)"
|
||||||
Condition="'$(PublishPackages)'=='true' AND '@(RepositoryNupkgs)' != ''" />
|
Condition="'$(PublishPackages)'=='true' AND '@(RepositoryNupkgs)' != ''" />
|
||||||
|
|
||||||
<Message Text="============ Done building $(RepositoryToBuild) ============" Importance="High" />
|
<Message Text="============ Done building $(RepositoryToBuild) ============" Importance="High" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_PinVersions">
|
<Target Name="_PinVersions" DependsOnTargets="_FindDotNetPath">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PinToolBinary>$(RepositoryRoot)tools\PinVersions\bin\$(Configuration)\netcoreapp1.1\PinVersions.dll</PinToolBinary>
|
<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>
|
<PinVersionArgs Condition="Exists('$(_DependencyPackagesDirectory)')">$(PinVersionArgs) -s "$(_DependencyPackagesDirectory) "</PinVersionArgs>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
<Project>
|
<Project>
|
||||||
|
<Import Project="RepositoryBuild.targets" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<NuGetPublishVolatileFeed>https://dotnet.myget.org/F/aspnetcore-volatile-dev/api/v2/package</NuGetPublishVolatileFeed>
|
<NuGetPublishVolatileFeed>https://dotnet.myget.org/F/aspnetcore-volatile-dev/api/v2/package</NuGetPublishVolatileFeed>
|
||||||
|
|
||||||
<_BuildGraphFile>$(BuildDir)BuildGraph.proj</_BuildGraphFile>
|
|
||||||
<_CloneRepositoryRoot>$(RepositoryRoot).r\</_CloneRepositoryRoot>
|
<_CloneRepositoryRoot>$(RepositoryRoot).r\</_CloneRepositoryRoot>
|
||||||
<_DependencyBuildDirectory>$(RepositoryRoot).deps\build\</_DependencyBuildDirectory>
|
<_DependencyBuildDirectory>$(RepositoryRoot).deps\build\</_DependencyBuildDirectory>
|
||||||
<_DependencyPackagesDirectory>$(_DependencyBuildDirectory)</_DependencyPackagesDirectory>
|
<_DependencyPackagesDirectory>$(_DependencyBuildDirectory)</_DependencyPackagesDirectory>
|
||||||
|
|
@ -33,7 +34,7 @@
|
||||||
<RemoveDir Directories="$(_CloneRepositoryRoot)" Condition="Exists('$(_CloneRepositoryRoot)')" />
|
<RemoveDir Directories="$(_CloneRepositoryRoot)" Condition="Exists('$(_CloneRepositoryRoot)')" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_FilterRepositories">
|
<Target Name="_PrepareRepositories">
|
||||||
<ItemGroup Condition="'$(KOREBUILD_REPOSITORY_INCLUDE)'!=''">
|
<ItemGroup Condition="'$(KOREBUILD_REPOSITORY_INCLUDE)'!=''">
|
||||||
<_RepositoriesToInclude Include="$(KOREBUILD_REPOSITORY_INCLUDE)" />
|
<_RepositoriesToInclude Include="$(KOREBUILD_REPOSITORY_INCLUDE)" />
|
||||||
<Repository
|
<Repository
|
||||||
|
|
@ -49,10 +50,12 @@
|
||||||
<Error Text="KOREBUILD_REPOSITORY_EXCLUDE AND KOREBUILD_REPOSITORY_INCLUDE are specified."
|
<Error Text="KOREBUILD_REPOSITORY_EXCLUDE AND KOREBUILD_REPOSITORY_INCLUDE are specified."
|
||||||
Condition="'$(KOREBUILD_REPOSITORY_INCLUDE)' != '' AND '$(KOREBUILD_REPOSITORY_EXCLUDE)' != ''" />
|
Condition="'$(KOREBUILD_REPOSITORY_INCLUDE)' != '' AND '$(KOREBUILD_REPOSITORY_EXCLUDE)' != ''" />
|
||||||
|
|
||||||
<Message Text="%(Repository.CloneUrl)" />
|
<ItemGroup>
|
||||||
|
<Repository Update="%(Identity)" RepositoryPath="$(_CloneRepositoryRoot)%(Identity)" />
|
||||||
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="CloneRepositories" DependsOnTargets="_FilterRepositories">
|
<Target Name="CloneRepositories" DependsOnTargets="_PrepareRepositories">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_CloneRepository Include="$(MSBuildProjectFullPath)">
|
<_CloneRepository Include="$(MSBuildProjectFullPath)">
|
||||||
<AdditionalProperties>
|
<AdditionalProperties>
|
||||||
|
|
@ -72,6 +75,7 @@
|
||||||
<MSBuild Projects="@(_CloneRepository)"
|
<MSBuild Projects="@(_CloneRepository)"
|
||||||
Targets="_CloneRepository"
|
Targets="_CloneRepository"
|
||||||
BuildInParallel="$(BuildInParallel)" />
|
BuildInParallel="$(BuildInParallel)" />
|
||||||
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_CloneRepository">
|
<Target Name="_CloneRepository">
|
||||||
|
|
@ -107,45 +111,9 @@
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="BuildRepositories"
|
<Target Name="BuildRepositories"
|
||||||
DependsOnTargets="_FilterRepositories;_FindDotNetPath;_GenerateRestoreGraphSpecs;_GenerateBuildGraph;_UpdateNuGetConfig;_CreateRepositoriesListWithCommits">
|
DependsOnTargets="_PrepareRepositories;_FindDotNetPath;_CreateRepositoriesListWithCommits;_UpdateNuGetConfig;_GenerateBuildGraph;_BuildRepositories" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<Target Name="_PrepareRestoreGraphSpecs" DependsOnTargets="_PrepareRepositories">
|
||||||
<!-- 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">
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Solution Include="$(_CloneRepositoryRoot)%(Repository.Identity)\*.sln">
|
<Solution Include="$(_CloneRepositoryRoot)%(Repository.Identity)\*.sln">
|
||||||
<Repository>%(Repository.Identity)</Repository>
|
<Repository>%(Repository.Identity)</Repository>
|
||||||
|
|
@ -154,22 +122,26 @@
|
||||||
<Solution>
|
<Solution>
|
||||||
<AdditionalProperties>RestoreGraphOutputPath=$(_RestoreGraphSpecsDirectory)%(Solution.Repository)\%(Solution.FileName)%(Solution.Extension).json</AdditionalProperties>
|
<AdditionalProperties>RestoreGraphOutputPath=$(_RestoreGraphSpecsDirectory)%(Solution.Repository)\%(Solution.FileName)%(Solution.Extension).json</AdditionalProperties>
|
||||||
</Solution>
|
</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
|
<MSBuild
|
||||||
Projects="@(Solution)"
|
Projects="@(Solution)"
|
||||||
Targets="GenerateRestoreGraphFile"
|
Targets="GenerateRestoreGraphFile"
|
||||||
BuildInParallel="$(BuildInParallel)" />
|
BuildInParallel="$(BuildInParallel)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_GenerateBuildGraph" DependsOnTargets="_FindDotNetPath">
|
<Target Name="_GenerateBuildGraph" DependsOnTargets="_GenerateRestoreGraphSpecs">
|
||||||
<PropertyGroup>
|
<RepoTasks.CalculateBuildGraph Repositories="@(Repository)" StartGraphAt="$(BuildGraphOf)" PackageSpecsDirectory="$(_RestoreGraphSpecsDirectory)">
|
||||||
<BuildGrapArgs>$(DotNetPath) run -r "$(_CloneRepositoryRoot) " --graph-specs-root "$(_RestoreGraphSpecsDirectory) " "$(_BuildGraphFile)"</BuildGrapArgs>
|
<Output TaskParameter="RepositoriesToBuildInOrder" ItemName="RepositoryToBuildInOrder" />
|
||||||
<BuildGrapArgs Condition="'$(BuildGraphOf)'!=''">$(BuildGrapArgs) --start-at $(BuildGraphOf)</BuildGrapArgs>
|
</RepoTasks.CalculateBuildGraph>
|
||||||
</PropertyGroup>
|
|
||||||
<Exec
|
|
||||||
Command="$(BuildGrapArgs)"
|
|
||||||
WorkingDirectory="$(RepositoryRoot)tools\BuildGraph\" />
|
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_UpdateNuGetConfig">
|
<Target Name="_UpdateNuGetConfig">
|
||||||
|
|
@ -216,16 +188,14 @@
|
||||||
-->
|
-->
|
||||||
<_CloneUrl>$([System.Environment]::GetEnvironmentVariable("vcsroot.%(Repository.Identity).url"))</_CloneUrl>
|
<_CloneUrl>$([System.Environment]::GetEnvironmentVariable("vcsroot.%(Repository.Identity).url"))</_CloneUrl>
|
||||||
<_CommitHash>$([System.Environment]::GetEnvironmentVariable("build.vcs.number.%(Repository.Identity)"))</_CommitHash>
|
<_CommitHash>$([System.Environment]::GetEnvironmentVariable("build.vcs.number.%(Repository.Identity)"))</_CommitHash>
|
||||||
|
|
||||||
<RepositoryCloneDirectory>$(_CloneRepositoryRoot)%(Repository.Identity)</RepositoryCloneDirectory>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Warning Text="%(Repository.Identity) has not been cloned."
|
<Warning Text="%(Repository.Identity) has not been cloned."
|
||||||
Condition="!Exists('$(RepositoryCloneDirectory)')" />
|
Condition="!Exists('%(Repository.RepositoryPath)')" />
|
||||||
|
|
||||||
<GetGitCommitInfo
|
<GetGitCommitInfo
|
||||||
WorkingDirectory="$(RepositoryCloneDirectory)"
|
WorkingDirectory="%(Repository.RepositoryPath)"
|
||||||
Condition="'$(_CommitHash)'=='' AND Exists('$(RepositoryCloneDirectory)')">
|
Condition="'$(_CommitHash)'=='' AND Exists('%(Repository.RepositoryPath)')">
|
||||||
|
|
||||||
<Output TaskParameter="CommitHash" PropertyName="_CommitHash" />
|
<Output TaskParameter="CommitHash" PropertyName="_CommitHash" />
|
||||||
</GetGitCommitInfo>
|
</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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace BuildGraph
|
namespace RepoTools.BuildGraph
|
||||||
{
|
{
|
||||||
public static class GraphBuilder
|
public static class GraphBuilder
|
||||||
{
|
{
|
||||||
|
|
@ -19,7 +19,7 @@ namespace BuildGraph
|
||||||
foreach (var project in repositories.SelectMany(r => r.AllProjects))
|
foreach (var project in repositories.SelectMany(r => r.AllProjects))
|
||||||
{
|
{
|
||||||
var thisProjectRepositoryNode = graphNodes[project.Repository];
|
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;
|
searchRoot = thisProjectRepositoryNode;
|
||||||
}
|
}
|
||||||
|
|
@ -58,4 +58,4 @@ namespace BuildGraph
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace BuildGraph
|
namespace RepoTools.BuildGraph
|
||||||
{
|
{
|
||||||
[DebuggerDisplay("{Repository.Name}")]
|
[DebuggerDisplay("{Repository.Name}")]
|
||||||
public class GraphNode
|
public class GraphNode
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace BuildGraph
|
namespace RepoTools.BuildGraph
|
||||||
{
|
{
|
||||||
[DebuggerDisplay("{Name}")]
|
[DebuggerDisplay("{Name}")]
|
||||||
public class Project
|
public class Project
|
||||||
|
|
@ -20,4 +20,4 @@ namespace BuildGraph
|
||||||
|
|
||||||
public ISet<string> PackageReferences { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
public ISet<string> PackageReferences { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,9 +6,8 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NuGet.LibraryModel;
|
using NuGet.LibraryModel;
|
||||||
using NuGet.ProjectModel;
|
using NuGet.ProjectModel;
|
||||||
using UniverseTools;
|
|
||||||
|
|
||||||
namespace BuildGraph
|
namespace RepoTools.BuildGraph
|
||||||
{
|
{
|
||||||
[DebuggerDisplay("{Name}")]
|
[DebuggerDisplay("{Name}")]
|
||||||
public class Repository : IEquatable<Repository>
|
public class Repository : IEquatable<Repository>
|
||||||
|
|
@ -26,25 +25,17 @@ namespace BuildGraph
|
||||||
|
|
||||||
public IEnumerable<Project> AllProjects => Projects.Concat(SupportProjects);
|
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[repositoryPaths.Count];
|
||||||
var repositories = new Repository[directories.Length];
|
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
Parallel.For(0, repositoryPaths.Count, new ParallelOptions { MaxDegreeOfParallelism = 6 }, i =>
|
||||||
Parallel.For(0, directories.Length, new ParallelOptions { MaxDegreeOfParallelism = 6 }, i =>
|
|
||||||
{
|
{
|
||||||
var directoryInfo = directories[i];
|
var repositoryPath = repositoryPaths[i];
|
||||||
Console.WriteLine($"Gathering dependency information from {directoryInfo.Name}.");
|
var repositoryName = Path.GetFileName(repositoryPath);
|
||||||
|
var repository = Read(provider, repositoryName, repositoryPath);
|
||||||
var repository = Read(provider, directoryInfo.Name, directoryInfo.FullName);
|
|
||||||
repositories[i] = repository;
|
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;
|
return repositories;
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +49,8 @@ namespace BuildGraph
|
||||||
var repository = new Repository(name);
|
var repository = new Repository(name);
|
||||||
|
|
||||||
ReadSharedSourceProjects(Path.Combine(repositoryPath, "shared"), repository, repository.Projects);
|
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");
|
var solutionFiles = Directory.EnumerateFiles(repositoryPath, "*.sln");
|
||||||
foreach (var file in solutionFiles)
|
foreach (var file in solutionFiles)
|
||||||
|
|
@ -67,7 +59,8 @@ namespace BuildGraph
|
||||||
var projects = spec.Projects.OrderBy(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ? 0 : 1);
|
var projects = spec.Projects.OrderBy(p => p.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ? 0 : 1);
|
||||||
foreach (var specProject in projects)
|
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) ?
|
var projectGroup = projectPath.StartsWith(srcDirectory, StringComparison.OrdinalIgnoreCase) ?
|
||||||
repository.Projects :
|
repository.Projects :
|
||||||
|
|
@ -126,4 +119,4 @@ namespace BuildGraph
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace BuildGraph
|
namespace RepoTools.BuildGraph
|
||||||
{
|
{
|
||||||
public class TopologicalSort : IComparer<GraphNode>
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue