Skip to content

Commit

Permalink
Use SdkAnalysisLevel in restorecommand http-errors (#5925)
Browse files Browse the repository at this point in the history
Use SdkAnalysisLevel in restorecommand http-errors (#5925)
  • Loading branch information
Nigusu-Allehu committed Jul 17, 2024
1 parent 12a39e1 commit 18a6790
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 5 deletions.
14 changes: 13 additions & 1 deletion src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,20 @@ public async Task<RestoreResult> ExecuteAsync(CancellationToken token)
var source = remoteProvider.Source;
if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections)
{
await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1302,
var isErrorEnabled = SdkAnalysisLevelMinimums.IsEnabled(_request.Project.RestoreMetadata.SdkAnalysisLevel,
_request.Project.RestoreMetadata.UsingMicrosoftNETSdk,
SdkAnalysisLevelMinimums.HttpErrorSdkAnalysisLevelMinimumValue);

if (isErrorEnabled)
{
await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1302,
string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "restore", source.Source)));
}
else
{
await _logger.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1803,
string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "restore", source.Source)));
}
}
}
}
Expand Down
40 changes: 40 additions & 0 deletions src/NuGet.Core/NuGet.Commands/Utility/SdkAnalysisLevelMinimums.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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 NuGet.Versioning;

namespace NuGet.Commands
{
/// <summary>
/// Defines constants that specify the minimum SDK analysis level required to enable new features.
/// </summary>
internal static class SdkAnalysisLevelMinimums
{
/// <summary>
/// Minimum SDK Analysis Level required to enable HTTP Errors is 9.0.100.
/// </summary>
internal static readonly NuGetVersion HttpErrorSdkAnalysisLevelMinimumValue = new("9.0.100");

/// <summary>
/// Determines whether the feature is enabled based on the SDK analysis level.
/// </summary>
/// <param name="sdkAnalysisLevel">The project SdkAnalysisLevel value </param>
/// <param name="usingMicrosoftNetSdk">Is it SDK project or not</param>
/// <param name="minSdkVersion">The minimum version of the SDK required for the feature to be enabled.</param>
/// <returns>Returns true if the feature should be enabled based on the given parameters; otherwise, false.</returns>
public static bool IsEnabled(NuGetVersion sdkAnalysisLevel, bool usingMicrosoftNetSdk, NuGetVersion minSdkVersion)
{
if (sdkAnalysisLevel != null && sdkAnalysisLevel >= minSdkVersion ||
sdkAnalysisLevel == null && usingMicrosoftNetSdk == false)
{
// SdkAnalysisLevel >= minSdkVersion or SdkAnalysisLevel is null and not using Microsoft NET Sdk
return true;
}
else
{
// SdkAnalysisLevel < minSdkVersion or SdkAnalysisLevel is null and using Microsoft NET Sdk
return false;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4073,8 +4073,8 @@ public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsFalse_ThrowsE
using var pathContext = new SimpleTestPathContext();
var packageA = new SimpleTestPackageContext("a", "1.0.0");
await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA);
string httpSourceUrl = "http://api.source/index.json";
string httpsSourceUrl = "https://api.source/index.json";
string httpSourceUrl = "http://unit.test/index.json";
string httpsSourceUrl = "https://unit.test/index.json";
pathContext.Settings.AddSource("http-feed", httpSourceUrl, "False");
pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "False");

Expand All @@ -4095,15 +4095,103 @@ public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsFalse_ThrowsE
Assert.Contains(httpSourceUrl, logMessage.Message);
}

[Fact]
public async Task Restore_WithHttpSourceSdkAnalysisLevelLowerThan90100_Warns()
{
// Arrange
using var pathContext = new SimpleTestPathContext();
var packageA = new SimpleTestPackageContext("a", "1.0.0");
await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA);
string httpSourceUrl = "http://unit.test/index.json";
string httpsSourceUrl = "https://unit.test/index.json";
pathContext.Settings.AddSource("http-feed", httpSourceUrl, "False");
pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "False");

var logger = new TestLogger();
ISettings settings = Settings.LoadDefaultSettings(pathContext.SolutionRoot);
var project1Spec = ProjectTestHelpers.GetPackageSpec(settings, "Project1", pathContext.SolutionRoot, framework: "net5.0");
project1Spec.RestoreMetadata.SdkAnalysisLevel = new NuGetVersion("7.8.100");
var request = ProjectTestHelpers.CreateRestoreRequest(pathContext, logger, project1Spec);
var command = new RestoreCommand(request);

// Act
var result = await command.ExecuteAsync();

// Assert
result.LockFile.LogMessages.Should().HaveCount(1);
IAssetsLogMessage logMessage = result.LockFile.LogMessages[0];
logMessage.Code.Should().Be(NuGetLogCode.NU1803);
Assert.Contains(httpSourceUrl, logMessage.Message);
}

[Fact]
public async Task Restore_WithHttpSourceSdkAnalysisLevelHigherThan90100_ThrowsAnError()
{
// Arrange
using var pathContext = new SimpleTestPathContext();
var packageA = new SimpleTestPackageContext("a", "1.0.0");
await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA);
string httpSourceUrl = "http://unit.test/index.json";
string httpsSourceUrl = "https://unit.test/index.json";
pathContext.Settings.AddSource("http-feed", httpSourceUrl, "False");
pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "False");

var logger = new TestLogger();
ISettings settings = Settings.LoadDefaultSettings(pathContext.SolutionRoot);
var project1Spec = ProjectTestHelpers.GetPackageSpec(settings, "Project1", pathContext.SolutionRoot, framework: "net5.0");
project1Spec.RestoreMetadata.SdkAnalysisLevel = new NuGetVersion("9.0.400");
var request = ProjectTestHelpers.CreateRestoreRequest(pathContext, logger, project1Spec);
var command = new RestoreCommand(request);

// Act
var result = await command.ExecuteAsync();

// Assert
result.Success.Should().BeFalse(because: logger.ShowMessages());
result.LockFile.LogMessages.Should().HaveCount(1);
IAssetsLogMessage logMessage = result.LockFile.LogMessages[0];
logMessage.Code.Should().Be(NuGetLogCode.NU1302);
Assert.Contains(httpSourceUrl, logMessage.Message);
}

[Theory]
[InlineData("8.0.100")]
[InlineData("9.0.400")]
public async Task Restore_WithHttpSourceAnySdkAnalysisLevelWithAllowInsecureConnectionsTrue_Succeeds(string version)
{
// Arrange
using var pathContext = new SimpleTestPathContext();
var packageA = new SimpleTestPackageContext("a", "1.0.0");
await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA);
string httpSourceUrl = "http://unit.test/index.json";
string httpsSourceUrl = "https://unit.test/index.json";
pathContext.Settings.AddSource("http-feed", httpSourceUrl, "True");
pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "True");

var logger = new TestLogger();
ISettings settings = Settings.LoadDefaultSettings(pathContext.SolutionRoot);
var project1Spec = ProjectTestHelpers.GetPackageSpec(settings, "Project1", pathContext.SolutionRoot, framework: "net5.0");
project1Spec.RestoreMetadata.SdkAnalysisLevel = new NuGetVersion(version);
var request = ProjectTestHelpers.CreateRestoreRequest(pathContext, logger, project1Spec);
var command = new RestoreCommand(request);

// Act
var result = await command.ExecuteAsync();

// Assert
result.Success.Should().BeTrue(because: logger.ShowMessages());
result.LockFile.LogMessages.Should().HaveCount(0);
}

[Fact]
public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsTrue_Succeeds()
{
// Arrange
using var pathContext = new SimpleTestPathContext();
var packageA = new SimpleTestPackageContext("a", "1.0.0");
await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA);
string httpSourceUrl = "http://api.source/index.json";
string httpsSourceUrl = "https://api.source/index.json";
string httpSourceUrl = "http://unit.test/index.json";
string httpsSourceUrl = "https://unit.test/index.json";
pathContext.Settings.AddSource("http-feed", httpSourceUrl, "True");
pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "True");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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 NuGet.Versioning;
using Xunit;

namespace NuGet.Commands.Test
{
public class SdkAnalysisLevelMinimumsTests
{
[Fact]
public void IsEnabled_WhenSdkAnalysisLevelIsNullAndUsingMicrosoftNetSdkIsFalse_ShouldReturnTrue()
{
var result = SdkAnalysisLevelMinimums.IsEnabled(null, false, new NuGetVersion("9.0.100"));
Assert.True(result);
}

[Fact]
public void IsEnabled_WhenSdkAnalysisLevelIsNullAndUsingMicrosoftNetSdkIsTrue_ShouldReturnFalse()
{
var result = SdkAnalysisLevelMinimums.IsEnabled(null, true, new NuGetVersion("9.0.100"));
Assert.False(result);
}

[Fact]
public void IsEnabled_WhenSdkAnalysisLevelIsLessThanMinSdkVersion_ShouldReturnFalse()
{
var result = SdkAnalysisLevelMinimums.IsEnabled(new NuGetVersion("8.0.900"), true, new NuGetVersion("9.0.100"));
Assert.False(result);
}

[Fact]
public void IsEnabled_WhenSdkAnalysisLevelIsEqualToMinSdkVersion_ShouldReturnTrue()
{
var result = SdkAnalysisLevelMinimums.IsEnabled(new NuGetVersion("9.0.100"), true, new NuGetVersion("9.0.100"));
Assert.True(result);
}

[Fact]
public void IsEnabled_WhenSdkAnalysisLevelIsGreaterThanMinSdkVersion_ShouldReturnTrue()
{
var result = SdkAnalysisLevelMinimums.IsEnabled(new NuGetVersion("9.0.101"), true, new NuGetVersion("9.0.100"));
Assert.True(result);
}
}
}

0 comments on commit 18a6790

Please sign in to comment.