| File: NuGetSourceConfiguration.cs | Web Access |
| Project: Microsoft.DotNet.Cli.Utils.csproj (Microsoft.DotNet.Cli.Utils) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.InteropServices; using NuGet.Configuration; namespace Microsoft.DotNet.Cli.Utils; public sealed class NuGetSourceConfiguration { private NuGetSourceConfiguration(ISettings settings, IReadOnlyList<PackageSource> packageSources) { Settings = settings; PackageSources = packageSources; } public ISettings Settings { get; } public IReadOnlyList<PackageSource> PackageSources { get; } public static NuGetSourceConfiguration Load( string? nugetConfig = null, string? rootConfigDirectory = null, IEnumerable<string>? sourceFeedOverrides = null, IEnumerable<string>? additionalSourceFeeds = null, string? basePath = null, Action<string>? invalidSource = null) { basePath ??= Directory.GetCurrentDirectory(); ISettings settings; if (!string.IsNullOrWhiteSpace(nugetConfig)) { string configPath = GetFullPath(nugetConfig, basePath); settings = NuGet.Configuration.Settings.LoadSpecificSettings( Path.GetDirectoryName(configPath)!, Path.GetFileName(configPath)); } else { settings = NuGet.Configuration.Settings.LoadDefaultSettings(rootConfigDirectory ?? basePath); } List<PackageSource> configuredSources = [.. new PackageSourceProvider(settings).LoadPackageSources()]; List<PackageSource> sources = sourceFeedOverrides?.Any() == true ? CreatePackageSources(sourceFeedOverrides, configuredSources, basePath, invalidSource) : [.. configuredSources.Where(source => source.IsEnabled)]; AddPackageSources(sources, additionalSourceFeeds, configuredSources, basePath, invalidSource); ValidateSources(sources); return new NuGetSourceConfiguration(settings, sources); } private static List<PackageSource> CreatePackageSources( IEnumerable<string> sourceFeeds, IReadOnlyList<PackageSource> configuredSources, string basePath, Action<string>? invalidSource) { List<PackageSource> sources = []; AddPackageSources(sources, sourceFeeds, configuredSources, basePath, invalidSource); return sources; } private static void AddPackageSources( List<PackageSource> sources, IEnumerable<string>? sourceFeeds, IReadOnlyList<PackageSource> configuredSources, string basePath, Action<string>? invalidSource) { if (sourceFeeds is null) { return; } foreach (string sourceFeed in sourceFeeds) { if (string.IsNullOrWhiteSpace(sourceFeed)) { continue; } string source = NormalizeSource(sourceFeed, basePath); PackageSource packageSource = ResolveSource(configuredSources, sourceFeed, source); if (packageSource.TrySourceAsUri is null) { invalidSource?.Invoke(sourceFeed); continue; } if (!sources.Any(existingSource => SourcesEqual(existingSource, packageSource))) { sources.Add(packageSource); } } } private static PackageSource ResolveSource( IReadOnlyList<PackageSource> configuredSources, string sourceFeed, string normalizedSource) => configuredSources.FirstOrDefault(source => source.Name.Equals(sourceFeed, StringComparison.OrdinalIgnoreCase) || SourcesEqual(source, new PackageSource(normalizedSource))) ?? new PackageSource(normalizedSource); private static bool SourcesEqual(PackageSource first, PackageSource second) { Uri? firstUri = first.TrySourceAsUri; Uri? secondUri = second.TrySourceAsUri; if (firstUri is not null && secondUri is not null) { if (firstUri.IsFile && secondUri.IsFile) { return GetPathComparer().Equals(firstUri.LocalPath, secondUri.LocalPath); } return firstUri.Equals(secondUri); } return GetPathComparer().Equals(first.Source, second.Source); } private static StringComparer GetPathComparer() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; private static void ValidateSources(IEnumerable<PackageSource> sources) { foreach (PackageSource source in sources) { if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections) { throw new GracefulException(string.Format( LocalizableStrings.Error_NU1302_HttpSourceUsed, source.Source)); } } } private static string NormalizeSource(string source, string basePath) { if (!Uri.IsWellFormedUriString(source, UriKind.Absolute) && !Path.IsPathRooted(source)) { return GetFullPath(source, basePath); } return source; } private static string GetFullPath(string path, string basePath) => Path.GetFullPath(Path.IsPathRooted(path) ? path : Path.Combine(basePath, path)); }