Skip to content

Commit 12e0132

Browse files
authored
Permit specifying to use workload versions in global.json (#47421)
Uses workloads-update-mode next to where you'd put a specific workload version to determine if we should be in workload set mode when doing install/update. If there's a conflict between this and other flags, it should error or warn (depending on where it is). Example: ``` { "sdk": { "workloads-update-mode" : "workload-set" } } ```
1 parent 706bc55 commit 12e0132

37 files changed

+318
-73
lines changed

src/Cli/dotnet/commands/InstallingWorkloadCommand.cs

Lines changed: 52 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ internal abstract class InstallingWorkloadCommand : WorkloadCommandBase
4747
protected readonly IWorkloadManifestUpdater _workloadManifestUpdaterFromConstructor;
4848
protected IInstaller _workloadInstaller;
4949
protected IWorkloadManifestUpdater _workloadManifestUpdater;
50+
protected bool? _shouldUseWorkloadSets;
5051
private WorkloadHistoryState _workloadHistoryRecord;
5152

5253
protected bool UseRollback => !string.IsNullOrWhiteSpace(_fromRollbackDefinition);
@@ -86,7 +87,8 @@ public InstallingWorkloadCommand(
8687
IInstaller workloadInstaller,
8788
INuGetPackageDownloader nugetPackageDownloader,
8889
IWorkloadManifestUpdater workloadManifestUpdater,
89-
string tempDirPath)
90+
string tempDirPath,
91+
bool? shouldUseWorkloadSetsFromGlobalJson = null)
9092
: base(parseResult, reporter: reporter, tempDirPath: tempDirPath, nugetPackageDownloader: nugetPackageDownloader)
9193
{
9294
_arguments = parseResult.GetArguments();
@@ -132,7 +134,8 @@ public InstallingWorkloadCommand(
132134
_workloadManifestUpdaterFromConstructor = workloadManifestUpdater;
133135

134136
_globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory);
135-
_workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPath);
137+
_workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPath, out _shouldUseWorkloadSets);
138+
_shouldUseWorkloadSets = shouldUseWorkloadSetsFromGlobalJson ?? _shouldUseWorkloadSets;
136139

137140
if (SpecifiedWorkloadSetVersionInGlobalJson && (SpecifiedWorkloadSetVersionOnCommandLine || UseRollback || FromHistory))
138141
{
@@ -150,6 +153,14 @@ public InstallingWorkloadCommand(
150153
InstallingWorkloadCommandParser.WorkloadSetVersionOption.Name,
151154
WorkloadUpdateCommandParser.FromHistoryOption.Name), isUserError: true);
152155
}
156+
else if (_shouldUseWorkloadSets == true && (UseRollback || (FromHistory && _WorkloadHistoryRecord.WorkloadSetVersion is null)))
157+
{
158+
throw new GracefulException(Workloads.Workload.Update.LocalizableStrings.SpecifiedWorkloadVersionAndSpecificNonWorkloadVersion, isUserError: true);
159+
}
160+
else if (_shouldUseWorkloadSets == false && (SpecifiedWorkloadSetVersionInGlobalJson || SpecifiedWorkloadSetVersionOnCommandLine || (FromHistory && _WorkloadHistoryRecord.WorkloadSetVersion is not null)))
161+
{
162+
throw new GracefulException(Workloads.Workload.Update.LocalizableStrings.SpecifiedNoWorkloadVersionAndSpecificWorkloadVersion, isUserError: true);
163+
}
153164

154165
// At this point, at most one of SpecifiedWorkloadSetVersionOnCommandLine, UseRollback, FromHistory, and SpecifiedWorkloadSetVersionInGlobalJson is true
155166
}
@@ -161,23 +172,19 @@ protected static Dictionary<string, string> GetInstallStateContents(IEnumerable<
161172

162173
InstallStateContents GetCurrentInstallState()
163174
{
164-
return GetCurrentInstallState(_sdkFeatureBand, _workloadRootDir);
165-
}
166-
167-
static InstallStateContents GetCurrentInstallState(SdkFeatureBand sdkFeatureBand, string dotnetDir)
168-
{
169-
string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, dotnetDir), "default.json");
175+
string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _workloadRootDir), "default.json");
170176
return InstallStateContents.FromPath(path);
171177
}
172178

173179
public static bool ShouldUseWorkloadSetMode(SdkFeatureBand sdkFeatureBand, string dotnetDir)
174180
{
175-
return GetCurrentInstallState(sdkFeatureBand, dotnetDir).ShouldUseWorkloadSets();
181+
return WorkloadManifestUpdater.ShouldUseWorkloadSetMode(sdkFeatureBand, dotnetDir);
176182
}
177183

178184
protected void UpdateWorkloadManifests(WorkloadHistoryRecorder recorder, ITransactionContext context, DirectoryPath? offlineCache)
179185
{
180-
var updateToLatestWorkloadSet = ShouldUseWorkloadSetMode(_sdkFeatureBand, _workloadRootDir) && !SpecifiedWorkloadSetVersionInGlobalJson;
186+
var shouldUseWorkloadSetsPerInstallState = ShouldUseWorkloadSetMode(_sdkFeatureBand, _workloadRootDir);
187+
var updateToLatestWorkloadSet = _shouldUseWorkloadSets ?? shouldUseWorkloadSetsPerInstallState && !SpecifiedWorkloadSetVersionInGlobalJson;
181188
if (FromHistory && !string.IsNullOrWhiteSpace(_WorkloadHistoryRecord.WorkloadSetVersion))
182189
{
183190
// This is essentially the same as updating to a specific workload set version, and we're now past the error check,
@@ -192,6 +199,12 @@ protected void UpdateWorkloadManifests(WorkloadHistoryRecorder recorder, ITransa
192199
updateToLatestWorkloadSet = false;
193200
}
194201

202+
string resolvedWorkloadSetVersion = _workloadSetVersionFromGlobalJson;
203+
if (SpecifiedWorkloadSetVersionInGlobalJson && recorder is not null)
204+
{
205+
recorder.HistoryRecord.GlobalJsonVersion = _workloadSetVersionFromGlobalJson;
206+
}
207+
195208
if (SpecifiedWorkloadSetVersionOnCommandLine)
196209
{
197210
updateToLatestWorkloadSet = false;
@@ -204,45 +217,37 @@ protected void UpdateWorkloadManifests(WorkloadHistoryRecorder recorder, ITransa
204217
_workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true);
205218
}
206219

207-
if (SpecifiedWorkloadSetVersionInGlobalJson && recorder is not null)
208-
{
209-
recorder.HistoryRecord.GlobalJsonVersion = _workloadSetVersionFromGlobalJson;
210-
}
211-
}
212-
213-
string resolvedWorkloadSetVersion = null;
214-
215-
if (_workloadSetVersionFromCommandLine?.Any(v => v.Contains('@')) == true)
216-
{
217-
var versions = WorkloadSearchVersionsCommand.FindBestWorkloadSetsFromComponents(
218-
_sdkFeatureBand,
219-
_workloadInstaller is not NetSdkMsiInstallerClient ? _workloadInstaller : null,
220-
_sdkFeatureBand.IsPrerelease,
221-
PackageDownloader,
222-
_workloadSetVersionFromCommandLine,
223-
_workloadResolver,
224-
numberOfWorkloadSetsToTake: 1);
225-
226-
if (versions is null)
220+
if (_workloadSetVersionFromCommandLine.Any(v => v.Contains('@')))
227221
{
228-
return;
229-
}
230-
else if (!versions.Any())
231-
{
232-
Reporter.WriteLine(Workloads.Workload.Update.LocalizableStrings.NoWorkloadUpdateFound);
233-
return;
222+
var versions = WorkloadSearchVersionsCommand.FindBestWorkloadSetsFromComponents(
223+
_sdkFeatureBand,
224+
_workloadInstaller is not NetSdkMsiInstallerClient ? _workloadInstaller : null,
225+
_sdkFeatureBand.IsPrerelease,
226+
PackageDownloader,
227+
_workloadSetVersionFromCommandLine,
228+
_workloadResolver,
229+
numberOfWorkloadSetsToTake: 1);
230+
231+
if (versions is null)
232+
{
233+
return;
234+
}
235+
else if (!versions.Any())
236+
{
237+
Reporter.WriteLine(Workloads.Workload.Update.LocalizableStrings.NoWorkloadUpdateFound);
238+
return;
239+
}
240+
else
241+
{
242+
resolvedWorkloadSetVersion = versions.Single();
243+
}
234244
}
235245
else
236246
{
237-
resolvedWorkloadSetVersion = versions.Single();
247+
resolvedWorkloadSetVersion = _workloadSetVersionFromCommandLine.Single();
238248
}
239249
}
240-
else if (SpecifiedWorkloadSetVersionOnCommandLine)
241-
{
242-
resolvedWorkloadSetVersion = _workloadSetVersionFromCommandLine.Single();
243-
}
244250

245-
resolvedWorkloadSetVersion = _workloadSetVersionFromGlobalJson ?? resolvedWorkloadSetVersion;
246251
if (string.IsNullOrWhiteSpace(resolvedWorkloadSetVersion) && !UseRollback && !FromHistory)
247252
{
248253
_workloadManifestUpdater.UpdateAdvertisingManifestsAsync(_includePreviews, updateToLatestWorkloadSet, offlineCache).Wait();
@@ -270,17 +275,11 @@ protected void UpdateWorkloadManifests(WorkloadHistoryRecorder recorder, ITransa
270275
return;
271276
}
272277

273-
IEnumerable<ManifestVersionUpdate> manifestsToUpdate;
274-
if (resolvedWorkloadSetVersion != null)
275-
{
276-
manifestsToUpdate = InstallWorkloadSet(context, resolvedWorkloadSetVersion);
277-
}
278-
else
279-
{
280-
manifestsToUpdate = UseRollback ? _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition, recorder) :
281-
FromHistory ? _workloadManifestUpdater.CalculateManifestUpdatesFromHistory(_WorkloadHistoryRecord) :
282-
_workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate);
283-
}
278+
IEnumerable<ManifestVersionUpdate> manifestsToUpdate =
279+
resolvedWorkloadSetVersion != null ? InstallWorkloadSet(context, resolvedWorkloadSetVersion) :
280+
UseRollback ? _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition, recorder) :
281+
FromHistory ? _workloadManifestUpdater.CalculateManifestUpdatesFromHistory(_WorkloadHistoryRecord) :
282+
_workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate);
284283

