From bb9cbadf7bd0cbf7a6d8c69cab784ef1a0629496 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 19 Jun 2023 15:28:05 -0400 Subject: [PATCH 1/5] Pass global.json path to workload manifest resolver This will allow the workload manifest resolver to read any workload version specified in global.json --- .../commands/InstallingWorkloadCommand.cs | 2 +- .../dotnet-workload/WorkloadInfoHelper.cs | 2 +- .../install/WorkloadManifestUpdater.cs | 2 +- .../install/WorkloadOptionsExtensions.cs | 2 +- .../repair/WorkloadRepairCommand.cs | 2 +- .../search/WorkloadSearchCommand.cs | 2 +- .../uninstall/WorkloadUninstallCommand.cs | 2 +- .../TemplateLocator.cs | 7 +++- .../MSBuildSdkResolver.cs | 7 +++- .../CachingWorkloadResolver.cs | 11 +++-- .../WorkloadSdkResolver.cs | 24 ++++++++++- .../SdkDirectoryWorkloadManifestProvider.cs | 20 +++++++-- .../ProcessFrameworkReferences.cs | 7 +++- .../ShowMissingWorkloads.cs | 7 +++- ...kDirectoryWorkloadManifestProviderTests.cs | 42 +++++++++---------- .../WorkloadPackGroupTests.cs | 2 +- 16 files changed, 101 insertions(+), 40 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index 52c7432fb321..3ba50f8930e1 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -77,7 +77,7 @@ public InstallingWorkloadCommand( _packageSourceLocation = string.IsNullOrEmpty(configOption) && (sourceOption == null || !sourceOption.Any()) ? null : new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), sourceFeedOverrides: sourceOption); - var sdkWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _installedSdkVersion.ToString(), userProfileDir); + var sdkWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _installedSdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); _workloadResolver = workloadResolver ?? WorkloadResolver.Create(sdkWorkloadManifestProvider, _dotnetPath, _installedSdkVersion.ToString(), _userProfileDir); _workloadInstallerFromConstructor = workloadInstaller; diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs index 365eea9074b2..04de0e417444 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs @@ -43,7 +43,7 @@ public WorkloadInfoHelper( string.IsNullOrWhiteSpace(_targetSdkVersion) ? currentSdkReleaseVersion.ToString() : _targetSdkVersion, - userProfileDir); + userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); WorkloadResolver = workloadResolver ?? NET.Sdk.WorkloadManifestReader.WorkloadResolver.Create( workloadManifestProvider, dotnetPath, currentSdkReleaseVersion.ToString(), userProfileDir); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 1ad6e01713cf..80ed706dcbdc 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -66,7 +66,7 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) var reporter = new NullReporter(); var dotnetPath = Path.GetDirectoryName(Environment.ProcessPath); var sdkVersion = Product.Version; - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir); + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, sdkVersion, userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetPath, sdkVersion, userProfileDir); var tempPackagesDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); var nugetPackageDownloader = new NuGetPackageDownloader(tempPackagesDir, diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs index cae4c9567933..22cb585cffe5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs @@ -26,7 +26,7 @@ internal static ReleaseVersion GetValidatedSdkVersion(string versionOption, stri } else { - var manifests = new SdkDirectoryWorkloadManifestProvider(dotnetPath, versionOption, userProfileDir).GetManifests(); + var manifests = new SdkDirectoryWorkloadManifestProvider(dotnetPath, versionOption, userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)).GetManifests(); if (!manifests.Any() && checkIfFeatureBandManifestsExist) { throw new GracefulException(string.Format(LocalizableStrings.NoManifestsExistForFeatureBand, new SdkFeatureBand(versionOption).ToString()), isUserError: false); diff --git a/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs index 1aba15b3dfec..2b376dacc0e1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs @@ -49,7 +49,7 @@ public WorkloadRepairCommand( _packageSourceLocation = string.IsNullOrEmpty(configOption) && (sourceOption == null || !sourceOption.Any()) ? null : new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), sourceFeedOverrides: sourceOption); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _sdkVersion.ToString(), userProfileDir); + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _sdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); _workloadResolver = workloadResolver ?? WorkloadResolver.Create(workloadManifestProvider, _dotnetPath, _sdkVersion.ToString(), userProfileDir); var sdkFeatureBand = new SdkFeatureBand(_sdkVersion); diff --git a/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs index 88fac779d565..2b1aad6cb170 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs @@ -33,7 +33,7 @@ public WorkloadSearchCommand( var dotnetPath = Path.GetDirectoryName(Environment.ProcessPath); userProfileDir ??= CliFolderPathCalculator.DotnetUserProfileFolderPath; _sdkVersion = WorkloadOptionsExtensions.GetValidatedSdkVersion(result.GetValueForOption(WorkloadSearchCommandParser.VersionOption), version, dotnetPath, userProfileDir, true); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString(), userProfileDir); + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); _workloadResolver = workloadResolver ?? WorkloadResolver.Create(workloadManifestProvider, dotnetPath, _sdkVersion.ToString(), userProfileDir); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs index 6bb77c3baa54..fca9467b1536 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs @@ -43,7 +43,7 @@ public WorkloadUninstallCommand( userProfileDir = userProfileDir ?? CliFolderPathCalculator.DotnetUserProfileFolderPath; _sdkVersion = WorkloadOptionsExtensions.GetValidatedSdkVersion(parseResult.GetValueForOption(WorkloadUninstallCommandParser.VersionOption), version, dotnetPath, userProfileDir, true); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString(), userProfileDir); + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); workloadResolver ??= WorkloadResolver.Create(workloadManifestProvider, dotnetPath, _sdkVersion.ToString(), userProfileDir); var sdkFeatureBand = new SdkFeatureBand(_sdkVersion); diff --git a/src/Microsoft.DotNet.TemplateLocator/TemplateLocator.cs b/src/Microsoft.DotNet.TemplateLocator/TemplateLocator.cs index b0a32fa649db..0fef63355810 100644 --- a/src/Microsoft.DotNet.TemplateLocator/TemplateLocator.cs +++ b/src/Microsoft.DotNet.TemplateLocator/TemplateLocator.cs @@ -54,7 +54,12 @@ public IReadOnlyCollection GetDotnetSdkTemplate nameof(dotnetRootPath)); } - _workloadManifestProvider ??= new SdkDirectoryWorkloadManifestProvider(dotnetRootPath, sdkVersion, userProfileDir); + // Will the current directory correspond to the folder we are creating a project in? If we need + // to honor global.json workload version selection for template creation in Visual Studio, we may + // need to update this interface to pass a folder where we should start the search for global.json + string? globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); + + _workloadManifestProvider ??= new SdkDirectoryWorkloadManifestProvider(dotnetRootPath, sdkVersion, userProfileDir, globalJsonPath); _workloadResolver ??= WorkloadResolver.Create(_workloadManifestProvider, dotnetRootPath, sdkVersion, userProfileDir); return _workloadResolver.GetInstalledWorkloadPacksOfKind(WorkloadPackKind.Template) diff --git a/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs b/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs index 85fe4093d5f5..7137e5e763c3 100644 --- a/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs +++ b/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/MSBuildSdkResolver.cs @@ -62,6 +62,7 @@ private sealed class CachedState public string DotnetRoot; public string MSBuildSdksDir; public string NETCoreSdkVersion; + public string GlobalJsonPath; public IDictionary PropertiesToAdd; public CachingWorkloadResolver WorkloadResolver; } @@ -71,6 +72,7 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext string dotnetRoot = null; string msbuildSdksDir = null; string netcoreSdkVersion = null; + string globalJsonPath = null; IDictionary propertiesToAdd = null; IDictionary itemsToAdd = null; List warnings = null; @@ -91,6 +93,7 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext dotnetRoot = priorResult.DotnetRoot; msbuildSdksDir = priorResult.MSBuildSdksDir; netcoreSdkVersion = priorResult.NETCoreSdkVersion; + globalJsonPath = priorResult.GlobalJsonPath; propertiesToAdd = priorResult.PropertiesToAdd; workloadResolver = priorResult.WorkloadResolver; @@ -136,6 +139,7 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext msbuildSdksDir = Path.Combine(resolverResult.ResolvedSdkDirectory, "Sdks"); netcoreSdkVersion = new DirectoryInfo(resolverResult.ResolvedSdkDirectory).Name; + globalJsonPath = resolverResult.GlobalJsonPath; // These are overrides that are used to force the resolved SDK tasks and targets to come from a given // base directory and report a given version to msbuild (which may be null if unknown. One key use case @@ -226,13 +230,14 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext DotnetRoot = dotnetRoot, MSBuildSdksDir = msbuildSdksDir, NETCoreSdkVersion = netcoreSdkVersion, + GlobalJsonPath = globalJsonPath, PropertiesToAdd = propertiesToAdd, WorkloadResolver = workloadResolver }; // First check if requested SDK resolves to a workload SDK pack string userProfileDir = CliFolderPathCalculatorCore.GetDotnetUserProfileFolderPath(); - var workloadResult = workloadResolver.Resolve(sdkReference.Name, dotnetRoot, netcoreSdkVersion, userProfileDir); + var workloadResult = workloadResolver.Resolve(sdkReference.Name, dotnetRoot, netcoreSdkVersion, userProfileDir, globalJsonPath); if (workloadResult is not CachingWorkloadResolver.NullResolutionResult) { diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/CachingWorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/CachingWorkloadResolver.cs index 7192615b7c15..b25b9eb76a5b 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/CachingWorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/CachingWorkloadResolver.cs @@ -37,12 +37,15 @@ namespace Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver // For SDK or workload installation actions, we expect to be running under a new process since Visual Studio will have been restarted. // For global.json changes, the Resolve method takes parameters for the dotnet root and the SDK version. If those values have changed // from the previous call, the cached state will be thrown out and recreated. + // We don't currently handle the case where a global.json file is edited to change the workload version. It may be necessary + // to kill running MSBuild processes to get that change to take effect. class CachingWorkloadResolver { private sealed record CachedState { public string DotnetRootPath { get; init; } public string SdkVersion { get; init; } + public string GlobalJsonPath { get; init; } public IWorkloadManifestProvider ManifestProvider { get; init; } public IWorkloadResolver WorkloadResolver { get; init; } public ImmutableDictionary CachedResults { get; init; } @@ -173,7 +176,7 @@ private static ResolutionResult Resolve(string sdkReferenceName, IWorkloadManife return new NullResolutionResult(); } - public ResolutionResult Resolve(string sdkReferenceName, string dotnetRootPath, string sdkVersion, string userProfileDir) + public ResolutionResult Resolve(string sdkReferenceName, string dotnetRootPath, string sdkVersion, string userProfileDir, string globalJsonPath) { if (!_enabled) { @@ -186,15 +189,17 @@ public ResolutionResult Resolve(string sdkReferenceName, string dotnetRootPath, { if (_cachedState == null || _cachedState.DotnetRootPath != dotnetRootPath || - _cachedState.SdkVersion != sdkVersion) + _cachedState.SdkVersion != sdkVersion || + _cachedState.GlobalJsonPath != globalJsonPath) { - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetRootPath, sdkVersion, userProfileDir); + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetRootPath, sdkVersion, userProfileDir, globalJsonPath); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, dotnetRootPath, sdkVersion, userProfileDir); _cachedState = new CachedState() { DotnetRootPath = dotnetRootPath, SdkVersion = sdkVersion, + GlobalJsonPath = globalJsonPath, ManifestProvider = workloadManifestProvider, WorkloadResolver = workloadResolver }; diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/WorkloadSdkResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/WorkloadSdkResolver.cs index 51d241f156d6..a26818248bcd 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/WorkloadSdkResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadMSBuildSdkResolver/WorkloadSdkResolver.cs @@ -35,6 +35,8 @@ private class CachedState public string DotnetRootPath { get; init; } public string SdkVersion { get; init; } + public string GlobalJsonPath { get; init; } + public CachingWorkloadResolver WorkloadResolver { get; init; } } @@ -56,10 +58,13 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext // The SDK version is the name of the SDK directory (ie dotnet\sdk\5.0.100) var sdkVersion = Path.GetFileName(sdkDirectory); + var globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(GetGlobalJsonStartDir(resolverContext)); + cachedState = new CachedState() { DotnetRootPath = dotnetRootPath, SdkVersion = sdkVersion, + GlobalJsonPath = globalJsonPath, WorkloadResolver = new CachingWorkloadResolver() }; @@ -67,7 +72,7 @@ public override SdkResult Resolve(SdkReference sdkReference, SdkResolverContext } string userProfileDir = CliFolderPathCalculatorCore.GetDotnetUserProfileFolderPath(); - var result = cachedState.WorkloadResolver.Resolve(sdkReference.Name, cachedState.DotnetRootPath, cachedState.SdkVersion, userProfileDir); + var result = cachedState.WorkloadResolver.Resolve(sdkReference.Name, cachedState.DotnetRootPath, cachedState.SdkVersion, userProfileDir, cachedState.GlobalJsonPath); return result.ToSdkResult(sdkReference, factory); @@ -95,6 +100,23 @@ private string GetDotNetRoot(SdkResolverContext context) var dotnetRoot = Directory.GetParent(sdkDirectory).Parent.FullName; return dotnetRoot; } + + // Duplicated logic from DotNetMSBuildSdkResolver + private static string GetGlobalJsonStartDir(SdkResolverContext context) + { + string startDir = Environment.CurrentDirectory; + + if (!string.IsNullOrWhiteSpace(context.SolutionFilePath)) + { + startDir = Path.GetDirectoryName(context.SolutionFilePath); + } + else if (!string.IsNullOrWhiteSpace(context.ProjectFilePath)) + { + startDir = Path.GetDirectoryName(context.ProjectFilePath); + } + + return startDir; + } } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 5cbc7f06128f..9eebc01d1c65 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -26,10 +26,9 @@ public class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestProvider private readonly WorkloadSet? _workloadSet; - public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? requestedWorkloadSet = null) - : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, requestedWorkloadSet) + public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? globalJsonPath) + : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir) { - } internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func getEnvironmentVariable, string? userProfileDir, string? requestedWorkloadSet = null) @@ -344,5 +343,20 @@ public string GetSdkFeatureBand() { return _sdkVersionBand.ToString(); } + + public static string? GetGlobalJsonPath(string? globalJsonStartDir) + { + string? directory = globalJsonStartDir; + while (directory != null) + { + string globalJsonPath = Path.Combine(directory, "global.json"); + if (File.Exists(globalJsonPath)) + { + return globalJsonPath; + } + directory = Path.GetDirectoryName(directory); + } + return null; + } } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs index 9447c16cbd02..7121acd08607 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs @@ -757,7 +757,12 @@ private string GetResolvedPackVersion(string packID, string packVersion) if (_workloadManifestProvider == null) { string userProfileDir = CliFolderPathCalculatorCore.GetDotnetUserProfileFolderPath(); - _workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(NetCoreRoot, NETCoreSdkVersion, userProfileDir); + + // When running MSBuild tasks, the current directory is always the project directory, so we can use that as the + // starting point to search for global.json + string globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); + + _workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(NetCoreRoot, NETCoreSdkVersion, userProfileDir, globalJsonPath); _workloadResolver = WorkloadResolver.Create(_workloadManifestProvider, NetCoreRoot, NETCoreSdkVersion, userProfileDir); } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs index 1c0c13f83504..acd9928439ef 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs @@ -43,7 +43,12 @@ protected override void ExecuteCore() if (MissingWorkloadPacks.Any()) { string? userProfileDir = CliFolderPathCalculatorCore.GetDotnetUserProfileFolderPath(); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(NetCoreRoot, NETCoreSdkVersion, userProfileDir); + + // When running MSBuild tasks, the current directory is always the project directory, so we can use that as the + // starting point to search for global.json + string globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); + + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(NetCoreRoot, NETCoreSdkVersion, userProfileDir, globalJsonPath); var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, NetCoreRoot, NETCoreSdkVersion, userProfileDir); var suggestedWorkloads = workloadResolver.GetWorkloadSuggestionForMissingPacks( diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index 48f39bccc188..f7509eeed9f1 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -53,7 +53,7 @@ public void ItShouldReturnListOfManifestFiles() File.WriteAllText(Path.Combine(_manifestVersionBandDirectory, "iOS", "WorkloadManifest.json"), iosManifestFileContent); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -70,7 +70,7 @@ public void GivenSDKVersionItShouldReturnListOfManifestFilesForThisVersionBand() File.WriteAllText(Path.Combine(_manifestVersionBandDirectory, "Android", "WorkloadManifest.json"), androidManifestFileContent); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -83,7 +83,7 @@ public void GivenNoManifestDirectoryItShouldReturnEmpty() Initialize(); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); sdkDirectoryWorkloadManifestProvider.GetManifests().Should().BeEmpty(); } @@ -95,7 +95,7 @@ public void GivenNoManifestJsonFileInDirectoryItShouldIgnoreIt() Directory.CreateDirectory(Path.Combine(_manifestVersionBandDirectory, "Android")); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); sdkDirectoryWorkloadManifestProvider.GetManifests() .Should() @@ -114,7 +114,7 @@ public void ItReturnsLatestManifestVersion() CreateMockManifest(_manifestRoot, "5.0.100", "ios", "11.0.2-rc.1", true); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -134,7 +134,7 @@ public void ItPrefersManifestsInSubfolders() CreateMockManifest(_manifestRoot, "5.0.100", "ios", "12.0.1", false); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -159,7 +159,7 @@ public void ItFallsBackToLatestManifestVersion() CreateMockManifest(_manifestRoot, "7.0.400", "ios", "18.0.1", true); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -194,7 +194,7 @@ public void ItUsesManifestsFromWorkloadSet() """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -223,7 +223,7 @@ public void ItUsesLatestWorkloadSet() """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -256,7 +256,7 @@ public void ItUsesLatestManifestThatIsNotInWorkloadSet() """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -290,7 +290,7 @@ public void ItFallsBackForManifestNotInWorkloadSet() """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.201", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.201", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -312,7 +312,7 @@ public void ItThrowsIfWorkloadSetHasInvalidVersion() } """); - Assert.Throws(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null)); + Assert.Throws(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null)); } [Fact] @@ -330,7 +330,7 @@ public void ItThrowsIfManifestFromWorkloadSetIsNotFound() } """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null); Assert.Throws(() => GetManifestContents(sdkDirectoryWorkloadManifestProvider).ToList()); } @@ -363,7 +363,7 @@ public void WorkloadSetCanIncludeMultipleJsonFiles() """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -399,7 +399,7 @@ public void ItThrowsExceptionIfWorkloadSetJsonFilesHaveDuplicateManifests() """); Assert.Throws(() => - new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null)); + new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null)); } [Fact] @@ -539,7 +539,7 @@ public void ItShouldIgnoreOutdatedManifestIds() File.WriteAllText(Path.Combine(_manifestVersionBandDirectory, "Microsoft.NET.Workload.Android", "WorkloadManifest.json"), "iOSContent"); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "5.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -570,7 +570,7 @@ public void ItShouldFallbackWhenFeatureBandHasNoManifests() File.WriteAllText(knownWorkloadsFilePath, "Android\niOS"); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "6.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "6.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -601,7 +601,7 @@ public void ItShouldFallbackWhenPreviewFeatureBandHasNoManifests() File.WriteAllText(knownWorkloadsFilePath, "Android\niOS"); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: prev4Version, userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: prev4Version, userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -632,7 +632,7 @@ public void ItShouldRollForwardToNonPrereleaseWhenPreviewFeatureBandHasNoManifes File.WriteAllText(knownWorkloadsFilePath, "Android\niOS"); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: prev4Version, userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: prev4Version, userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -664,7 +664,7 @@ public void ItReturnsManifestsInOrderFromKnownWorkloadManifestsFile() Microsoft.Net.Workload.Emscripten.net7" .Trim()); - var sdkDirectoryWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: currentSdkVersion, userProfileDir: null); + var sdkDirectoryWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: currentSdkVersion, userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -718,7 +718,7 @@ public void ItShouldIgnoreManifestsNotFoundInFallback() File.WriteAllText(knownWorkloadsFilePath, "Android\niOS"); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: fakeDotnetRootDirectory, sdkVersion: "6.0.100", userProfileDir: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: fakeDotnetRootDirectory, sdkVersion: "6.0.100", userProfileDir: null, globalJsonPath: null); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/WorkloadPackGroupTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/WorkloadPackGroupTests.cs index 0c7869d92489..5f3cb5d9aba9 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/WorkloadPackGroupTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/WorkloadPackGroupTests.cs @@ -106,7 +106,7 @@ public void TestGetManifestFeatureBands() SdkDirectoryWorkloadManifestProvider CreateManifestProvider() { - return new(TestContext.Current.ToolsetUnderTest.DotNetRoot, TestContext.Current.ToolsetUnderTest.SdkVersion, userProfileDir: null); + return new(TestContext.Current.ToolsetUnderTest.DotNetRoot, TestContext.Current.ToolsetUnderTest.SdkVersion, userProfileDir: null, globalJsonPath: null); } public IEnumerable GetManifests(SdkDirectoryWorkloadManifestProvider? manifestProvider = null) From abc7f24dd3e15c6453a33a5c586e4cc4e33e15b1 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 20 Jun 2023 15:20:52 -0400 Subject: [PATCH 2/5] Read workload set version from global.json --- ...rkloadManifestProvider.GlobalJsonReader.cs | 181 ++++++++++++++++++ .../SdkDirectoryWorkloadManifestProvider.cs | 20 +- .../Strings.resx | 4 +- .../WorkloadManifestReader.NewtonsoftJson.cs | 2 +- .../WorkloadManifestReader.SystemTextJson.cs | 2 +- .../xlf/Strings.cs.xlf | 10 +- .../xlf/Strings.de.xlf | 10 +- .../xlf/Strings.es.xlf | 10 +- .../xlf/Strings.fr.xlf | 10 +- .../xlf/Strings.it.xlf | 10 +- .../xlf/Strings.ja.xlf | 10 +- .../xlf/Strings.ko.xlf | 10 +- .../xlf/Strings.pl.xlf | 10 +- .../xlf/Strings.pt-BR.xlf | 10 +- .../xlf/Strings.ru.xlf | 10 +- .../xlf/Strings.tr.xlf | 10 +- .../xlf/Strings.zh-Hans.xlf | 10 +- .../xlf/Strings.zh-Hant.xlf | 10 +- 18 files changed, 263 insertions(+), 76 deletions(-) create mode 100644 src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs new file mode 100644 index 000000000000..4d90e4f0c25c --- /dev/null +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs @@ -0,0 +1,181 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.NET.Sdk.Localization; +using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadManifestReader; +using System.Runtime.Serialization; + +#if USE_SYSTEM_TEXT_JSON +using System.Text.Json; +#else +using Newtonsoft.Json; +using JsonTokenType = Newtonsoft.Json.JsonToken; +#endif + +namespace Microsoft.NET.Sdk.WorkloadManifestReader +{ + public partial class SdkDirectoryWorkloadManifestProvider + { + static class GlobalJsonReader + { + public static string? GetWorkloadVersionFromGlobalJson(string globalJsonPath) + { + if (string.IsNullOrEmpty(globalJsonPath)) + { + return null; + } + + using var fileStream = File.OpenRead(globalJsonPath); + +#if USE_SYSTEM_TEXT_JSON + var readerOptions = new JsonReaderOptions + { + AllowTrailingCommas = true, + CommentHandling = JsonCommentHandling.Skip + }; + var reader = new Utf8JsonStreamReader(fileStream, readerOptions); +#else + using var textReader = new StreamReader(fileStream, System.Text.Encoding.UTF8, true); + using var jsonReader = new JsonTextReader(textReader); + + var reader = new Utf8JsonStreamReader(jsonReader); +#endif + + string? workloadVersion = null; + + ConsumeToken(ref reader, JsonTokenType.StartObject); + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonTokenType.PropertyName: + var propName = reader.GetString(); + if (string.Equals("sdk", propName, StringComparison.OrdinalIgnoreCase)) + { + ConsumeToken(ref reader, JsonTokenType.StartObject); + + bool readingSdk = true; + while (readingSdk && reader.Read()) + { + switch (reader.TokenType) + { + case JsonTokenType.PropertyName: + var sdkPropName = reader.GetString(); + if (string.Equals("workloadVersion", sdkPropName, StringComparison.OrdinalIgnoreCase)) + { + workloadVersion = ReadString(ref reader); + } + else + { + ConsumeValue(ref reader); + } + break; + case JsonTokenType.EndObject: + readingSdk = false; + break; + default: + throw new GlobalJsonFormatException(Strings.UnexpectedTokenAtOffset, reader.TokenType, reader.TokenStartIndex); + } + } + } + else + { + ConsumeValue(ref reader); + } + break; + + case JsonTokenType.EndObject: + return workloadVersion; + default: + throw new GlobalJsonFormatException(Strings.UnexpectedTokenAtOffset, reader.TokenType, reader.TokenStartIndex); + } + } + + throw new GlobalJsonFormatException(Strings.IncompleteDocument); + } + + + /// + /// this expects the reader to be before the value token, and leaves it on the last token of the value + /// + private static bool ConsumeValue(ref Utf8JsonStreamReader reader) + { + if (!reader.Read()) + { + return false; + } + + var tokenType = reader.TokenType; + if (tokenType != JsonTokenType.StartArray && tokenType != JsonTokenType.StartObject) + { + return true; + } + + var depth = reader.CurrentDepth; + do + { + if (!reader.Read()) + { + return false; + } + } while (reader.CurrentDepth > depth); + + return true; + } + + private static void ConsumeToken(ref Utf8JsonStreamReader reader, JsonTokenType expected) + { + if (reader.Read() && expected == reader.TokenType) + { + return; + } + ThrowUnexpectedTokenException(ref reader, expected); + } + + private static void ThrowUnexpectedTokenException(ref Utf8JsonStreamReader reader, JsonTokenType expected) + { + string key; + if (expected.IsBool()) + { + key = Strings.ExpectedBoolAtOffset; + } + else if (expected.IsInt()) + { + key = Strings.ExpectedIntegerAtOffset; + } + else if (expected == JsonTokenType.String) + { + key = Strings.ExpectedStringAtOffset; + } + else + { + throw new GlobalJsonFormatException(Strings.ExpectedTokenAtOffset, expected, reader.TokenStartIndex); + } + + throw new GlobalJsonFormatException(key, reader.TokenStartIndex); + } + + private static string ReadString(ref Utf8JsonStreamReader reader) + { + ConsumeToken(ref reader, JsonTokenType.String); + return reader.GetString(); + } + } + + [Serializable] + class GlobalJsonFormatException : Exception + { + public GlobalJsonFormatException() { } + public GlobalJsonFormatException(string messageFormat, params object?[] args) : base(string.Format(messageFormat, args)) { } + public GlobalJsonFormatException(string message) : base(message) { } + public GlobalJsonFormatException(string message, Exception inner) : base(message, inner) { } + protected GlobalJsonFormatException(SerializationInfo info, StreamingContext context) : base(info, context) { } + } + } +} + diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 9eebc01d1c65..20f1ef347ed9 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -13,7 +13,7 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader { - public class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestProvider + public partial class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestProvider { private const string WorkloadSetsFolderName = "workloadsets"; @@ -27,11 +27,11 @@ public class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestProvider private readonly WorkloadSet? _workloadSet; public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? globalJsonPath) - : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir) + : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, globalJsonPath) { } - internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func getEnvironmentVariable, string? userProfileDir, string? requestedWorkloadSet = null) + internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func getEnvironmentVariable, string? userProfileDir, string? globalJsonPath = null) { if (string.IsNullOrWhiteSpace(sdkVersion)) { @@ -90,14 +90,20 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers _manifestRoots = _manifestRoots ?? Array.Empty(); var availableWorkloadSets = GetAvailableWorkloadSets(); - if (requestedWorkloadSet != null) + + if (globalJsonPath != null) { - if (!availableWorkloadSets.TryGetValue(requestedWorkloadSet, out _workloadSet)) + string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globalJsonPath); + if (globalJsonWorkloadSetVersion != null) { - throw new FileNotFoundException(string.Format(Strings.SpecifiedWorkloadSetNotFound, requestedWorkloadSet)); + if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet)) + { + throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, globalJsonPath)); + } } } - else if (availableWorkloadSets.Any()) + + if (_workloadSet == null && availableWorkloadSets.Any()) { var maxWorkloadSetVersion = availableWorkloadSets.Keys.Select(k => new ReleaseVersion(k)).Max()!; _workloadSet = availableWorkloadSets[maxWorkloadSetVersion.ToString()]; diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx index 8fd50a5bae10..6fd2ecda0cea 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx @@ -192,8 +192,8 @@ Specified workload manifest was not found: {0} - - Specified workload set was not found: {0} + + Workload version {0}, which was specified in {1}, was not found Error parsing version '{1}' for workload manifest ID '{0}' diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.NewtonsoftJson.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.NewtonsoftJson.cs index 99ae66379fb8..a03776f25749 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.NewtonsoftJson.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.NewtonsoftJson.cs @@ -41,7 +41,7 @@ public static WorkloadManifest ReadWorkloadManifest(string manifestId, Stream ma } // this is a compat wrapper so the source matches the system.text.json impl - private ref struct Utf8JsonStreamReader + internal ref struct Utf8JsonStreamReader { public Utf8JsonStreamReader(JsonTextReader reader) { diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.SystemTextJson.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.SystemTextJson.cs index 2aca5c01baea..8682dceb9a85 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.SystemTextJson.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadManifestReader.SystemTextJson.cs @@ -38,7 +38,7 @@ public static WorkloadManifest ReadWorkloadManifest(string manifestId, Stream ma return ReadLocalizationCatalog(ref localizationReader); } - private ref struct Utf8JsonStreamReader + internal ref struct Utf8JsonStreamReader { static ReadOnlySpan utf8Bom => new byte[] { 0xEF, 0xBB, 0xBF }; diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf index e71b6b8e47ee..4ced45e75b07 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf @@ -107,11 +107,6 @@ Zadaný manifest úlohy se nenašel: {0} - - Specified workload set was not found: {0} - Zadaná sada úloh se nenašla: {0} - - Unexpected token '{0}' at offset {1} Neočekávaný token {0} u posunu {1} @@ -137,6 +132,11 @@ Nevyřešený cíl {0} pro přesměrování úlohy {1} v manifestu {2} [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf index f426c8f24b81..034d70f74949 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf @@ -107,11 +107,6 @@ Das angegebene Workloadmanifest wurde nicht gefunden: {0} - - Specified workload set was not found: {0} - Die angegebene Workloadgruppe wurde nicht gefunden: {0} - - Unexpected token '{0}' at offset {1} Unerwartetes Token "{0}" bei Offset {1}. @@ -137,6 +132,11 @@ Nicht aufgelöstes Ziel „{0}“ für die Workloadumleitung „{1}“ im Manifest „{2}“ [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf index 3af09af0f85c..0fdc95f983e8 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf @@ -107,11 +107,6 @@ No se encontró el manifiesto de carga de trabajo especificado: {0} - - Specified workload set was not found: {0} - No se encontró el conjunto de cargas de trabajo especificado: {0} - - Unexpected token '{0}' at offset {1} Token "{0}" inesperado en el desplazamiento {1} @@ -137,6 +132,11 @@ Destino sin resolver '{0}' para redirección de carga de trabajo '{1}' en el manifiesto '{2}' [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf index 5aa6655d7bd0..5941a8eb5afc 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf @@ -107,11 +107,6 @@ Le manifeste de charge de travail spécifié est introuvable : {0} - - Specified workload set was not found: {0} - L’ensemble de charge de travail spécifié est introuvable : {0} - - Unexpected token '{0}' at offset {1} Jeton '{0}' inattendu à l'offset {1} @@ -137,6 +132,11 @@ Cible non résolue « {0} » pour la redirection de charge de travail « {1} » dans le manifeste « {2} » [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf index 89c6799baf98..af5a9678c3b5 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf @@ -107,11 +107,6 @@ Il manifesto del carico di lavoro specificato non è stato trovato: {0} - - Specified workload set was not found: {0} - Il set di carico di lavoro specificato non è stato trovato: {0} - - Unexpected token '{0}' at offset {1} Token '{0}' imprevisto alla posizione di offset {1} @@ -137,6 +132,11 @@ Destinazione non risolta '{0}' per il reindirizzamento del carico di lavoro '{1}' nel manifesto '{2}' [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf index 3fd54ffcb479..dc1b77f561fc 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf @@ -107,11 +107,6 @@ 指定されたワークロード マニフェストが見つかりませんでした: {0} - - Specified workload set was not found: {0} - 指定されたワークロード セットが見つかりませんでした: {0} - - Unexpected token '{0}' at offset {1} オフセット {1} に予期しないトークン '{0}' があります @@ -137,6 +132,11 @@ マニフェスト '{2}' [{3}] 内のワークロード リダイレクト '{1}' に対する未解決のターゲット '{0}' + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf index 43ce489e53ca..b54ee64fa26c 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf @@ -107,11 +107,6 @@ 지정한 워크로드 매니페스트를 찾을 수 없습니다. {0} - - Specified workload set was not found: {0} - 지정한 워크로드 집합을 찾을 수 없습니다. {0} - - Unexpected token '{0}' at offset {1} 오프셋 {1}에 예기치 않은 토큰 '{0}'이(가) 있습니다. @@ -137,6 +132,11 @@ 매니페스트 '{2}' [{3}]의 워크로드 리디렉션 '{1}'에 대한 확인되지 않는 대상 '{0}' + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf index a7dedc315ea0..3baf84d2798d 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf @@ -107,11 +107,6 @@ Nie znaleziono określonego manifestu obciążenia: {0} - - Specified workload set was not found: {0} - Nie znaleziono określonego zestawu obciążeń: {0} - - Unexpected token '{0}' at offset {1} Nieoczekiwany token „{0}” pod przesunięciem {1} @@ -137,6 +132,11 @@ Nierozpoznany element docelowy „{0}” przekierowania obciążenia „{1}” w manifeście „{2}” [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf index 9cd19380a167..dcefe9f6d475 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf @@ -107,11 +107,6 @@ O manifesto de carga de trabalho especificado não foi encontrado: {0} - - Specified workload set was not found: {0} - O conjunto de cargas de trabalho especificado não foi encontrado: {0} - - Unexpected token '{0}' at offset {1} Token inesperado '{0}' no deslocamento {1} @@ -137,6 +132,11 @@ Destino '{0}' não resolvido para o redirecionamento de carga de trabalho '{1}' no manifesto '{2}' [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf index de2a933fb3e7..47a5b90f3d06 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf @@ -107,11 +107,6 @@ Указанный манифест рабочей нагрузки не найден: {0} - - Specified workload set was not found: {0} - Указанный набор рабочей нагрузки не найден: {0} - - Unexpected token '{0}' at offset {1} Непредвиденный токен "{0}" в смещении {1} @@ -137,6 +132,11 @@ Неразрешенный целевой объект "{0}" для перенаправления рабочей нагрузки "{1}" в манифесте "{2}" [{3}] + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf index 1d9f4f0baf8a..8864b1658472 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf @@ -107,11 +107,6 @@ Belirtilen iş yükü bildirimi bulunamadı: {0} - - Specified workload set was not found: {0} - Belirtilen iş yükü bildirimi bulunamadı: {0} - - Unexpected token '{0}' at offset {1} {1} uzaklığında beklenmeyen '{0}' belirteci @@ -137,6 +132,11 @@ '{2}' [{3}] bildirimindeki '{1}' iş akışı yeniden yönlendirmesi için '{0}' hedefi çözümlenemedi + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf index 17023dabdd62..a5b53c47d2f7 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf @@ -107,11 +107,6 @@ 找不到指定的工作负荷清单: {0} - - Specified workload set was not found: {0} - 找不到指定的工作负荷集: {0} - - Unexpected token '{0}' at offset {1} 偏移为 {1} 时意外出现的标记“{0}” @@ -137,6 +132,11 @@ 工作负载未解析的目标“{0}”重定向到清单“{2}”[{3}] 中的“{1}” + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf index 50a1a75149cd..c946453d8855 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf @@ -107,11 +107,6 @@ 找不到指定的工作負載資訊清單: {0} - - Specified workload set was not found: {0} - 找不到指定的工作負載集: {0} - - Unexpected token '{0}' at offset {1} 位移 {1} 有未預期的權杖 '{0}' @@ -137,6 +132,11 @@ 資訊清單 '{2}' [{3}] 中工作負載重新導向 '{1}' 的未解析目標 '{0}' + + Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found + + \ No newline at end of file From 932e58373b6198a52a1c8916b1e0fbeff1c65cc1 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 20 Jun 2023 16:18:24 -0400 Subject: [PATCH 3/5] Add tests for workload set version in global.json --- ...rkloadManifestProvider.GlobalJsonReader.cs | 2 +- ...kDirectoryWorkloadManifestProviderTests.cs | 129 +++++++++++++++++- 2 files changed, 126 insertions(+), 5 deletions(-) diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs index 4d90e4f0c25c..c152df98d689 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs @@ -168,7 +168,7 @@ private static string ReadString(ref Utf8JsonStreamReader reader) } [Serializable] - class GlobalJsonFormatException : Exception + internal class GlobalJsonFormatException : Exception { public GlobalJsonFormatException() { } public GlobalJsonFormatException(string messageFormat, params object?[] args) : base(string.Format(messageFormat, args)) { } diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index f7509eeed9f1..593b70fd2ff6 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -10,6 +10,7 @@ using System.Text.Json; using FluentAssertions; using Microsoft.DotNet.Cli; +using Microsoft.NET.Sdk.Localization; using Microsoft.NET.Sdk.WorkloadManifestReader; using Microsoft.NET.TestFramework; @@ -201,10 +202,32 @@ var sdkDirectoryWorkloadManifestProvider .BeEquivalentTo("ios: 11.0.2/8.0.100", "android: 33.0.2-rc.1/8.0.200", "maui: 15.0.1-rc.456/8.0.200-rc.2"); } - [Fact] - public void ItUsesLatestWorkloadSet() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void ItUsesLatestWorkloadSet(bool globalJsonExists) { - Initialize("8.0.200"); + Initialize("8.0.200", identifier: globalJsonExists.ToString()); + + string? globalJsonPath; + if (globalJsonExists) + { + globalJsonPath = Path.Combine(_testDirectory, "global.json"); + File.WriteAllText(globalJsonPath, """ + { + "sdk": { + "version": "1.0.42", + }, + "msbuild-sdks": { + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", + } + } + """); + } + else + { + globalJsonPath = null; + } CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true); CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true); @@ -223,7 +246,7 @@ public void ItUsesLatestWorkloadSet() """); var sdkDirectoryWorkloadManifestProvider - = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null); + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath); GetManifestContents(sdkDirectoryWorkloadManifestProvider) .Should() @@ -402,6 +425,104 @@ public void ItThrowsExceptionIfWorkloadSetJsonFilesHaveDuplicateManifests() new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null)); } + [Fact] + public void ItUsesWorkloadSetFromGlobalJson() + { + Initialize("8.0.200"); + + string? globalJsonPath = Path.Combine(_testDirectory, "global.json"); + File.WriteAllText(globalJsonPath, """ + { + "sdk": { + "version": "8.0.200", + "workloadversion": "8.0.201" + }, + "msbuild-sdks": { + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", + } + } + """); + + CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true); + CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true); + CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.201", """ +{ + "ios": "11.0.2/8.0.100" +} +"""); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ +{ + "ios": "12.0.1/8.0.200" +} +"""); + + var sdkDirectoryWorkloadManifestProvider + = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath); + + GetManifestContents(sdkDirectoryWorkloadManifestProvider) + .Should() + .BeEquivalentTo("ios: 11.0.2/8.0.100"); + } + + [Fact] + public void ItFailsIfWorkloadSetFromGlobalJsonIsNotInstalled() + { + Initialize("8.0.200"); + + string? globalJsonPath = Path.Combine(_testDirectory, "global.json"); + File.WriteAllText(globalJsonPath, """ + { + "sdk": { + "version": "8.0.200", + "workloadversion": "8.0.201" + }, + "msbuild-sdks": { + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", + } + } + """); + + CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ +{ + "ios": "12.0.1/8.0.200" +} +"""); + + var ex = Assert.Throws(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath)); + ex.Message.Should().Be(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, "8.0.201", globalJsonPath)); + } + + [Fact] + public void ItFailsIfGlobalJsonIsMalformed() + { + Initialize("8.0.200"); + + string? globalJsonPath = Path.Combine(_testDirectory, "global.json"); + File.WriteAllText(globalJsonPath, """ + { + "sdk": { + "workloadversion": [ "8.0.202" ] + } + } + """); + + CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ +{ + "ios": "12.0.1/8.0.200" +} +"""); + + var ex = Assert.Throws( + () => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath)); + } + [Fact] public void ItShouldReturnManifestsFromTestHook() { From 477171d34c38929eef404cbd55e7a162e9ab5ac7 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 22 Jun 2023 13:23:47 -0400 Subject: [PATCH 4/5] Refactor workload resolver creation --- .../commands/InstallingWorkloadCommand.cs | 30 +++-- .../install/WorkloadOptionsExtensions.cs | 54 --------- .../install/WorkloadResolverFactory.cs | 106 ++++++++++++++++++ .../repair/WorkloadRepairCommand.cs | 25 +++-- .../search/WorkloadSearchCommand.cs | 22 +++- .../uninstall/WorkloadUninstallCommand.cs | 22 +++- ...rkloadManifestProvider.GlobalJsonReader.cs | 1 - 7 files changed, 176 insertions(+), 84 deletions(-) delete mode 100644 src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs create mode 100644 src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index 3ba50f8930e1..c458cf741ec0 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -33,8 +33,6 @@ internal abstract class InstallingWorkloadCommand : WorkloadCommandBase protected readonly string _dotnetPath; protected readonly string _userProfileDir; protected readonly bool _checkIfManifestExist; - protected readonly ReleaseVersion _sdkVersion; - protected readonly ReleaseVersion _installedSdkVersion; protected readonly SdkFeatureBand _sdkFeatureBand; protected readonly SdkFeatureBand _installedFeatureBand; protected readonly string _fromRollbackDefinition; @@ -63,13 +61,6 @@ public InstallingWorkloadCommand( _fromCacheOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.FromCacheOption); _includePreviews = parseResult.GetValueForOption(InstallingWorkloadCommandParser.IncludePreviewOption); _downloadToCacheOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.DownloadToCacheOption); - _dotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); - _userProfileDir = userProfileDir ?? CliFolderPathCalculator.DotnetUserProfileFolderPath; - _checkIfManifestExist = !(_printDownloadLinkOnly); // don't check for manifest existence when print download link is passed - _sdkVersion = WorkloadOptionsExtensions.GetValidatedSdkVersion(parseResult.GetValueForOption(InstallingWorkloadCommandParser.VersionOption), version, _dotnetPath, _userProfileDir, _checkIfManifestExist); - _sdkFeatureBand = new SdkFeatureBand(_sdkVersion); - _installedSdkVersion = new ReleaseVersion(version ?? Product.Version); - _installedFeatureBand = new SdkFeatureBand(installedFeatureBand ?? Product.Version); _fromRollbackDefinition = parseResult.GetValueForOption(InstallingWorkloadCommandParser.FromRollbackFileOption); var configOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.ConfigOption); @@ -77,8 +68,25 @@ public InstallingWorkloadCommand( _packageSourceLocation = string.IsNullOrEmpty(configOption) && (sourceOption == null || !sourceOption.Any()) ? null : new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), sourceFeedOverrides: sourceOption); - var sdkWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _installedSdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); - _workloadResolver = workloadResolver ?? WorkloadResolver.Create(sdkWorkloadManifestProvider, _dotnetPath, _installedSdkVersion.ToString(), _userProfileDir); + var creationParameters = new WorkloadResolverFactory.CreationParameters() + { + DotnetPath = dotnetDir, + UserProfileDir = userProfileDir, + GlobalJsonStartDir = null, + VersionFromOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.VersionOption), + VersionForTesting = version, + CheckIfFeatureBandManifestExists = !(_printDownloadLinkOnly), // don't check for manifest existence when print download link is passed + WorkloadResolverForTesting = workloadResolver, + UseInstalledSdkVersionForResolver = true + }; + + var creationResult = WorkloadResolverFactory.Create(creationParameters); + + _dotnetPath = creationResult.DotnetPath; + _userProfileDir = creationResult.UserProfileDir; + _sdkFeatureBand = new SdkFeatureBand(creationResult.SdkVersion); + _installedFeatureBand = new SdkFeatureBand(creationResult.InstalledSdkVersion); + _workloadResolver = creationResult.WorkloadResolver; _workloadInstallerFromConstructor = workloadInstaller; _workloadManifestUpdaterFromConstructor = workloadManifestUpdater; diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs deleted file mode 100644 index 22cb585cffe5..000000000000 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadOptionsExtensions.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.CommandLine.Parsing; -using Microsoft.Deployment.DotNet.Releases; -using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.NET.Sdk.WorkloadManifestReader; -using Product = Microsoft.DotNet.Cli.Utils.Product; -using System.IO; -using System.Linq; - -namespace Microsoft.DotNet.Workloads.Workload.Install -{ - internal class WorkloadOptionsExtensions - { - internal static ReleaseVersion GetValidatedSdkVersion(string versionOption, string providedVersion, string dotnetPath, string userProfileDir, bool checkIfFeatureBandManifestsExist) - { - - if (string.IsNullOrEmpty(versionOption)) - { - return new ReleaseVersion(providedVersion ?? Product.Version); - } - else - { - var manifests = new SdkDirectoryWorkloadManifestProvider(dotnetPath, versionOption, userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)).GetManifests(); - if (!manifests.Any() && checkIfFeatureBandManifestsExist) - { - throw new GracefulException(string.Format(LocalizableStrings.NoManifestsExistForFeatureBand, new SdkFeatureBand(versionOption).ToString()), isUserError: false); - } - try - { - foreach (var readableManifest in manifests) - { - using (var manifestStream = readableManifest.OpenManifestStream()) - using (var localizationStream = readableManifest.OpenLocalizationStream()) - { - var manifest = WorkloadManifestReader.ReadWorkloadManifest(readableManifest.ManifestId, manifestStream, localizationStream, readableManifest.ManifestPath); - } - } - } - catch - { - throw new GracefulException(string.Format(LocalizableStrings.IncompatibleManifests, versionOption), isUserError: false); - } - - return new ReleaseVersion(versionOption); - } - } - } -} diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs new file mode 100644 index 000000000000..4f9e1eba15de --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs @@ -0,0 +1,106 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Deployment.DotNet.Releases; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Configurer; +using Microsoft.NET.Sdk.WorkloadManifestReader; +using Product = Microsoft.DotNet.Cli.Utils.Product; + +namespace Microsoft.DotNet.Workloads.Workload.Install +{ + internal static class WorkloadResolverFactory + { + public class CreationParameters + { + public string DotnetPath { get; set; } + public string UserProfileDir { get; set; } + public string GlobalJsonStartDir { get; set; } + public string VersionFromOption { get; set; } + public string VersionForTesting { get; set; } + public bool CheckIfFeatureBandManifestExists { get; set; } + public IWorkloadResolver WorkloadResolverForTesting { get; set; } + + public bool UseInstalledSdkVersionForResolver { get; set; } + } + + public class CreationResult + { + public string DotnetPath { get; set; } + public string UserProfileDir { get; set; } + public ReleaseVersion SdkVersion { get; set; } + public ReleaseVersion InstalledSdkVersion { get; set; } + public IWorkloadResolver WorkloadResolver { get; set; } + + } + + public static CreationResult Create(CreationParameters parameters) + { + var result = new CreationResult(); + + result.InstalledSdkVersion = new ReleaseVersion(parameters.VersionForTesting ?? Product.Version); + + bool manifestsNeedValidation; + if (string.IsNullOrEmpty(parameters.VersionFromOption)) + { + result.SdkVersion = result.InstalledSdkVersion; + manifestsNeedValidation = false; + } + else + { + result.SdkVersion = new ReleaseVersion(parameters.VersionFromOption); + manifestsNeedValidation = true; + } + + result.DotnetPath = parameters.DotnetPath ?? Path.GetDirectoryName(Environment.ProcessPath); + result.UserProfileDir = parameters.UserProfileDir ?? CliFolderPathCalculator.DotnetUserProfileFolderPath; + string globalJsonStartDir = parameters.GlobalJsonStartDir ?? Environment.CurrentDirectory; + + string globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(globalJsonStartDir); + + var sdkWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(result.DotnetPath, result.SdkVersion.ToString(), result.UserProfileDir, globalJsonPath); + + if (manifestsNeedValidation) + { + var manifests = sdkWorkloadManifestProvider.GetManifests(); + if (parameters.CheckIfFeatureBandManifestExists && !manifests.Any()) + { + throw new GracefulException(string.Format(LocalizableStrings.NoManifestsExistForFeatureBand, result.SdkVersion.ToString()), isUserError: false); + } + try + { + foreach (var readableManifest in manifests) + { + using (var manifestStream = readableManifest.OpenManifestStream()) + using (var localizationStream = readableManifest.OpenLocalizationStream()) + { + var manifest = WorkloadManifestReader.ReadWorkloadManifest(readableManifest.ManifestId, manifestStream, localizationStream, readableManifest.ManifestPath); + } + } + } + catch + { + throw new GracefulException(string.Format(LocalizableStrings.IncompatibleManifests, parameters.VersionFromOption), isUserError: false); + } + } + + ReleaseVersion versionForResolver = parameters.UseInstalledSdkVersionForResolver ? result.InstalledSdkVersion : result.SdkVersion; + if (parameters.UseInstalledSdkVersionForResolver && !result.InstalledSdkVersion.Equals(result.SdkVersion)) + { + // Create new manifest provider using installed SDK version instead of the target SDK version + sdkWorkloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(result.DotnetPath, result.InstalledSdkVersion.ToString(), result.UserProfileDir, globalJsonPath); + } + + result.WorkloadResolver = parameters.WorkloadResolverForTesting ?? WorkloadResolver.Create(sdkWorkloadManifestProvider, result.DotnetPath, result.SdkVersion.ToString(), result.UserProfileDir); + + return result; + } + } +} diff --git a/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs index 2b376dacc0e1..a0af5bc3ee68 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs @@ -40,19 +40,30 @@ public WorkloadRepairCommand( string userProfileDir = null) : base(parseResult, reporter: reporter, nugetPackageDownloader: nugetPackageDownloader) { - _dotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); - userProfileDir ??= CliFolderPathCalculator.DotnetUserProfileFolderPath; - _sdkVersion = WorkloadOptionsExtensions.GetValidatedSdkVersion(parseResult.GetValueForOption(WorkloadRepairCommandParser.VersionOption), version, _dotnetPath, userProfileDir, true); - var configOption = parseResult.GetValueForOption(WorkloadRepairCommandParser.ConfigOption); var sourceOption = parseResult.GetValueForOption(WorkloadRepairCommandParser.SourceOption); _packageSourceLocation = string.IsNullOrEmpty(configOption) && (sourceOption == null || !sourceOption.Any()) ? null : new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), sourceFeedOverrides: sourceOption); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(_dotnetPath, _sdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); - _workloadResolver = workloadResolver ?? WorkloadResolver.Create(workloadManifestProvider, _dotnetPath, _sdkVersion.ToString(), userProfileDir); + var creationParameters = new WorkloadResolverFactory.CreationParameters() + { + DotnetPath = dotnetDir, + UserProfileDir = userProfileDir, + GlobalJsonStartDir = null, + VersionFromOption = parseResult.GetValueForOption(WorkloadRepairCommandParser.VersionOption), + VersionForTesting = version, + CheckIfFeatureBandManifestExists = true, + WorkloadResolverForTesting = workloadResolver, + UseInstalledSdkVersionForResolver = false + }; + + var creationResult = WorkloadResolverFactory.Create(creationParameters); + + _dotnetPath = creationResult.DotnetPath; + _sdkVersion = creationResult.SdkVersion; var sdkFeatureBand = new SdkFeatureBand(_sdkVersion); - + _workloadResolver = creationResult.WorkloadResolver; + _workloadInstaller = workloadInstaller ?? WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand, _workloadResolver, Verbosity, userProfileDir, VerifySignatures, PackageDownloader, dotnetDir, TempDirectoryPath, diff --git a/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs index 2b1aad6cb170..8807b7b846a1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs @@ -30,11 +30,23 @@ public WorkloadSearchCommand( string userProfileDir = null) : base(result, CommonOptions.HiddenVerbosityOption, reporter) { _workloadIdStub = result.GetValueForArgument(WorkloadSearchCommandParser.WorkloadIdStubArgument); - var dotnetPath = Path.GetDirectoryName(Environment.ProcessPath); - userProfileDir ??= CliFolderPathCalculator.DotnetUserProfileFolderPath; - _sdkVersion = WorkloadOptionsExtensions.GetValidatedSdkVersion(result.GetValueForOption(WorkloadSearchCommandParser.VersionOption), version, dotnetPath, userProfileDir, true); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); - _workloadResolver = workloadResolver ?? WorkloadResolver.Create(workloadManifestProvider, dotnetPath, _sdkVersion.ToString(), userProfileDir); + + var creationParameters = new WorkloadResolverFactory.CreationParameters() + { + DotnetPath = null, + UserProfileDir = userProfileDir, + GlobalJsonStartDir = null, + VersionFromOption = result.GetValueForOption(WorkloadSearchCommandParser.VersionOption), + VersionForTesting = version, + CheckIfFeatureBandManifestExists = true, + WorkloadResolverForTesting = workloadResolver, + UseInstalledSdkVersionForResolver = true + }; + + var creationResult = WorkloadResolverFactory.Create(creationParameters); + + _sdkVersion = creationResult.SdkVersion; + _workloadResolver = creationResult.WorkloadResolver; } public override int Execute() diff --git a/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs index fca9467b1536..da088b49de78 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs @@ -39,15 +39,25 @@ public WorkloadUninstallCommand( { _workloadIds = parseResult.GetValueForArgument(WorkloadUninstallCommandParser.WorkloadIdArgument) .Select(workloadId => new WorkloadId(workloadId)).ToList().AsReadOnly(); - var dotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); - userProfileDir = userProfileDir ?? CliFolderPathCalculator.DotnetUserProfileFolderPath; - _sdkVersion = WorkloadOptionsExtensions.GetValidatedSdkVersion(parseResult.GetValueForOption(WorkloadUninstallCommandParser.VersionOption), version, dotnetPath, userProfileDir, true); - var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(dotnetPath, _sdkVersion.ToString(), userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); - workloadResolver ??= WorkloadResolver.Create(workloadManifestProvider, dotnetPath, _sdkVersion.ToString(), userProfileDir); + var creationParameters = new WorkloadResolverFactory.CreationParameters() + { + DotnetPath = dotnetDir, + UserProfileDir = userProfileDir, + GlobalJsonStartDir = null, + VersionFromOption = parseResult.GetValueForOption(WorkloadUninstallCommandParser.VersionOption), + VersionForTesting = version, + CheckIfFeatureBandManifestExists = true, + WorkloadResolverForTesting = workloadResolver, + UseInstalledSdkVersionForResolver = true + }; + + var creationResult = WorkloadResolverFactory.Create(creationParameters); + + _sdkVersion = creationResult.SdkVersion; var sdkFeatureBand = new SdkFeatureBand(_sdkVersion); - _workloadInstaller = WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand, workloadResolver, Verbosity, userProfileDir, VerifySignatures, PackageDownloader, dotnetPath); + _workloadInstaller = WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand, workloadResolver, Verbosity, userProfileDir, VerifySignatures, PackageDownloader, creationResult.DotnetPath); } public override int Execute() diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs index c152df98d689..20027af22f33 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs @@ -99,7 +99,6 @@ static class GlobalJsonReader throw new GlobalJsonFormatException(Strings.IncompleteDocument); } - /// /// this expects the reader to be before the value token, and leaves it on the last token of the value /// From d2547b17f9c1e25763446f5ea7dc4c85ef60fc86 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 23 Jun 2023 13:26:40 -0400 Subject: [PATCH 5/5] Code review feedback --- src/Cli/dotnet/commands/InstallingWorkloadCommand.cs | 2 +- .../dotnet-workload/install/WorkloadResolverFactory.cs | 8 ++++---- .../dotnet-workload/repair/WorkloadRepairCommand.cs | 4 ++-- .../dotnet-workload/search/WorkloadSearchCommand.cs | 2 +- .../dotnet-workload/uninstall/WorkloadUninstallCommand.cs | 4 ++-- .../Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx | 2 +- .../xlf/Strings.cs.xlf | 4 ++-- .../xlf/Strings.de.xlf | 4 ++-- .../xlf/Strings.es.xlf | 4 ++-- .../xlf/Strings.fr.xlf | 4 ++-- .../xlf/Strings.it.xlf | 4 ++-- .../xlf/Strings.ja.xlf | 4 ++-- .../xlf/Strings.ko.xlf | 4 ++-- .../xlf/Strings.pl.xlf | 4 ++-- .../xlf/Strings.pt-BR.xlf | 4 ++-- .../xlf/Strings.ru.xlf | 4 ++-- .../xlf/Strings.tr.xlf | 4 ++-- .../xlf/Strings.zh-Hans.xlf | 4 ++-- .../xlf/Strings.zh-Hant.xlf | 4 ++-- 19 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index c458cf741ec0..12be81805f2d 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -73,7 +73,7 @@ public InstallingWorkloadCommand( DotnetPath = dotnetDir, UserProfileDir = userProfileDir, GlobalJsonStartDir = null, - VersionFromOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.VersionOption), + SdkVersionFromOption = parseResult.GetValueForOption(InstallingWorkloadCommandParser.VersionOption), VersionForTesting = version, CheckIfFeatureBandManifestExists = !(_printDownloadLinkOnly), // don't check for manifest existence when print download link is passed WorkloadResolverForTesting = workloadResolver, diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs index 4f9e1eba15de..542585ed9ff8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadResolverFactory.cs @@ -23,7 +23,7 @@ public class CreationParameters public string DotnetPath { get; set; } public string UserProfileDir { get; set; } public string GlobalJsonStartDir { get; set; } - public string VersionFromOption { get; set; } + public string SdkVersionFromOption { get; set; } public string VersionForTesting { get; set; } public bool CheckIfFeatureBandManifestExists { get; set; } public IWorkloadResolver WorkloadResolverForTesting { get; set; } @@ -48,14 +48,14 @@ public static CreationResult Create(CreationParameters parameters) result.InstalledSdkVersion = new ReleaseVersion(parameters.VersionForTesting ?? Product.Version); bool manifestsNeedValidation; - if (string.IsNullOrEmpty(parameters.VersionFromOption)) + if (string.IsNullOrEmpty(parameters.SdkVersionFromOption)) { result.SdkVersion = result.InstalledSdkVersion; manifestsNeedValidation = false; } else { - result.SdkVersion = new ReleaseVersion(parameters.VersionFromOption); + result.SdkVersion = new ReleaseVersion(parameters.SdkVersionFromOption); manifestsNeedValidation = true; } @@ -87,7 +87,7 @@ public static CreationResult Create(CreationParameters parameters) } catch { - throw new GracefulException(string.Format(LocalizableStrings.IncompatibleManifests, parameters.VersionFromOption), isUserError: false); + throw new GracefulException(string.Format(LocalizableStrings.IncompatibleManifests, parameters.SdkVersionFromOption), isUserError: false); } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs index a0af5bc3ee68..6e2042249349 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/repair/WorkloadRepairCommand.cs @@ -50,7 +50,7 @@ public WorkloadRepairCommand( DotnetPath = dotnetDir, UserProfileDir = userProfileDir, GlobalJsonStartDir = null, - VersionFromOption = parseResult.GetValueForOption(WorkloadRepairCommandParser.VersionOption), + SdkVersionFromOption = parseResult.GetValueForOption(WorkloadRepairCommandParser.VersionOption), VersionForTesting = version, CheckIfFeatureBandManifestExists = true, WorkloadResolverForTesting = workloadResolver, @@ -66,7 +66,7 @@ public WorkloadRepairCommand( _workloadInstaller = workloadInstaller ?? WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand, - _workloadResolver, Verbosity, userProfileDir, VerifySignatures, PackageDownloader, dotnetDir, TempDirectoryPath, + _workloadResolver, Verbosity, creationResult.UserProfileDir, VerifySignatures, PackageDownloader, dotnetDir, TempDirectoryPath, _packageSourceLocation, _parseResult.ToRestoreActionConfig()); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs index 8807b7b846a1..d2e1d7b70c4e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/search/WorkloadSearchCommand.cs @@ -36,7 +36,7 @@ public WorkloadSearchCommand( DotnetPath = null, UserProfileDir = userProfileDir, GlobalJsonStartDir = null, - VersionFromOption = result.GetValueForOption(WorkloadSearchCommandParser.VersionOption), + SdkVersionFromOption = result.GetValueForOption(WorkloadSearchCommandParser.VersionOption), VersionForTesting = version, CheckIfFeatureBandManifestExists = true, WorkloadResolverForTesting = workloadResolver, diff --git a/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs index da088b49de78..638b09028551 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/uninstall/WorkloadUninstallCommand.cs @@ -45,7 +45,7 @@ public WorkloadUninstallCommand( DotnetPath = dotnetDir, UserProfileDir = userProfileDir, GlobalJsonStartDir = null, - VersionFromOption = parseResult.GetValueForOption(WorkloadUninstallCommandParser.VersionOption), + SdkVersionFromOption = parseResult.GetValueForOption(WorkloadUninstallCommandParser.VersionOption), VersionForTesting = version, CheckIfFeatureBandManifestExists = true, WorkloadResolverForTesting = workloadResolver, @@ -57,7 +57,7 @@ public WorkloadUninstallCommand( _sdkVersion = creationResult.SdkVersion; var sdkFeatureBand = new SdkFeatureBand(_sdkVersion); - _workloadInstaller = WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand, workloadResolver, Verbosity, userProfileDir, VerifySignatures, PackageDownloader, creationResult.DotnetPath); + _workloadInstaller = WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, sdkFeatureBand, creationResult.WorkloadResolver, Verbosity, creationResult.UserProfileDir, VerifySignatures, PackageDownloader, creationResult.DotnetPath); } public override int Execute() diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx index 6fd2ecda0cea..c728ad1b1252 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx @@ -193,7 +193,7 @@ Specified workload manifest was not found: {0} - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. Error parsing version '{1}' for workload manifest ID '{0}' diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf index 4ced45e75b07..21c6db144608 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf index 034d70f74949..964ea8d93bc4 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf index 0fdc95f983e8..14947a999995 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf index 5941a8eb5afc..f9c0d0118b3a 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf index af5a9678c3b5..79c6896ac19a 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf index dc1b77f561fc..3afd0757c553 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf index b54ee64fa26c..e5f2ddbf82be 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf index 3baf84d2798d..ce40b3cf34b3 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf index dcefe9f6d475..a12293a4d03a 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf index 47a5b90f3d06..a8800afc0c1c 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf index 8864b1658472..7d219cb80738 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf index a5b53c47d2f7..2e3f773f6d9b 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf index c946453d8855..cb75375292af 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf @@ -133,8 +133,8 @@ - Workload version {0}, which was specified in {1}, was not found - Workload version {0}, which was specified in {1}, was not found + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. + Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version.