Support packages both built in Universe and used as external dependencies

- `AnalyzeBuildGraph` fix should correct Update Universe build break
- `VerifyCoherentVersions` fix should correct UniverseCoherence build break

nits:
- add and rename a couple of variables for clarity and reduced repetition
- remove and sort `using`s
This commit is contained in:
Doug Bunting 2018-06-22 23:44:26 -07:00 committed by Doug Bunting
parent 7c2d0058d2
commit f47e86439d
2 changed files with 43 additions and 18 deletions

View File

@ -2,19 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.IO; using System.IO;
using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using Microsoft.Build.Framework; using Microsoft.Build.Framework;
using Microsoft.Build.Utilities; using Microsoft.Build.Utilities;
using NuGet.Frameworks;
using NuGet.Versioning; using NuGet.Versioning;
using RepoTools.BuildGraph;
using RepoTasks.ProjectModel; using RepoTasks.ProjectModel;
using RepoTasks.Utilities; using RepoTasks.Utilities;
using RepoTools.BuildGraph;
namespace RepoTasks namespace RepoTasks
{ {
@ -117,17 +115,19 @@ namespace RepoTasks
foreach (var tfm in project.Frameworks) foreach (var tfm in project.Frameworks)
foreach (var dependency in tfm.Dependencies) foreach (var dependency in tfm.Dependencies)
{ {
var dependencyVersion = dependency.Value.Version;
if (!buildPackageMap.TryGetValue(dependency.Key, out var package)) if (!buildPackageMap.TryGetValue(dependency.Key, out var package))
{ {
var idx = -1;
// This dependency is not one of the packages that will be compiled by this run of Universe. // This dependency is not one of the packages that will be compiled by this run of Universe.
// Must match an external dependency, including its Version.
var idx = -1;
if (!dependencyMap.TryGetValue(dependency.Key, out var externalVersions) if (!dependencyMap.TryGetValue(dependency.Key, out var externalVersions)
|| (idx = externalVersions.FindIndex(0, externalVersions.Count, i => i.Version == dependency.Value.Version)) < 0) || (idx = externalVersions.FindIndex(0, externalVersions.Count, i => i.Version == dependencyVersion)) < 0)
{ {
Log.LogKoreBuildError( Log.LogKoreBuildError(
project.FullPath, project.FullPath,
KoreBuildErrors.UndefinedExternalDependency, KoreBuildErrors.UndefinedExternalDependency,
message: $"Undefined external dependency on {dependency.Key}/{dependency.Value.Version}"); message: $"Undefined external dependency on {dependency.Key}/{dependencyVersion}");
} }
if (idx >= 0) if (idx >= 0)
@ -137,7 +137,8 @@ namespace RepoTasks
continue; continue;
} }
var refVersion = VersionRange.Parse(dependency.Value.Version); // This package will be created in this Universe run.
var refVersion = VersionRange.Parse(dependencyVersion);
if (refVersion.IsFloating && refVersion.Float.Satisfies(package.PackageInfo.Version)) if (refVersion.IsFloating && refVersion.Float.Satisfies(package.PackageInfo.Version))
{ {
continue; continue;
@ -146,6 +147,13 @@ namespace RepoTasks
{ {
continue; continue;
} }
else if (dependencyMap.TryGetValue(dependency.Key, out var externalDependency) &&
externalDependency.Any(ext => ext.Version == dependencyVersion))
{
// Project depends on external version of this package, not the version built in Universe. That's
// fine in benchmark apps for example.
continue;
}
if (!solution.ShouldBuild && solution.Shipped) if (!solution.ShouldBuild && solution.Shipped)
{ {
@ -157,7 +165,7 @@ namespace RepoTasks
Solution = solution, Solution = solution,
Project = project, Project = project,
PackageId = dependency.Key, PackageId = dependency.Key,
ActualVersion = dependency.Value.Version, ActualVersion = dependencyVersion,
ExpectedVersion = package.PackageInfo.Version, ExpectedVersion = package.PackageInfo.Version,
}); });
} }

View File

@ -5,12 +5,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using Microsoft.Build.Framework; using Microsoft.Build.Framework;
using NuGet.Frameworks;
using NuGet.Packaging; using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.Versioning;
using RepoTasks.ProjectModel; using RepoTasks.ProjectModel;
namespace RepoTasks namespace RepoTasks
@ -91,29 +87,50 @@ namespace RepoTasks
foreach (var dependency in dependencySet.Packages) foreach (var dependency in dependencySet.Packages)
{ {
PackageInfo dependencyPackageInfo; PackageInfo dependencyPackageInfo;
var depVersion = dependency.VersionRange.MinVersion.ToString(); var minVersion = dependency.VersionRange.MinVersion;
var minVersionString = minVersion.ToString();
if (dependencyMap.TryGetValue(dependency.Id, out var externalDepVersions)) if (dependencyMap.TryGetValue(dependency.Id, out var externalDepVersions))
{ {
var matchedVersion = externalDepVersions.FirstOrDefault(d => depVersion.Equals(d)); var matchedVersion = externalDepVersions.FirstOrDefault(d => minVersionString.Equals(d));
// If dependency does not match an external dependency version, check if matching version
// will be built in Universe. That's fine in benchmark apps for example.
var universePackageVersion = string.Empty;
if (matchedVersion == null &&
packageLookup.TryGetValue(dependency.Id, out var universePackageInfo))
{
if (universePackageInfo.Version == minVersion)
{
continue;
}
// Include Universe version in following error message.
universePackageVersion = universePackageInfo.Version.ToString();
}
if (matchedVersion == null) if (matchedVersion == null)
{ {
var versions = string.Join(" or ", externalDepVersions); var versions = string.Join(" or ", externalDepVersions);
if (!string.IsNullOrEmpty(universePackageVersion))
{
versions += $" or {universePackageVersion}";
}
Log.LogError($"Package {packageInfo.Id} has an external dependency on the wrong version of {dependency.Id}. " Log.LogError($"Package {packageInfo.Id} has an external dependency on the wrong version of {dependency.Id}. "
+ $"It uses {depVersion} but only {versions} is allowed."); + $"It uses {minVersionString} but only {versions} is allowed.");
} }
continue; continue;
} }
else if (!packageLookup.TryGetValue(dependency.Id, out dependencyPackageInfo)) else if (!packageLookup.TryGetValue(dependency.Id, out dependencyPackageInfo))
{ {
Log.LogError($"Package {packageInfo.Id} has an undefined external dependency on {dependency.Id}/{depVersion}. " + Log.LogError($"Package {packageInfo.Id} has an undefined external dependency on {dependency.Id}/{minVersionString}. " +
"If the package is built in aspnet/Universe, make sure it is also marked as 'ship'. " + "If the package is built in aspnet/Universe, make sure it is also marked as 'ship'. " +
"If it is an external dependency, add it as a new ExternalDependency."); "If it is an external dependency, add it as a new ExternalDependency.");
continue; continue;
} }
if (dependencyPackageInfo.Version != dependency.VersionRange.MinVersion) if (dependencyPackageInfo.Version != minVersion)
{ {
// For any dependency in the universe // For any dependency in the universe
// Add a mismatch if the min version doesn't work out // Add a mismatch if the min version doesn't work out