285284
InstallStateContents oldInstallState = GetCurrentInstallState();
286285

src/Cli/dotnet/commands/dotnet-workload/GlobalJsonWorkloadSetFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ string GetWorkloadVersionFromGlobalJson(string globalJsonPath)
102102
{
103103
try
104104
{
105-
return SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globalJsonPath);
105+
return SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globalJsonPath, out _);
106106
}
107107
catch (SdkDirectoryWorkloadManifestProvider.JsonFormatException)
108108
{

src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,7 @@ To display a value, specify the corresponding command-line option without provid
124124
<data name="UpdateModeDescription" xml:space="preserve">
125125
<value>Controls whether updates should look for workload sets or the latest version of each individual manifest.</value>
126126
</data>
127+
<data name="UpdateModeDoesNotMatchGlobalJson" xml:space="preserve">
128+
<value>Specified to update workloads using {0} from the command line, but global.json file at {1} specified to use {2}.</value>
129+
</data>
127130
</root>

src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.DotNet.Cli;
77
using Microsoft.DotNet.Cli.Extensions;
88
using Microsoft.DotNet.Cli.Utils;
9+
using Microsoft.DotNet.Cli.Utils.Extensions;
910
using Microsoft.DotNet.Workloads.Workload.Install;
1011
using Microsoft.NET.Sdk.WorkloadManifestReader;
1112

@@ -53,17 +54,34 @@ public override int Execute()
5354
// It seems that the parser doesn't give us a good way to do that, however
5455
if (_hasUpdateMode)
5556
{
57+
string globalJsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory);
58+
var globalJsonVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globalJsonPath, out bool? shouldUseWorkloadSets);
59+
shouldUseWorkloadSets ??= string.IsNullOrWhiteSpace(globalJsonVersion) ? null : true;
5660
if (WorkloadConfigCommandParser.UpdateMode_WorkloadSet.Equals(_updateMode, StringComparison.InvariantCultureIgnoreCase))
5761
{
58-
_workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true);
62+
if (shouldUseWorkloadSets == false)
63+
{
64+
Reporter.WriteLine(string.Format(LocalizableStrings.UpdateModeDoesNotMatchGlobalJson, WorkloadConfigCommandParser.UpdateMode_WorkloadSet, globalJsonPath, WorkloadConfigCommandParser.UpdateMode_Manifests).Yellow());
65+
}
66+
else
67+
{
68+
_workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true);
69+
}
5970
}
6071
else if (WorkloadConfigCommandParser.UpdateMode_Manifests.Equals(_updateMode, StringComparison.InvariantCultureIgnoreCase))
6172
{
62-
_workloadInstaller.UpdateInstallMode(_sdkFeatureBand, false);
73+
if (shouldUseWorkloadSets == true)
74+
{
75+
Reporter.WriteLine(string.Format(LocalizableStrings.UpdateModeDoesNotMatchGlobalJson, WorkloadConfigCommandParser.UpdateMode_Manifests, globalJsonPath, WorkloadConfigCommandParser.UpdateMode_WorkloadSet).Yellow());
76+
}
77+
else
78+
{
79+
_workloadInstaller.UpdateInstallMode(_sdkFeatureBand, false);
80+
}
6381
}
6482
else if (string.IsNullOrEmpty(_updateMode))
6583
{
66-
if (InstallingWorkloadCommand.ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath))
84+
if (shouldUseWorkloadSets ?? InstallingWorkloadCommand.ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath))
6785
{
6886
Reporter.WriteLine(WorkloadConfigCommandParser.UpdateMode_WorkloadSet);
6987
}

src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)