| File: Commands\Workload\Install\WorkloadManifestUpdater.Managed.cs | Web Access |
| Project: src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.DotNet.Cli.Commands.Workload.Install.WorkloadInstallRecords; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils.Extensions; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Versioning; namespace Microsoft.DotNet.Cli.Commands.Workload.Install; internal partial class WorkloadManifestUpdater : IWorkloadManifestUpdater { private readonly IReporter _reporter; private readonly IWorkloadResolver _workloadResolver; private readonly INuGetPackageDownloader _nugetPackageDownloader; private readonly SdkFeatureBand _sdkFeatureBand; private readonly PackageSourceLocation? _packageSourceLocation; private readonly IWorkloadManifestInstaller _workloadManifestInstaller; private readonly WorkloadAdvertisingManifestUpdater _advertisingUpdater; public WorkloadManifestUpdater( IReporter reporter, IWorkloadResolver workloadResolver, INuGetPackageDownloader nugetPackageDownloader, string userProfileDir, IWorkloadInstallationRecordRepository workloadRecordRepo, IWorkloadManifestInstaller workloadManifestInstaller, PackageSourceLocation? packageSourceLocation = null, Func<string, string?>? getEnvironmentVariable = null, bool displayManifestUpdates = true, SdkFeatureBand? sdkFeatureBand = null) { _reporter = reporter; _workloadResolver = workloadResolver; _nugetPackageDownloader = nugetPackageDownloader; _sdkFeatureBand = sdkFeatureBand ?? new SdkFeatureBand(_workloadResolver.GetSdkFeatureBand()); _packageSourceLocation = packageSourceLocation; _workloadManifestInstaller = workloadManifestInstaller; _advertisingUpdater = new WorkloadAdvertisingManifestUpdater( reporter, workloadResolver, nugetPackageDownloader, userProfileDir, workloadRecordRepo, workloadManifestInstaller, packageSourceLocation, getEnvironmentVariable, displayManifestUpdates, _sdkFeatureBand); } public Task UpdateAdvertisingManifestsAsync( bool includePreviews, bool useWorkloadSets = false, DirectoryPath? offlineCache = null) => _advertisingUpdater.UpdateAdvertisingManifestsAsync(includePreviews, useWorkloadSets, offlineCache); public Task BackgroundUpdateAdvertisingManifestsWhenRequiredAsync() => _advertisingUpdater.BackgroundUpdateAdvertisingManifestsWhenRequiredAsync(); public void DeleteUpdatableWorkloadsFile() => _advertisingUpdater.DeleteUpdatableWorkloadsFile(); public string? GetAdvertisedWorkloadSetVersion() => _advertisingUpdater.GetAdvertisedWorkloadSetVersion(); public IEnumerable<ManifestUpdateWithWorkloads> CalculateManifestUpdates() => _advertisingUpdater.CalculateManifestUpdates(); public IEnumerable<WorkloadId> GetUpdatableWorkloadsToAdvertise(IEnumerable<WorkloadId> installedWorkloads) => _advertisingUpdater.GetUpdatableWorkloadsToAdvertise(installedWorkloads); public IEnumerable<ManifestVersionUpdate> CalculateManifestRollbacks( string rollbackDefinitionFilePath, WorkloadHistoryRecorder? recorder = null) { var currentManifestIds = GetInstalledManifestIds(); var manifestRollbacks = ParseRollbackDefinitionFile(rollbackDefinitionFilePath, _sdkFeatureBand); if (recorder is not null) { recorder.HistoryRecord.RollbackFileContents = manifestRollbacks.ToDictionary( kvp => kvp.Id.ToString(), kvp => kvp.ManifestWithBand.Version + "/" + kvp.ManifestWithBand.Band); } var unrecognizedManifestIds = manifestRollbacks.Where(rollbackManifest => !currentManifestIds.Contains(rollbackManifest.Id)); if (unrecognizedManifestIds.Any()) { _reporter.WriteLine(string.Format( CliCommandStrings.RollbackDefinitionContainsExtraneousManifestIds, rollbackDefinitionFilePath, string.Join(" ", unrecognizedManifestIds)).Yellow()); manifestRollbacks = manifestRollbacks.Where(rollbackManifest => currentManifestIds.Contains(rollbackManifest.Id)); } return CalculateManifestRollbacks(manifestRollbacks); } private static IEnumerable<ManifestVersionUpdate> CalculateManifestRollbacks( IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> versionUpdates) { return versionUpdates.Select(manifest => { var (id, (version, band)) = manifest; return new ManifestVersionUpdate(id, version, band.ToString()); }); } public async Task<IEnumerable<WorkloadDownload>> GetManifestPackageDownloadsAsync( bool includePreviews, SdkFeatureBand providedSdkFeatureBand, SdkFeatureBand installedSdkFeatureBand) { var downloads = new List<WorkloadDownload>(); foreach (var manifest in _workloadResolver.GetInstalledManifests()) { try { PackageId? providedPackageId = null; var fallbackFeatureBand = new SdkFeatureBand(manifest.ManifestFeatureBand); SdkFeatureBand[] bands = [providedSdkFeatureBand, installedSdkFeatureBand, fallbackFeatureBand]; var success = false; foreach (var band in bands.Distinct()) { var packageId = _workloadManifestInstaller.GetManifestPackageId(new ManifestId(manifest.Id), band); providedPackageId ??= packageId; try { var latestVersion = await _nugetPackageDownloader.GetLatestPackageVersion( packageId, _packageSourceLocation, includePreviews); success = true; downloads.Add(new WorkloadDownload(manifest.Id, packageId.ToString(), latestVersion.ToString())); break; } catch (NuGetPackageNotFoundException) { } } if (!success) { _reporter.WriteLine(CliCommandStrings.ManifestPackageUrlNotResolved, providedPackageId); } } catch { _reporter.WriteLine(CliCommandStrings.ManifestPackageUrlNotResolved, manifest.Id); } } return downloads; } private IEnumerable<ManifestId> GetInstalledManifestIds() => _workloadResolver.GetInstalledManifests().Select(manifest => new ManifestId(manifest.Id)); public IEnumerable<ManifestVersionUpdate> CalculateManifestUpdatesFromHistory(WorkloadHistoryState state) { return state.ManifestVersions.Select( m => new ManifestVersionUpdate( new ManifestId(m.Key), new ManifestVersion(m.Value.Split('/')[0]), m.Value.Split('/')[1])); } public IEnumerable<ManifestVersionUpdate> CalculateManifestUpdatesForWorkloadSet(WorkloadSet workloadSet) { return CalculateManifestRollbacks( workloadSet.ManifestVersions.Select( kvp => (kvp.Key, new ManifestVersionWithBand(kvp.Value.Version, kvp.Value.FeatureBand)))); } private static IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> ParseRollbackDefinitionFile( string rollbackDefinitionFilePath, SdkFeatureBand featureBand) { string fileContent; if (Uri.TryCreate(rollbackDefinitionFilePath, UriKind.Absolute, out var rollbackUri) && !rollbackUri.IsFile) { using HttpClient httpClient = new(); fileContent = httpClient.GetStringAsync(rollbackDefinitionFilePath).Result; } else if (File.Exists(rollbackDefinitionFilePath)) { fileContent = File.ReadAllText(rollbackDefinitionFilePath); } else { throw new ArgumentException(string.Format( CliCommandStrings.RollbackDefinitionFileDoesNotExist, rollbackDefinitionFilePath)); } var versions = WorkloadSet.FromJson(fileContent, featureBand).ManifestVersions; return versions.Select(kvp => (kvp.Key, new ManifestVersionWithBand(kvp.Value.Version, kvp.Value.FeatureBand))); } }