Skip to content

Commit

Permalink
Add option to enable floating versions in CPM
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffkl committed Oct 24, 2023
1 parent b02fdbb commit b087968
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ private async Task<PackageSpec> GetPackageSpecAsync(ISettings settings)
MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.RestoreLockedMode))),
CentralPackageVersionsEnabled = isCpvmEnabled,
CentralPackageVersionOverrideDisabled = GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.CentralPackageVersionOverrideEnabled).EqualsFalse(),
CentralPackageFloatingVersionsEnabled = MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.CentralPackageFloatingVersionsEnabled)),
CentralPackageTransitivePinningEnabled = MSBuildStringUtility.IsTrue(GetPropertySafe(_vsProjectAdapter.BuildProperties, ProjectBuildProperties.CentralPackageTransitivePinningEnabled)),
RestoreAuditProperties = auditProperties,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ internal static bool IsCentralPackageVersionOverrideDisabled(IEnumerable tfms)
return GetSingleNonEvaluatedPropertyOrNull(tfms, ProjectBuildProperties.CentralPackageVersionOverrideEnabled, (value) => value.EqualsFalse());
}

internal static bool IsCentralPackageFloatingVersionsEnabled(IEnumerable tfms)
{
return GetSingleNonEvaluatedPropertyOrNull(tfms, ProjectBuildProperties.CentralPackageFloatingVersionsEnabled, MSBuildStringUtility.IsTrue);
}

internal static bool IsCentralPackageTransitivePinningEnabled(IEnumerable tfms)
{
return GetSingleNonEvaluatedPropertyOrNull(tfms, ProjectBuildProperties.CentralPackageTransitivePinningEnabled, MSBuildStringUtility.IsTrue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ internal static PackageSpec ToPackageSpec(ProjectNames projectNames, IEnumerable
CacheFilePath = NoOpRestoreUtilities.GetProjectCacheFilePath(cacheRoot: outputPath),
RestoreLockProperties = VSNominationUtilities.GetRestoreLockProperties(TargetFrameworks),
CentralPackageVersionsEnabled = cpvmEnabled,
CentralPackageFloatingVersionsEnabled = VSNominationUtilities.IsCentralPackageFloatingVersionsEnabled(TargetFrameworks),
CentralPackageVersionOverrideDisabled = VSNominationUtilities.IsCentralPackageVersionOverrideDisabled(TargetFrameworks),
CentralPackageTransitivePinningEnabled = VSNominationUtilities.IsCentralPackageTransitivePinningEnabled(TargetFrameworks),
RestoreAuditProperties = VSNominationUtilities.GetRestoreAuditProperties(TargetFrameworks),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ private PackageSpec GetPackageSpec(IMSBuildProject project, IReadOnlyDictionary<

ProjectStyle? projectStyleOrNull = BuildTasksUtility.GetProjectRestoreStyleFromProjectProperty(project.GetProperty("RestoreProjectStyle"));

(bool isCentralPackageManagementEnabled, bool isCentralPackageVersionOverrideDisabled, bool isCentralPackageTransitivePinningEnabled) = GetCentralPackageManagementSettings(project, projectStyleOrNull);
(bool isCentralPackageManagementEnabled, bool isCentralPackageVersionOverrideDisabled, bool isCentralPackageTransitivePinningEnabled, bool isCentralPackageFloatingVersionsEnabled) = GetCentralPackageManagementSettings(project, projectStyleOrNull);

RestoreAuditProperties auditProperties = MSBuildRestoreUtility.GetRestoreAuditProperties(project);

Expand Down Expand Up @@ -854,6 +854,7 @@ private PackageSpec GetPackageSpec(IMSBuildProject project, IReadOnlyDictionary<
SkipContentFileWrite = IsLegacyProject(project),
ValidateRuntimeAssets = project.IsPropertyTrue("ValidateRuntimeIdentifierCompatibility"),
CentralPackageVersionsEnabled = isCentralPackageManagementEnabled && projectStyle == ProjectStyle.PackageReference,
CentralPackageFloatingVersionsEnabled = isCentralPackageFloatingVersionsEnabled,
CentralPackageVersionOverrideDisabled = isCentralPackageVersionOverrideDisabled,
CentralPackageTransitivePinningEnabled = isCentralPackageTransitivePinningEnabled,
RestoreAuditProperties = auditProperties
Expand Down Expand Up @@ -1030,15 +1031,15 @@ private ICollection<ProjectWithInnerNodes> LoadProjects(IEnumerable<ProjectGraph
/// </summary>
/// <param name="project">The <see cref="IMSBuildProject" /> to get the central package management settings for.</param>
/// <param name="projectStyle">The <see cref="ProjectStyle?" /> of the specified project. Specify <see langword="null" /> when the project does not define a restore style.</param>
/// <returns>A <see cref="Tuple{T1, T2}" /> containing values indicating whether or not central package management is enabled and if the ability to override a package version is disabled.</returns>
internal static (bool IsEnabled, bool IsVersionOverrideDisabled, bool IsCentralPackageTransitivePinningEnabled) GetCentralPackageManagementSettings(IMSBuildProject project, ProjectStyle? projectStyle)
/// <returns>A <see cref="Tuple{T1, T2, T3, T4}" /> containing values indicating whether or not central package management is enabled, if the ability to override a package version is disabled, if the ability to transitively pin a package version is enabled, and if floating versions are enabled.</returns>
internal static (bool IsEnabled, bool IsVersionOverrideDisabled, bool IsCentralPackageTransitivePinningEnabled, bool IsFloatingVersionsEnabled) GetCentralPackageManagementSettings(IMSBuildProject project, ProjectStyle? projectStyle)
{
if (!projectStyle.HasValue || (projectStyle.Value == ProjectStyle.PackageReference))
{
return (project.IsPropertyTrue("_CentralPackageVersionsEnabled"), project.IsPropertyFalse("CentralPackageVersionOverrideEnabled"), project.IsPropertyTrue("CentralPackageTransitivePinningEnabled"));
return (project.IsPropertyTrue("_CentralPackageVersionsEnabled"), project.IsPropertyFalse("CentralPackageVersionOverrideEnabled"), project.IsPropertyTrue("CentralPackageTransitivePinningEnabled"), project.IsPropertyTrue("CentralPackageFloatingVersionsEnabled"));
}

return (false, false, false);
return (false, false, false, false);
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<NuGetLockFilePath>$(NuGetLockFilePath)</NuGetLockFilePath>
<RestoreLockedMode>$(RestoreLockedMode)</RestoreLockedMode>
<_CentralPackageVersionsEnabled>$(_CentralPackageVersionsEnabled)</_CentralPackageVersionsEnabled>
<CentralPackageFloatingVersionsEnabled>$(CentralPackageFloatingVersionsEnabled)</CentralPackageFloatingVersionsEnabled>
<CentralPackageVersionOverrideEnabled>$(CentralPackageVersionOverrideEnabled)</CentralPackageVersionOverrideEnabled>
<CentralPackageTransitivePinningEnabled>$(CentralPackageTransitivePinningEnabled)</CentralPackageTransitivePinningEnabled>
<NuGetAudit>$(NuGetAudit)</NuGetAudit>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,15 @@ public bool AreCentralVersionRequirementsSatisfied(PackageReferenceArgs packageR
packageReferenceArgs.Logger.LogError(string.Format(CultureInfo.CurrentCulture, Strings.Error_CentralPackageVersions_MissingPackageVersion, string.Join(";", packageReferencedDependenciesWithoutCentralVersionDefined.Select(d => d.Name))));
return false;
}
var floatingVersionDependencies = packageSpec.TargetFrameworks.SelectMany(tfm => tfm.CentralPackageVersions.Values).Where(cpv => cpv.VersionRange.IsFloating);
if (floatingVersionDependencies.Any())

if (!packageSpec.RestoreMetadata.CentralPackageFloatingVersionsEnabled)
{
packageReferenceArgs.Logger.LogError(string.Format(CultureInfo.CurrentCulture, Strings.Error_CentralPackageVersions_FloatingVersionsAreNotAllowed));
return false;
var floatingVersionDependencies = packageSpec.TargetFrameworks.SelectMany(tfm => tfm.CentralPackageVersions.Values).Where(cpv => cpv.VersionRange.IsFloating);
if (floatingVersionDependencies.Any())
{
packageReferenceArgs.Logger.LogError(string.Format(CultureInfo.CurrentCulture, Strings.Error_CentralPackageVersions_FloatingVersionsAreNotAllowed));
return false;
}
}

// PackageVersion should not be defined outside the project file.
Expand Down
13 changes: 9 additions & 4 deletions src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -599,12 +599,17 @@ private async Task<bool> AreCentralVersionRequirementsSatisfiedAsync(RestoreRequ
await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1010, string.Format(CultureInfo.CurrentCulture, Strings.Error_CentralPackageVersions_MissingPackageVersion, string.Join(";", packageReferencedDependenciesWithoutCentralVersionDefined.Select(d => d.Name)))));
return false;
}
var floatingVersionDependencies = _request.Project.TargetFrameworks.SelectMany(tfm => tfm.CentralPackageVersions.Values).Where(cpv => cpv.VersionRange.IsFloating);
if (floatingVersionDependencies.Any())

if (!restoreRequest.Project.RestoreMetadata.CentralPackageFloatingVersionsEnabled)
{
await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1011, Strings.Error_CentralPackageVersions_FloatingVersionsAreNotAllowed));
return false;
var floatingVersionDependencies = _request.Project.TargetFrameworks.SelectMany(tfm => tfm.CentralPackageVersions.Values).Where(cpv => cpv.VersionRange.IsFloating);
if (floatingVersionDependencies.Any())
{
await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1011, Strings.Error_CentralPackageVersions_FloatingVersionsAreNotAllowed));
return false;
}
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public static PackageSpec GetPackageSpec(IEnumerable<IMSBuildItem> items)
{
ProjectStyle restoreType = GetProjectStyle(specItem);

(bool isCentralPackageManagementEnabled, bool isCentralPackageVersionOverrideDisabled, bool isCentralPackageTransitivePinningEnabled) = GetCentralPackageManagementSettings(specItem, restoreType);
(bool isCentralPackageManagementEnabled, bool isCentralPackageVersionOverrideDisabled, bool isCentralPackageTransitivePinningEnabled, bool isCentralPackageFloatingVersionsEnabled) = GetCentralPackageManagementSettings(specItem, restoreType);

// Get base spec
if (restoreType == ProjectStyle.ProjectJson)
Expand Down Expand Up @@ -296,6 +296,7 @@ public static PackageSpec GetPackageSpec(IEnumerable<IMSBuildItem> items)

result.RestoreMetadata.CentralPackageVersionsEnabled = isCentralPackageManagementEnabled;
result.RestoreMetadata.CentralPackageVersionOverrideDisabled = isCentralPackageVersionOverrideDisabled;
result.RestoreMetadata.CentralPackageFloatingVersionsEnabled = isCentralPackageFloatingVersionsEnabled;
result.RestoreMetadata.CentralPackageTransitivePinningEnabled = isCentralPackageTransitivePinningEnabled;
}

Expand Down Expand Up @@ -1055,11 +1056,12 @@ private static ProjectStyle GetProjectStyle(IMSBuildItem projectSpecItem)
return restoreType;
}

internal static (bool IsEnabled, bool IsVersionOverrideDisabled, bool IsCentralPackageTransitivePinningEnabled) GetCentralPackageManagementSettings(IMSBuildItem projectSpecItem, ProjectStyle projectStyle)
internal static (bool IsEnabled, bool IsVersionOverrideDisabled, bool IsCentralPackageTransitivePinningEnabled, bool isCentralPackageFloatingVersionsEnabled) GetCentralPackageManagementSettings(IMSBuildItem projectSpecItem, ProjectStyle projectStyle)
{
return (IsPropertyTrue(projectSpecItem, "_CentralPackageVersionsEnabled") && projectStyle == ProjectStyle.PackageReference,
IsPropertyFalse(projectSpecItem, "CentralPackageVersionOverrideEnabled"),
IsPropertyTrue(projectSpecItem, "CentralPackageTransitivePinningEnabled"));
IsPropertyTrue(projectSpecItem, "CentralPackageTransitivePinningEnabled"),
IsPropertyTrue(projectSpecItem, "CentralPackageFloatingVersionsEnabled"));
}

private static void AddCentralPackageVersions(PackageSpec spec, IEnumerable<IMSBuildItem> items)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ public static class ProjectBuildProperties
public const string NuGetAudit = nameof(NuGetAudit);
public const string NuGetAuditLevel = nameof(NuGetAuditLevel);
public const string NuGetAuditMode = nameof(NuGetAuditMode);
public const string CentralPackageFloatingVersionsEnabled = nameof(CentralPackageFloatingVersionsEnabled);
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#nullable enable
~const NuGet.ProjectManagement.ProjectBuildProperties.CentralPackageFloatingVersionsEnabled = "CentralPackageFloatingVersionsEnabled" -> string
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,7 @@ private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, I
private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec packageSpec)
{
var centralPackageVersionsManagementEnabled = false;
var centralPackageFloatingVersionsEnabled = false;
var centralPackageVersionOverrideDisabled = false;
var CentralPackageTransitivePinningEnabled = false;
List<string> configFilePaths = null;
Expand Down Expand Up @@ -935,6 +936,10 @@ private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec p
centralPackageVersionsManagementEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath);
break;

case "centralPackageFloatingVersionsEnabled":
centralPackageFloatingVersionsEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath);
break;

case "centralPackageVersionOverrideDisabled":
centralPackageVersionOverrideDisabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath);
break;
Expand Down Expand Up @@ -1131,6 +1136,7 @@ private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec p
}

