Widen dependency version range on Microsoft.AspNetCore.App to allow patch updates (#1186)

Originally, we thought using exact version ranges on the dependencies of Microsoft.AspNetCore.App
would help protect consumers from lifting binaries out of the shared framework. However,
this makes it difficult for consumers to use packages that share a dependency with .App.
When users tried to mix Microsoft.EntityFramework.SQLite 2.1.1 with Microsoft.AspNetCore.App 2.1.0,
NuGet errors and warnings made it difficult to reason about what was wrong, and how to resolve it.

This changes the dependency version range to allow uses to upgrade within the major.minor patch family
without needing to override NuGet warnings. This removes some of the protections against users
unintentionally lifting to a binary newer than the shared framework, however, after lots of discussion,
we believe this is a better user experience.
This commit is contained in:
Nate McMaster 2018-05-31 12:40:52 -07:00 committed by GitHub
parent 079232d3c5
commit 309e9e3077
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 8 deletions

View File

@ -70,7 +70,7 @@
<RepoTasks.AddMetapackageReferences
ReferencePackagePath="$(MetapackageWorkDirectory)$(MetapackageName).csproj"
MetapackageReferenceType="$(MetapackageReferenceType)"
LockToExactVersions="$(LockToExactVersions)"
DependencyVersionRangeType="$(MetapackageDependencyVersionRangeType)"
BuildArtifacts="@(ArtifactInfo)"
PackageArtifacts="@(PackageArtifact)"
ExternalDependencies="@(ExternalDependency)" />
@ -87,7 +87,7 @@
<AdditionalProperties>
MetapackageName=Microsoft.AspNetCore.App;
MetapackageReferenceType=AppMetapackage;
LockToExactVersions=true
MetapackageDependencyVersionRangeType=MajorMinor
</AdditionalProperties>
</_MetapackageBuilderProject>
@ -95,7 +95,7 @@
<AdditionalProperties>
MetapackageName=Microsoft.AspNetCore.All;
MetapackageReferenceType=AllMetapackage;
LockToExactVersions=false
MetapackageDependencyVersionRangeType=Minimum
</AdditionalProperties>
</_MetapackageBuilderProject>
@ -103,7 +103,7 @@
<AdditionalProperties>
MetapackageName=Microsoft.AspNetCore.Analyzers;
MetapackageReferenceType=Analyzer;
LockToExactVersions=true
MetapackageDependencyVersionRangeType=Minimum
</AdditionalProperties>
</_MetapackageBuilderProject>
</ItemGroup>

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Xml;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using NuGet.Versioning;
using RepoTasks.Utilities;
namespace RepoTasks
@ -19,7 +20,14 @@ namespace RepoTasks
public string MetapackageReferenceType { get; set; }
[Required]
public bool LockToExactVersions { get; set; }
public string DependencyVersionRangeType { get; set; }
// MSBuild doesn't allow binding to enums directly.
private enum VersionRangeType
{
Minimum, // [1.1.1, )
MajorMinor, // [1.1.1, 1.2.0)
}
[Required]
public ITaskItem[] BuildArtifacts { get; set; }
@ -32,6 +40,12 @@ namespace RepoTasks
public override bool Execute()
{
if (!Enum.TryParse<VersionRangeType>(DependencyVersionRangeType, out var dependencyVersionType))
{
Log.LogError("Unexpected value {0} for DependencyVersionRangeType", DependencyVersionRangeType);
return false;
}
// Parse input
var metapackageArtifacts = PackageArtifacts.Where(p => p.GetMetadata(MetapackageReferenceType) == "true");
var externalArtifacts = ExternalDependencies.Where(p => p.GetMetadata(MetapackageReferenceType) == "true");
@ -65,8 +79,13 @@ namespace RepoTasks
throw;
}
var packageVersionValue = LockToExactVersions ? $"[{packageVersion}]" : packageVersion;
if (string.IsNullOrEmpty(packageVersion))
{
Log.LogError("Missing version information for package {0}", packageName);
continue;
}
var packageVersionValue = GetDependencyVersion(dependencyVersionType, packageName, packageVersion);
Log.LogMessage(MessageImportance.High, $" - Package: {packageName} Version: {packageVersionValue}");
var packageReferenceElement = xmlDoc.CreateElement("PackageReference");
@ -81,7 +100,14 @@ namespace RepoTasks
{
var packageName = package.ItemSpec;
var packageVersion = package.GetMetadata("Version");
var packageVersionValue = LockToExactVersions ? $"[{packageVersion}]" : packageVersion;
if (string.IsNullOrEmpty(packageVersion))
{
Log.LogError("Missing version information for package {0}", packageName);
continue;
}
var packageVersionValue = GetDependencyVersion(dependencyVersionType, packageName, packageVersion);
Log.LogMessage(MessageImportance.High, $" - Package: {packageName} Version: {packageVersionValue}");
@ -99,7 +125,25 @@ namespace RepoTasks
xmlDoc.AppendChild(projectElement);
xmlDoc.Save(ReferencePackagePath);
return true;
return !Log.HasLoggedErrors;
}
private string GetDependencyVersion(VersionRangeType dependencyVersionType, string packageName, string packageVersion)
{
switch (dependencyVersionType)
{
case VersionRangeType.MajorMinor:
if (!NuGetVersion.TryParse(packageVersion, out var nugetVersion))
{
Log.LogError("Invalid NuGet version '{0}' for package {1}", packageVersion, packageName);
return null;
}
return $"[{packageVersion}, {nugetVersion.Major}.{nugetVersion.Minor + 1}.0)";
case VersionRangeType.Minimum:
return packageVersion;
default:
throw new NotImplementedException();
}
}
}
}