Skip to content
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
@@ -1,6 +1,8 @@
// 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.

#nullable enable

using System;
using System.Collections.Generic;
using System.Globalization;
Expand Down Expand Up @@ -48,28 +50,62 @@ public static async Task<int> RunAsync(PackageDownloadArgs args, CancellationTok

public static async Task<int> RunAsync(PackageDownloadArgs args, ILoggerWithColor logger, IReadOnlyList<PackageSource> packageSources, ISettings settings, CancellationToken token)
{
// Check for insecure sources
if (DetectAndReportInsecureSources(args.AllowInsecureConnections, packageSources, logger))
bool hasSourcesArg = args.Sources?.Count > 0;
PackageSourceMapping? packageSourceMapping = null;
if (!hasSourcesArg)
{
packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(settings);
}

bool ignorePackageSourceMapping =
hasSourcesArg
|| packageSourceMapping is null
|| !packageSourceMapping.IsEnabled;

// When package source mapping is disabled, validate all configured sources upfront.
// When mapping is enabled, source validation is deferred to the per-package resolution step,
// since each package may map to a different subset of sources.
if (ignorePackageSourceMapping && DetectAndReportInsecureSources(args.AllowInsecureConnections, packageSources, logger))
{
return ExitCodeError;
}

string outputDirectory = args.OutputDirectory ?? Directory.GetCurrentDirectory();
var cache = new SourceCacheContext();
IReadOnlyList<SourceRepository> sourceRepositories = GetSourceRepositories(packageSources);
IReadOnlyList<SourceRepository> allRepositories = GetSourceRepositories(packageSources);
bool downloadedAllSuccessfully = true;

foreach (var package in args.Packages)
foreach (var package in args.Packages ?? [])
{
logger.LogMinimal(string.Format(
CultureInfo.CurrentCulture,
Strings.PackageDownloadCommand_Starting,
package.Id,
string.IsNullOrEmpty(package.NuGetVersion?.ToNormalizedString()) ? Strings.PackageDownloadCommand_LatestVersion : package.NuGetVersion.ToNormalizedString()));

// Resolve which repositories to use for this package
IReadOnlyList<SourceRepository> sourceRepositories;
if (ignorePackageSourceMapping)
{
sourceRepositories = allRepositories;
}
else
{
if (!TryGetRepositoriesForPackage(
package.Id,
args,
packageSourceMapping!,
allRepositories,
logger,
out sourceRepositories))
{
return ExitCodeError;
}
}

try
{
(NuGetVersion version, SourceRepository downloadRepository) =
(NuGetVersion? version, SourceRepository? downloadRepository) =
await ResolvePackageDownloadVersion(
package,
sourceRepositories,
Expand All @@ -88,7 +124,7 @@ await ResolvePackageDownloadVersion(
bool success = await DownloadPackageAsync(
package.Id,
version,
downloadRepository,
downloadRepository!,
cache,
settings,
outputDirectory,
Expand Down Expand Up @@ -127,16 +163,16 @@ await ResolvePackageDownloadVersion(
return downloadedAllSuccessfully ? ExitCodeSuccess : ExitCodeError;
}

internal static async Task<(NuGetVersion, SourceRepository)> ResolvePackageDownloadVersion(
internal static async Task<(NuGetVersion?, SourceRepository?)> ResolvePackageDownloadVersion(
PackageWithNuGetVersion packageWithNuGetVersion,
IEnumerable<SourceRepository> sourceRepositories,
IReadOnlyList<SourceRepository> sourceRepositories,
SourceCacheContext cache,
ILoggerWithColor logger,
bool includePrerelease,
CancellationToken token)
{
NuGetVersion versionToDownload = null;
SourceRepository downloadSourceRepository = null;
NuGetVersion? versionToDownload = null;
SourceRepository? downloadSourceRepository = null;
bool versionSpecified = packageWithNuGetVersion.NuGetVersion != null;

foreach (var repo in sourceRepositories)
Expand Down Expand Up @@ -188,6 +224,69 @@ await ResolvePackageDownloadVersion(
return (versionToDownload, downloadSourceRepository);
}

/// <summary>
/// Builds the set of SourceRepository objects to use for a given package,
/// applying package source mapping
/// validating HTTP usage only on the *effective* sources.
/// </summary>
private static bool TryGetRepositoriesForPackage(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm finding this method really hard to read/maintain. There's too many nested control statements and three different code paths for a return statement. One suggestion would be to factor the foreach statement out into its own helper function. Ideally, there should be a single return statement.

string packageId,
PackageDownloadArgs args,
PackageSourceMapping packageSourceMapping,
IReadOnlyList<SourceRepository> allRepos,
ILoggerWithColor logger,
out IReadOnlyList<SourceRepository> repositories)
{
var mappedNames = packageSourceMapping.GetConfiguredPackageSources(packageId);

// Only validate insecure sources when mapping produced something
if (mappedNames.Count > 0)
{
var mappedRepos = new List<SourceRepository>(mappedNames.Count);
foreach (var mappedName in mappedNames)
{
SourceRepository? repo = null;
for (int i = 0; i < allRepos.Count; i++)
{
if (string.Equals(allRepos[i].PackageSource.Name, mappedName, StringComparison.OrdinalIgnoreCase))
{
repo = allRepos[i];
break;
}
}

if (repo != null)
{
mappedRepos.Add(repo);
}
else
{
logger.LogVerbose(
string.Format(
CultureInfo.CurrentCulture,
Strings.PackageDownloadCommand_PackageSourceMapping_NoSuchSource,
mappedName,
packageId));
}
}

if (DetectAndReportInsecureSources(args.AllowInsecureConnections, mappedRepos.Select(repo => repo.PackageSource), logger))
{
repositories = [];
return false;
}

repositories = mappedRepos;
return true;
}
else
{
// No mapping for this package: fall back to all sources
repositories = allRepos;
return true;
}
}

private static async Task<bool> DownloadPackageAsync(
string id,
NuGetVersion version,
Expand Down Expand Up @@ -239,7 +338,7 @@ private static async Task<bool> DownloadPackageAsync(
return success;
}

private static IReadOnlyList<PackageSource> GetPackageSources(IList<string> sources, IPackageSourceProvider sourceProvider)
private static IReadOnlyList<PackageSource> GetPackageSources(IList<string>? sources, IPackageSourceProvider sourceProvider)
{
IEnumerable<PackageSource> configuredSources = sourceProvider.LoadPackageSources()
.Where(s => s.IsEnabled);
Expand Down
9 changes: 9 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1157,4 +1157,9 @@ Do not translate "PackageVersion"</comment>
<data name="Error_PackageDownload_VersionNotFound" xml:space="preserve">
<value>Unable to find a valid package version</value>
</data>
<data name="PackageDownloadCommand_PackageSourceMapping_NoSuchSource" xml:space="preserve">
<value>The mapped source '{0}' for package '{1}' was not found among the configured sources.</value>
<comment>0 - package source name
1 - package name</comment>
</data>
</root>
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Další informace najdete tady: https://docs.nuget.org/docs/reference/command-li
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Weitere Informationen finden Sie unter: https://docs.nuget.org/docs/reference/co
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Para obtener más información, visite https://docs.nuget.org/docs/reference/com
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Pour plus d'informations, visitez https://docs.nuget.org/docs/reference/command-
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Per altre informazioni, vedere https://docs.nuget.org/docs/reference/command-lin
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ For more information, visit https://docs.nuget.org/docs/reference/command-line-r
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ For more information, visit https://docs.nuget.org/docs/reference/command-line-r
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Aby uzyskać więcej informacji, odwiedź stronę https://docs.nuget.org/docs/re
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ Para obter mais informações, acesse https://docs.nuget.org/docs/reference/comm
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ For more information, visit https://docs.nuget.org/docs/reference/command-line-r
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
6 changes: 6 additions & 0 deletions src/NuGet.Core/NuGet.CommandLine.XPlat/xlf/Strings.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,12 @@ Daha fazla bilgi için bkz. https://docs.nuget.org/docs/reference/command-line-r
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@ For more information, visit https://docs.nuget.org/docs/reference/command-line-r
<target state="new">Package identifier (e.g. 'Newtonsoft.Json').</target>
<note />
</trans-unit>
<trans-unit id="PackageDownloadCommand_PackageSourceMapping_NoSuchSource">
<source>The mapped source '{0}' for package '{1}' was not found among the configured sources.</source>
<target state="new">The mapped source '{0}' for package '{1}' was not found among the configured sources.</target>
<note>0 - package source name
1 - package name</note>
</trans-unit>
<trans-unit id="PackageDownloadCommand_SourcesDescription">
<source>Specifies one or more NuGet package sources to use.</source>
<target state="new">Specifies one or more NuGet package sources to use.</target>
Expand Down
Loading