msbuildMetadata.CentralPackageVersionsEnabled = centralPackageVersionsManagementEnabled;
msbuildMetadata.CentralPackageFloatingVersionsEnabled = centralPackageFloatingVersionsEnabled;
msbuildMetadata.CentralPackageVersionOverrideDisabled = centralPackageVersionOverrideDisabled;
msbuildMetadata.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled;
msbuildMetadata.RestoreAuditProperties = auditProperties;
Expand Down
1 change: 1 addition & 0 deletions src/NuGet.Core/NuGet.ProjectModel/PackageSpecWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ private static void WriteMetadataBooleans(IObjectWriter writer, ProjectRestoreMe
SetValueIfTrue(writer, "validateRuntimeAssets", msbuildMetadata.ValidateRuntimeAssets);
SetValueIfTrue(writer, "skipContentFileWrite", msbuildMetadata.SkipContentFileWrite);
SetValueIfTrue(writer, "centralPackageVersionsManagementEnabled", msbuildMetadata.CentralPackageVersionsEnabled);
SetValueIfTrue(writer, "centralPackageFloatingVersionsEnabled", msbuildMetadata.CentralPackageFloatingVersionsEnabled);
SetValueIfTrue(writer, "centralPackageVersionOverrideDisabled", msbuildMetadata.CentralPackageVersionOverrideDisabled);
SetValueIfTrue(writer, "CentralPackageTransitivePinningEnabled", msbuildMetadata.CentralPackageTransitivePinningEnabled);
}
Expand Down
8 changes: 8 additions & 0 deletions src/NuGet.Core/NuGet.ProjectModel/ProjectRestoreMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ public class ProjectRestoreMetadata : IEquatable<ProjectRestoreMetadata>
/// </summary>
public bool CentralPackageVersionOverrideDisabled { get; set; }

/// <summary>
/// Gets or sets a value indicating whether or not floating versions are allowed when using central package management (CPM).
/// </summary>
public bool CentralPackageFloatingVersionsEnabled { get; set; }

public bool CentralPackageTransitivePinningEnabled { get; set; }

public RestoreAuditProperties RestoreAuditProperties { get; set; }
Expand Down Expand Up @@ -153,6 +158,7 @@ public override int GetHashCode()
hashCode.AddObject(ProjectWideWarningProperties);
hashCode.AddObject(RestoreLockProperties);
hashCode.AddObject(CentralPackageVersionsEnabled);
hashCode.AddObject(CentralPackageFloatingVersionsEnabled);
hashCode.AddObject(CentralPackageVersionOverrideDisabled);
hashCode.AddObject(CentralPackageTransitivePinningEnabled);
hashCode.AddObject(RestoreAuditProperties);
Expand Down Expand Up @@ -198,6 +204,7 @@ public bool Equals(ProjectRestoreMetadata other)
EqualityUtility.EqualsWithNullCheck(ProjectWideWarningProperties, other.ProjectWideWarningProperties) &&
EqualityUtility.EqualsWithNullCheck(RestoreLockProperties, other.RestoreLockProperties) &&
EqualityUtility.EqualsWithNullCheck(CentralPackageVersionsEnabled, other.CentralPackageVersionsEnabled) &&
EqualityUtility.EqualsWithNullCheck(CentralPackageFloatingVersionsEnabled, other.CentralPackageFloatingVersionsEnabled) &&
EqualityUtility.EqualsWithNullCheck(CentralPackageVersionOverrideDisabled, other.CentralPackageVersionOverrideDisabled) &&
EqualityUtility.EqualsWithNullCheck(CentralPackageTransitivePinningEnabled, other.CentralPackageTransitivePinningEnabled) &&
RestoreAuditProperties == other.RestoreAuditProperties;
Expand Down Expand Up @@ -233,6 +240,7 @@ protected void FillClone(ProjectRestoreMetadata clone)
clone.ProjectWideWarningProperties = ProjectWideWarningProperties?.Clone();
clone.RestoreLockProperties = RestoreLockProperties?.Clone();
clone.CentralPackageVersionsEnabled = CentralPackageVersionsEnabled;
clone.CentralPackageFloatingVersionsEnabled = CentralPackageFloatingVersionsEnabled;
clone.CentralPackageVersionOverrideDisabled = CentralPackageVersionOverrideDisabled;
clone.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled;
clone.RestoreAuditProperties = RestoreAuditProperties?.Clone();
Expand Down
2 changes: 2 additions & 0 deletions src/NuGet.Core/NuGet.ProjectModel/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
NuGet.ProjectModel.ProjectRestoreMetadata.CentralPackageFloatingVersionsEnabled.get -> bool
NuGet.ProjectModel.ProjectRestoreMetadata.CentralPackageFloatingVersionsEnabled.set -> void
Loading

0 comments on commit b087968

Please sign in to comment.