Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable users to install unlisted version of tool if specify the exact match of the version of the tool #36021

Merged
merged 5 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Task<string> DownloadPackageAsync(PackageId packageId,
NuGetVersion packageVersion = null,
PackageSourceLocation packageSourceLocation = null,
bool includePreview = false,
bool includeUnlisted = false,
DirectoryPath? downloadFolder = null,
PackageSourceMapping packageSourceMapping = null);

Expand Down
27 changes: 17 additions & 10 deletions src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,14 @@ public async Task<string> DownloadPackageAsync(PackageId packageId,
NuGetVersion packageVersion = null,
PackageSourceLocation packageSourceLocation = null,
bool includePreview = false,
bool includeUnlisted = false,
DirectoryPath? downloadFolder = null,
PackageSourceMapping packageSourceMapping = null)
{
CancellationToken cancellationToken = CancellationToken.None;

(var source, var resolvedPackageVersion) = await GetPackageSourceAndVersion(packageId, packageVersion,
packageSourceLocation, includePreview, packageSourceMapping).ConfigureAwait(false);
packageSourceLocation, includePreview, includeUnlisted, packageSourceMapping).ConfigureAwait(false);

FindPackageByIdResource resource = null;
SourceRepository repository = GetSourceRepository(source);
Expand Down Expand Up @@ -220,6 +221,7 @@ public async Task<IEnumerable<string>> ExtractPackageAsync(string packagePath, D
NuGetVersion packageVersion = null,
PackageSourceLocation packageSourceLocation = null,
bool includePreview = false,
bool includeUnlisted = false,
PackageSourceMapping packageSourceMapping = null)
{
CancellationToken cancellationToken = CancellationToken.None;
Expand All @@ -239,7 +241,7 @@ public async Task<IEnumerable<string>> ExtractPackageAsync(string packagePath, D
packageVersion = new NuGetVersion(packageVersion);
(source, packageMetadata) =
await GetPackageMetadataAsync(packageId.ToString(), packageVersion, packagesSources,
cancellationToken).ConfigureAwait(false);
cancellationToken, includeUnlisted).ConfigureAwait(false);
}

packageVersion = packageMetadata.Identity.Version;
Expand Down Expand Up @@ -421,14 +423,14 @@ private IEnumerable<PackageSource> LoadNuGetSources(PackageId packageId, Package
{
foundPackagesBySource = packageSources.Select(source => GetPackageMetadataAsync(source,
packageIdentifier,
true, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()).ToArray();
true, false, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()).ToArray();
}
else
{
foundPackagesBySource =
await Task.WhenAll(
packageSources.Select(source => GetPackageMetadataAsync(source, packageIdentifier,
true, cancellationToken)))
true, false, cancellationToken)))
.ConfigureAwait(false);
}

Expand Down Expand Up @@ -475,14 +477,14 @@ await Task.WhenAll(
{
foundPackagesBySource = packageSources.Select(source => GetPackageMetadataAsync(source,
packageIdentifier,
true, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()).ToArray();
true, false, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()).ToArray();
}
else
{
foundPackagesBySource =
await Task.WhenAll(
packageSources.Select(source => GetPackageMetadataAsync(source, packageIdentifier,
true, cancellationToken)))
true, false, cancellationToken)))
.ConfigureAwait(false);
}

Expand Down Expand Up @@ -525,6 +527,11 @@ public async Task<NuGetVersion> GetBestPackageVersionAsync(PackageId packageId,
VersionRange versionRange,
PackageSourceLocation packageSourceLocation = null)
{
if(versionRange.MinVersion != null && versionRange.MaxVersion != null && versionRange.MinVersion == versionRange.MaxVersion)
{
return versionRange.MinVersion;
}

CancellationToken cancellationToken = CancellationToken.None;
IPackageSearchMetadata packageMetadata;

Expand All @@ -539,7 +546,7 @@ public async Task<NuGetVersion> GetBestPackageVersionAsync(PackageId packageId,
}

private async Task<(PackageSource, IPackageSearchMetadata)> GetPackageMetadataAsync(string packageIdentifier,
NuGetVersion packageVersion, IEnumerable<PackageSource> sources, CancellationToken cancellationToken)
NuGetVersion packageVersion, IEnumerable<PackageSource> sources, CancellationToken cancellationToken, bool includeUnlisted = false)
{
if (string.IsNullOrWhiteSpace(packageIdentifier))
{
Expand All @@ -555,7 +562,7 @@ public async Task<NuGetVersion> GetBestPackageVersionAsync(PackageId packageId,
CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
List<Task<(PackageSource source, IEnumerable<IPackageSearchMetadata> foundPackages)>> tasks = sources
.Select(source =>
GetPackageMetadataAsync(source, packageIdentifier, true, linkedCts.Token)).ToList();
GetPackageMetadataAsync(source, packageIdentifier, true, includeUnlisted, linkedCts.Token)).ToList();

bool TryGetPackageMetadata(
(PackageSource source, IEnumerable<IPackageSearchMetadata> foundPackages) sourceAndFoundPackages,
Expand Down Expand Up @@ -621,7 +628,7 @@ bool TryGetPackageMetadata(
}

private async Task<(PackageSource source, IEnumerable<IPackageSearchMetadata> foundPackages)>
GetPackageMetadataAsync(PackageSource source, string packageIdentifier, bool includePrerelease = false,
GetPackageMetadataAsync(PackageSource source, string packageIdentifier, bool includePrerelease = false, bool includeUnlisted = false,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrWhiteSpace(packageIdentifier))
Expand All @@ -643,7 +650,7 @@ bool TryGetPackageMetadata(
foundPackages = await resource.GetMetadataAsync(
packageIdentifier,
includePrerelease,
false,
includeUnlisted,
_cacheSettings,
_verboseLogger,
cancellationToken).ConfigureAwait(false);
Expand Down
13 changes: 10 additions & 3 deletions src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa
var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true);

var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds);

bool givenSpecificVersion = false;
if (versionRange.MinVersion != null && versionRange.MaxVersion != null && versionRange.MinVersion == versionRange.MaxVersion)
{
givenSpecificVersion = true;
}
NuGetVersion packageVersion = nugetPackageDownloader.GetBestPackageVersionAsync(packageId, versionRange, packageSourceLocation).GetAwaiter().GetResult();

rollbackDirectory = isGlobalTool ? toolDownloadDir.Value: Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString());
Expand All @@ -116,7 +122,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa

if (package == null)
{
DownloadAndExtractPackage(packageLocation, packageId, nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore, packageVersion, packageSourceLocation).GetAwaiter().GetResult();
DownloadAndExtractPackage(packageLocation, packageId, nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore, packageVersion, packageSourceLocation, includeUnlisted: givenSpecificVersion).GetAwaiter().GetResult();
}
else if(isGlobalTool)
{
Expand Down Expand Up @@ -236,10 +242,11 @@ private static async Task<NuGetVersion> DownloadAndExtractPackage(
string packagesRootPath,
IToolPackageStore toolPackageStore,
NuGetVersion packageVersion,
PackageSourceLocation packageSourceLocation
PackageSourceLocation packageSourceLocation,
bool includeUnlisted = false
)
{
var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation).ConfigureAwait(false);
var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation, includeUnlisted: includeUnlisted).ConfigureAwait(false);

// look for package on disk and read the version
NuGetVersion version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public FailingNuGetPackageDownloader(string testDir)
public Task<string> DownloadPackageAsync(PackageId packageId, NuGetVersion packageVersion,
PackageSourceLocation packageSourceLocation = null,
bool includePreview = false,
bool includeUnlisted = false,
DirectoryPath? downloadFolder = null,
PackageSourceMapping packageSourceMapping = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public Task<string> DownloadPackageAsync(PackageId packageId,
NuGetVersion packageVersion = null,
PackageSourceLocation packageSourceLocation = null,
bool includePreview = false,
bool includeUnlisted = false,
DirectoryPath? downloadFolder = null,
PackageSourceMapping packageSourceMapping = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

namespace Microsoft.DotNet.Tests.Commands.Tool
{
public class ToolInstallGlobalOrToolPathCommandTests
public class ToolInstallGlobalOrToolPathCommandTests: SdkTest
{
private readonly IFileSystem _fileSystem;
private readonly IToolPackageStore _toolPackageStore;
Expand All @@ -35,8 +35,9 @@ public class ToolInstallGlobalOrToolPathCommandTests
private const string PackageId = "global.tool.console.demo";
private const string PackageVersion = "1.0.4";
private const string ToolCommandName = "SimulatorCommand";
private readonly string UnlistedPackageId = "elemental.sysinfotool";

public ToolInstallGlobalOrToolPathCommandTests()
public ToolInstallGlobalOrToolPathCommandTests(ITestOutputHelper log): base(log)
{
_reporter = new BufferedReporter();
_fileSystem = new FileSystemMockBuilder().UseCurrentSystemTemporaryDirectory().Build();
Expand Down Expand Up @@ -351,6 +352,36 @@ public void WhenRunWithValidVersionRangeItShouldSucceed()
PackageVersion).Green());
}

[Fact]
public void WhenRunWithValidUnlistedVersionRangeItShouldSucceed()
JL03-Yue marked this conversation as resolved.
Show resolved Hide resolved
{
const string nugetSourcePath = "https://api.nuget.org/v3/index.json";
var testDir = _testAssetsManager.CreateTestDirectory().Path;

var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--version", "[0.5.0]", "--add-source", nugetSourcePath)
.WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true")
.WithWorkingDirectory(testDir);

toolInstallGlobalOrToolPathCommand.Execute().Should().Pass();

// Uninstall the unlisted package
var toolUninstallCommand = new DotnetCommand(Log, "tool", "uninstall", "-g", UnlistedPackageId);
toolUninstallCommand.Execute().Should().Pass();
}

[Fact]
public void WhenRunWithoutValidVersionUnlistedToolItShouldThrow()
{
const string nugetSourcePath = "https://api.nuget.org/v3/index.json";
var testDir = _testAssetsManager.CreateTestDirectory().Path;

var toolInstallGlobalOrToolPathCommand = new DotnetCommand(Log, "tool", "install", "-g", UnlistedPackageId, "--add-source", nugetSourcePath)
.WithEnvironmentVariable("DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK", "true")
.WithWorkingDirectory(testDir);

toolInstallGlobalOrToolPathCommand.Execute().Should().Fail();
}

[Fact]
public void WhenRunWithPrereleaseItShouldSucceed()
{
Expand Down
Loading