Verify external dependencies (#561)
This commit is contained in:
parent
72598ad07c
commit
951dc99d5b
|
|
@ -0,0 +1,178 @@
|
|||
<Project>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<ExternalDependency>
|
||||
<!-- The NuGet package version. Floating versions not allowed. -->
|
||||
<Version></Version>
|
||||
<!-- Where does this pacakge come from -->
|
||||
<Source></Source>
|
||||
<!-- A list of warnings to suppress. -->
|
||||
<NoWarn></NoWarn>
|
||||
<!-- This dependency is 'Private', aka. it should not end up as a public-facing external dependency. This is validated by checking the nuspec on generated packages. -->
|
||||
<Private>false</Private>
|
||||
</ExternalDependency>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!-- ASP.NET Core Tools feed -->
|
||||
<PropertyGroup>
|
||||
<RoslynFeed>https://dotnet.myget.org/F/roslyn/api/v3/index.json</RoslynFeed>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.Common" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true">
|
||||
<!-- This version is required for Razor to build the VSIX for VS. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.CSharp" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true">
|
||||
<!-- This version is required for Razor to build the VSIX for VS. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.Remote.Razor.ServiceHub" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true">
|
||||
<!-- This version is required for Razor to build the VSIX for VS. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.LanguageServices.Razor.RemoteClient" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.LanguageServices" Version="2.6.0-beta1-61924-08" Source="$(RoslynFeed)" Private="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ASP.NET Core Tools feed -->
|
||||
<PropertyGroup>
|
||||
<AspNetCoreToolsFeed>https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json</AspNetCoreToolsFeed>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ExternalDependency Include="Internal.AspNetCore.Sdk" Version="2.0.1-rtm-15400" Source="$(AspNetCoreToolsFeed)" Private="true"/>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ASP.NET Core (non-Universe builds) -->
|
||||
<PropertyGroup>
|
||||
<AspNetCoreModuleFeed>https://dotnet.myget.org/F/aspnetcoremodule/api/v3/index.json</AspNetCoreModuleFeed>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ExternalDependency Include="Microsoft.AspNetCore.AspNetCoreModule" Version="1.0.0-pre-10057" Source="$(AspNetCoreModuleFeed)" Private="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- ASP.NET Core (non-Universe builds) -->
|
||||
<PropertyGroup>
|
||||
<AspNetCoreFeed>https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json</AspNetCoreFeed>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ExternalDependency Include="Libuv" Version="1.10.0" Source="$(AspNetCoreFeed)"/>
|
||||
<ExternalDependency Include="Microsoft.AspNetCore.Internal.CoreFxLab.Sources" Version="2.0.0-rtm-21470" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- nuget.org -->
|
||||
<PropertyGroup>
|
||||
<DefaultNuGetFeed>https://api.nuget.org/v3/index.json</DefaultNuGetFeed>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ExternalDependency Include="BenchmarkDotNet" Version="0.10.3" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="EntityFramework" Version="6.1.3" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="FSharp.Core" Version="4.2.1" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="Microsoft.AspNet.Identity.EntityFramework" Version="2.2.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.AspNet.WebApi.Client" Version="5.2.2" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Azure.KeyVault" Version="2.3.2" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Build.Runtime" Version="15.3.409" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Build.Tasks.Core" Version="15.3.409" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Build.Utilities.Core" Version="15.3.409" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Build" Version="15.3.409" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.Common" Version="2.3.1" Source="$(DefaultNuGetFeed)" >
|
||||
<!-- This version is used by the Razor runtime packages and any other piece of aspnetcore that uses Roslyn. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="2.3.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.CSharp" Version="2.3.1" Source="$(DefaultNuGetFeed)" >
|
||||
<!-- This version is used by the Razor runtime packages and any other piece of aspnetcore that uses Roslyn. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="2.3.1" Source="$(DefaultNuGetFeed)" >
|
||||
<!-- This version is used by the Razor runtime packages and any other piece of aspnetcore that uses Roslyn. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Microsoft.CSharp" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.DotNet.ProjectModel" Version="1.0.0-rc3-003121" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="Microsoft.Extensions.DependencyModel" Version="2.0.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.14.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="2.1.4" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.NET.Test.Sdk" Version="15.3.0" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="Microsoft.NETCore.Windows.ApiSets" Version="1.0.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Owin.Security.Cookies" Version="3.0.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Owin.Security" Version="3.0.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Microsoft.Owin.Testing" Version="3.0.1" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Editor" Version="15.0.26606" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.OLE.Interop" Version="7.10.6070" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.15.0" Version="15.0.26606" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.Interop.10.0" Version="10.0.30319" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.Interop.11.0" Version="11.0.61030" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.Interop.12.0" Version="12.0.30110" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.Interop.8.0" Version="8.0.50727" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.Interop.9.0" Version="9.0.30729" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.VisualStudio.Shell.Interop" Version="7.10.6071" Source="$(DefaultNuGetFeed)" Private="true" />
|
||||
<ExternalDependency Include="Microsoft.Web.Xdt" Version="1.4.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="Microsoft.Win32.Registry" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Moq" Version="4.7.49" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="Microsoft.NETCore.App" Version="2.0.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="NETStandard.Library" Version="2.0.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Newtonsoft.Json.Bson" Version="1.0.1" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Newtonsoft.Json" Version="9.0.1" Source="$(DefaultNuGetFeed)" Private="true">
|
||||
<!-- This version is used by tooling packages to match what is in VS and MSBuild. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="Newtonsoft.Json" Version="10.0.1" Source="$(DefaultNuGetFeed)">
|
||||
<!-- This version is used by runtime packages. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="NuGet.Frameworks" Version="4.0.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="Remotion.Linq" Version="2.1.1" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="Serilog.Extensions.Logging" Version="1.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="Serilog.Sinks.File" Version="3.2.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="SQLitePCLRaw.bundle_green" Version="1.1.7" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="SQLitePCLRaw.core" Version="1.1.7" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="StackExchange.Redis.StrongName" Version="1.2.4" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="StreamJsonRpc" Version="1.1.92" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="StyleCop.Analyzers" Version="1.0.0" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="System.Buffers" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Collections.Immutable" Version="1.4.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.ComponentModel.Annotations" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Data.SqlClient" Version="4.4.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Diagnostics.DiagnosticSource" Version="4.4.1" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Interactive.Async" Version="3.1.1" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Net.Http.WinHttpHandler" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Numerics.Vectors" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Reflection.Metadata" Version="1.5.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Runtime.CompilerServices.Unsafe" Version="4.4.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Security.Cryptography.Xml" Version="4.4.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Security.Principal.Windows" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Text.Encodings.Web" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="System.Threading.Tasks.Dataflow" Version="4.8.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.Threading.Tasks.Extensions" Version="4.4.0" Source="$(DefaultNuGetFeed)"/>
|
||||
<ExternalDependency Include="System.ValueTuple" Version="4.4.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="WindowsAzure.Storage" Version="8.1.4" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="xunit.abstractions" Version="2.0.1" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="xunit.assert" Version="2.2.0" Source="$(DefaultNuGetFeed)" Private="true">
|
||||
<!-- EF's benchmarks use a different version of xunit.assert -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="xunit.assert" Version="2.3.0-beta2-build3683" Source="$(DefaultNuGetFeed)" Private="true">
|
||||
<!-- EF's benchmarks use a different version of xunit.assert -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="xunit.extensibility.core" Version="2.2.0" Source="$(DefaultNuGetFeed)" />
|
||||
<ExternalDependency Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" Source="$(DefaultNuGetFeed)" Private="true"/>
|
||||
<ExternalDependency Include="xunit" Version="2.2.0" Source="$(DefaultNuGetFeed)">
|
||||
<!-- It is okay to have multiple versions of test-only dependencies. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
<ExternalDependency Include="xunit" Version="2.3.0-beta2-build3683" Source="$(DefaultNuGetFeed)" Private="true">
|
||||
<!-- It is okay to have multiple versions of test-only dependencies. -->
|
||||
<NoWarn>KRB2004</NoWarn>
|
||||
</ExternalDependency>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
This ensures the build number is a time-based number for local builds.
|
||||
This is important for local builds of Universe which need to ensure repo-to-repo
|
||||
builds are using new articacts, not ones from the global cache.
|
||||
-->
|
||||
<IncrementalVersion>true</IncrementalVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -5,4 +5,5 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<Import Project="artifacts.props" />
|
||||
<Import Project="dependencies.props" />
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@
|
|||
|
||||
<Message Text="Clone %(_CloneRepositories.Identity)" Importance="High" />
|
||||
|
||||
<!-- <MSBuild Projects="@(_CloneRepository)"
|
||||
<MSBuild Projects="@(_CloneRepository)"
|
||||
Targets="_CloneRepository"
|
||||
BuildInParallel="$(BuildInParallel)" /> -->
|
||||
BuildInParallel="$(BuildInParallel)" />
|
||||
|
||||
</Target>
|
||||
|
||||
|
|
@ -161,6 +161,7 @@
|
|||
<RepoTasks.AnalyzeBuildGraph
|
||||
Solutions="@(Solution)"
|
||||
Artifacts="@(ArtifactInfo)"
|
||||
Dependencies="@(ExternalDependency)"
|
||||
ShippedArtifacts="@(ShippedArtifactInfo)"
|
||||
StartGraphAt="$(BuildGraphOf)"
|
||||
Properties="Configuration=$(Configuration);BuildNumber=$(BuildNumber)">
|
||||
|
|
@ -199,13 +200,15 @@
|
|||
DestinationFolder="$(ArtifactsDir)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="VerifyCoherentVersions">
|
||||
<Target Name="VerifyCoherentVersions" DependsOnTargets="ResolveRepoInfo">
|
||||
<ItemGroup>
|
||||
<ShippingPackageFiles Include="$(ArtifactsDir)ship\*.nupkg" />
|
||||
<ShippedExternalDependency Include="%(ShippedArtifactInfo.PackageId)" Version="%(Version)" />
|
||||
</ItemGroup>
|
||||
|
||||
<RepoTasks.VerifyCoherentVersions
|
||||
PackageFiles="@(ShippingPackageFiles)" />
|
||||
PackageFiles="@(ShippingPackageFiles)"
|
||||
ExternalDependencies="@(ExternalDependency);@(ShippedExternalDependency)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_CreateRepositoriesListWithCommits" DependsOnTargets="_GetRepositoryCommits">
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ namespace RepoTasks
|
|||
[Required]
|
||||
public ITaskItem[] Artifacts { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] Dependencies { get; set; }
|
||||
|
||||
// Artifacts that already shipped from repos
|
||||
[Required]
|
||||
public ITaskItem[] ShippedArtifacts { get; set; }
|
||||
|
|
@ -95,6 +98,21 @@ namespace RepoTasks
|
|||
|
||||
// ensure versions cascade
|
||||
var buildPackageMap = packages.ToDictionary(p => p.PackageInfo.Id, p => p, StringComparer.OrdinalIgnoreCase);
|
||||
var dependencyMap = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var dep in Dependencies)
|
||||
{
|
||||
if (!dependencyMap.TryGetValue(dep.ItemSpec, out var versions))
|
||||
{
|
||||
dependencyMap[dep.ItemSpec] = versions = new List<string>();
|
||||
}
|
||||
else if (dep.GetMetadata("NoWarn") == null || dep.GetMetadata("NoWarn").IndexOf("KRB" + KoreBuildErrors.MultipleExternalDependencyVersions) < 0)
|
||||
{
|
||||
Log.LogKoreBuildWarning(
|
||||
KoreBuildErrors.MultipleExternalDependencyVersions,
|
||||
message: $"Multiple versions of external dependency '{dep.ItemSpec}' are defined. In most cases, there should only be one version of external dependencies.");
|
||||
}
|
||||
versions.Add(dep.GetMetadata("Version"));
|
||||
}
|
||||
|
||||
var inconsistentVersions = new List<VersionMismatch>();
|
||||
var reposThatShouldPatch = new HashSet<string>();
|
||||
|
|
@ -107,7 +125,25 @@ namespace RepoTasks
|
|||
{
|
||||
if (!buildPackageMap.TryGetValue(dependency.Key, out var package))
|
||||
{
|
||||
// this dependency is not a PackageReference to something that we build in Universe
|
||||
// This dependency is not one of the packages that will be compiled by this run of Universe.
|
||||
|
||||
var matchesExternalDependency = false;
|
||||
if (shippedPackageMap.TryGetValue(dependency.Key, out var shippedPackage))
|
||||
{
|
||||
matchesExternalDependency = shippedPackage.PackageInfo.Version.Equals(NuGetVersion.Parse(dependency.Value.Version));
|
||||
}
|
||||
else if (dependencyMap.TryGetValue(dependency.Key, out var externalVersions))
|
||||
{
|
||||
matchesExternalDependency = externalVersions.Contains(dependency.Value.Version);
|
||||
}
|
||||
|
||||
if (!matchesExternalDependency)
|
||||
{
|
||||
Log.LogKoreBuildError(
|
||||
project.FullPath,
|
||||
KoreBuildErrors.UndefinedExternalDependency,
|
||||
message: $"Undefined external dependency on {dependency.Key}/{dependency.Value.Version}");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@ namespace RepoTasks.Utilities
|
|||
public const int RepoVersionDoesNotMatchProjectVersion = 2001;
|
||||
public const int RepoPackageVersionDoesNotMatchProjectPackageVersion = 2002;
|
||||
public const int DuplicatePackageReference = 2003;
|
||||
public const int MultipleExternalDependencyVersions = 2004;
|
||||
|
||||
// NuGet errors
|
||||
public const int InvalidNuspecFile = 4001;
|
||||
public const int PackageReferenceHasVersion = 4002;
|
||||
public const int DotNetCliReferenceReferenceHasVersion = 4003;
|
||||
public const int PackageVersionNotFoundInLineup = 4004;
|
||||
public const int UndefinedExternalDependency = 4005;
|
||||
|
||||
// Other unknown errors
|
||||
public const int PolicyFailedToApply = 5000;
|
||||
|
|
|
|||
|
|
@ -18,11 +18,27 @@ namespace RepoTasks
|
|||
{
|
||||
public class VerifyCoherentVersions : Microsoft.Build.Utilities.Task
|
||||
{
|
||||
[Required]
|
||||
public ITaskItem[] PackageFiles { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] ExternalDependencies { get; set; }
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
var packageLookup = new Dictionary<string, PackageInfo>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var dependencyMap = new Dictionary<string, ExternalDependency>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var dep in ExternalDependencies)
|
||||
{
|
||||
if (!dependencyMap.TryGetValue(dep.ItemSpec, out var externalDep))
|
||||
{
|
||||
dependencyMap[dep.ItemSpec] = externalDep = new ExternalDependency();
|
||||
}
|
||||
externalDep.IsPrivate = bool.TryParse(dep.GetMetadata("Private"), out var isPrivate) && isPrivate;
|
||||
externalDep.AllowedVersions.Add(dep.GetMetadata("Version"));
|
||||
}
|
||||
|
||||
foreach (var file in PackageFiles)
|
||||
{
|
||||
PackageInfo package;
|
||||
|
|
@ -47,51 +63,51 @@ namespace RepoTasks
|
|||
packageLookup[package.Id] = package;
|
||||
}
|
||||
|
||||
var dependencyIssues = new List<DependencyWithIssue>();
|
||||
foreach (var packageInfo in packageLookup.Values)
|
||||
{
|
||||
dependencyIssues.AddRange(Visit(packageLookup, packageInfo));
|
||||
}
|
||||
|
||||
var success = true;
|
||||
foreach (var mismatch in dependencyIssues)
|
||||
{
|
||||
var message = $"{mismatch.Info.Id} depends on {mismatch.Dependency.Id} " +
|
||||
$"v{mismatch.Dependency.VersionRange} ({mismatch.TargetFramework}) when the latest build is v{mismatch.Info.Version}.";
|
||||
Log.LogError(message);
|
||||
success = false;
|
||||
Visit(packageLookup, dependencyMap, packageInfo);
|
||||
}
|
||||
|
||||
Log.LogMessage(MessageImportance.High, $"Verified {PackageFiles.Length} package(s) have coherent versions");
|
||||
return success;
|
||||
return !Log.HasLoggedErrors;
|
||||
}
|
||||
|
||||
private class DependencyWithIssue
|
||||
private class ExternalDependency
|
||||
{
|
||||
public PackageDependency Dependency { get; set; }
|
||||
public PackageInfo Info { get; set; }
|
||||
public NuGetFramework TargetFramework { get; set; }
|
||||
public List<string> AllowedVersions { get; } = new List<string>();
|
||||
public bool IsPrivate { get; set; }
|
||||
}
|
||||
|
||||
private IEnumerable<DependencyWithIssue> Visit(IDictionary<string, PackageInfo> packageLookup, PackageInfo packageInfo)
|
||||
private void Visit(
|
||||
IReadOnlyDictionary<string, PackageInfo> packageLookup,
|
||||
IReadOnlyDictionary<string, ExternalDependency> dependencyMap,
|
||||
PackageInfo packageInfo)
|
||||
{
|
||||
Log.LogMessage(MessageImportance.Low, $"Processing package {packageInfo.Id}");
|
||||
try
|
||||
{
|
||||
var issues = new List<DependencyWithIssue>();
|
||||
foreach (var dependencySet in packageInfo.DependencyGroups)
|
||||
{
|
||||
// If the package doens't target any frameworks, just accept it
|
||||
if (dependencySet.TargetFramework == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var dependency in dependencySet.Packages)
|
||||
{
|
||||
if (!packageLookup.TryGetValue(dependency.Id, out var dependencyPackageInfo))
|
||||
PackageInfo dependencyPackageInfo;
|
||||
var depVersion = dependency.VersionRange.MinVersion.ToString();
|
||||
if (dependencyMap.TryGetValue(dependency.Id, out var externalDepInfo))
|
||||
{
|
||||
// External dependency
|
||||
if (externalDepInfo.IsPrivate)
|
||||
{
|
||||
Log.LogError($"Package {packageInfo.Id} has an external dependency on {dependency.Id}/{depVersion} which is marked as Private=true.");
|
||||
}
|
||||
else if (!externalDepInfo.AllowedVersions.Any(a => depVersion.Equals(a)))
|
||||
{
|
||||
Log.LogError($"Package {packageInfo.Id} has an external dependency on the wrong version of {dependency.Id}. "
|
||||
+ $"It uses {depVersion} but only {string.Join(" or ", externalDepInfo.AllowedVersions)} is allowed.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (!packageLookup.TryGetValue(dependency.Id, out dependencyPackageInfo))
|
||||
{
|
||||
Log.LogError($"Package {packageInfo.Id} has an undefined external dependency on {dependency.Id}/{depVersion}");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -100,21 +116,15 @@ namespace RepoTasks
|
|||
// For any dependency in the universe
|
||||
// Add a mismatch if the min version doesn't work out
|
||||
// (we only really care about >= minVersion)
|
||||
issues.Add(new DependencyWithIssue
|
||||
{
|
||||
Dependency = dependency,
|
||||
TargetFramework = dependencySet.TargetFramework,
|
||||
Info = dependencyPackageInfo
|
||||
});
|
||||
Log.LogError($"{packageInfo.Id} depends on {dependency.Id} " +
|
||||
$"{dependency.VersionRange} ({dependencySet.TargetFramework}) when the latest build is {depVersion}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return issues;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.LogError($"Unable to verify package {packageInfo.Id}");
|
||||
throw;
|
||||
Log.LogError($"Unexpected error while attempting to verify package {packageInfo.Id}.\r\n{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue