| File: Commands\Workload\WorkloadManifestCorruptionRepairer.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 System.Diagnostics.CodeAnalysis; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Commands.Workload.Install; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.NET.Sdk.WorkloadManifestReader; namespace Microsoft.DotNet.Cli.Commands.Workload; internal sealed class WorkloadManifestCorruptionRepairer : IWorkloadManifestCorruptionRepairer { private readonly IReporter _reporter; private readonly IInstaller _workloadInstaller; private readonly IWorkloadResolver _workloadResolver; private readonly SdkFeatureBand _sdkFeatureBand; private readonly string _dotnetPath; private readonly string _userProfileDir; private readonly INuGetPackageDownloader? _packageDownloader; private readonly PackageSourceLocation? _packageSourceLocation; private readonly VerbosityOptions _verbosity; private bool _checked; public WorkloadManifestCorruptionRepairer( IReporter reporter, IInstaller workloadInstaller, IWorkloadResolver workloadResolver, SdkFeatureBand sdkFeatureBand, string dotnetPath, string userProfileDir, INuGetPackageDownloader? packageDownloader, PackageSourceLocation? packageSourceLocation, VerbosityOptions verbosity) { _reporter = reporter ?? NullReporter.Instance; _workloadInstaller = workloadInstaller; _workloadResolver = workloadResolver; _sdkFeatureBand = sdkFeatureBand; _dotnetPath = dotnetPath; _userProfileDir = userProfileDir; _packageDownloader = packageDownloader; _packageSourceLocation = packageSourceLocation; _verbosity = verbosity; } public void EnsureManifestsHealthy(ManifestCorruptionFailureMode failureMode) { if (_checked) { return; } _checked = true; if (failureMode == ManifestCorruptionFailureMode.Ignore) { return; } // Get the workload set directly from the provider - it was already resolved during construction // and doesn't require reading the install state file again var provider = _workloadResolver.GetWorkloadManifestProvider() as SdkDirectoryWorkloadManifestProvider; var workloadSet = provider?.ResolvedWorkloadSet; if (workloadSet is null) { // No workload set is being used return; } if (!provider?.HasMissingManifests(workloadSet) ?? true) { return; } if (failureMode == ManifestCorruptionFailureMode.Throw) { throw new InvalidOperationException(string.Format(CliCommandStrings.WorkloadSetHasMissingManifests, workloadSet.Version)); } _reporter.WriteLine($"Repairing workload set {workloadSet.Version}..."); CliTransaction.RunNew(context => RepairCorruptWorkloadSet(context, workloadSet)); } private void RepairCorruptWorkloadSet(ITransactionContext context, WorkloadSet workloadSet) { var manifestUpdates = CreateManifestUpdatesFromWorkloadSet(workloadSet); foreach (var manifestUpdate in manifestUpdates) { _workloadInstaller.InstallWorkloadManifest(manifestUpdate, context); } } [MemberNotNull(nameof(_packageDownloader))] private IEnumerable<ManifestVersionUpdate> CreateManifestUpdatesFromWorkloadSet(WorkloadSet workloadSet) { if (_packageDownloader is null) { throw new InvalidOperationException("Package downloader is required to repair workload manifests."); } var manifestUpdater = new WorkloadManifestUpdater( _reporter, _workloadResolver, _packageDownloader, _userProfileDir, _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, displayManifestUpdates: _verbosity >= VerbosityOptions.detailed); return manifestUpdater.CalculateManifestUpdatesForWorkloadSet(workloadSet); } }