10
10
using System . Text . Json . Nodes ;
11
11
using Microsoft . Deployment . DotNet . Releases ;
12
12
using Microsoft . DotNet . Cli ;
13
+ using Microsoft . DotNet . Cli . Commands . DotNetWorkloads ;
13
14
using Microsoft . DotNet . Cli . NuGetPackageDownloader ;
14
15
using Microsoft . DotNet . Cli . Utils ;
15
16
using Microsoft . DotNet . ToolPackage ;
17
+ using Microsoft . DotNet . Workloads . Workload . History ;
16
18
using Microsoft . DotNet . Workloads . Workload . Install ;
17
19
using Microsoft . DotNet . Workloads . Workload . Update ;
18
20
using Microsoft . Extensions . EnvironmentAbstractions ;
@@ -24,6 +26,7 @@ namespace Microsoft.DotNet.Workloads.Workload
24
26
{
25
27
internal abstract class InstallingWorkloadCommand : WorkloadCommandBase
26
28
{
29
+ protected readonly string [ ] _arguments ;
27
30
protected readonly bool _printDownloadLinkOnly ;
28
31
protected readonly string _fromCacheOption ;
29
32
protected readonly bool _includePreviews ;
@@ -36,6 +39,8 @@ internal abstract class InstallingWorkloadCommand : WorkloadCommandBase
36
39
protected readonly SdkFeatureBand _sdkFeatureBand ;
37
40
protected readonly ReleaseVersion _targetSdkVersion ;
38
41
protected readonly string _fromRollbackDefinition ;
42
+ protected int _fromHistorySpecified ;
43
+ protected bool _historyManifestOnlyOption ;
39
44
protected string _workloadSetVersionFromCommandLine ;
40
45
protected string _globalJsonPath ;
41
46
protected string _workloadSetVersionFromGlobalJson ;
@@ -46,10 +51,37 @@ internal abstract class InstallingWorkloadCommand : WorkloadCommandBase
46
51
protected readonly IWorkloadManifestUpdater _workloadManifestUpdaterFromConstructor ;
47
52
protected IInstaller _workloadInstaller ;
48
53
protected IWorkloadManifestUpdater _workloadManifestUpdater ;
54
+ private WorkloadHistoryState _workloadHistoryRecord ;
49
55
50
56
protected bool UseRollback => ! string . IsNullOrWhiteSpace ( _fromRollbackDefinition ) ;
57
+ protected bool FromHistory => _fromHistorySpecified != 0 ;
51
58
protected bool SpecifiedWorkloadSetVersionOnCommandLine => ! string . IsNullOrWhiteSpace ( _workloadSetVersionFromCommandLine ) ;
52
59
protected bool SpecifiedWorkloadSetVersionInGlobalJson => ! string . IsNullOrWhiteSpace ( _workloadSetVersionFromGlobalJson ) ;
60
+ protected WorkloadHistoryState _WorkloadHistoryRecord
61
+ {
62
+ get
63
+ {
64
+ if ( _workloadHistoryRecord is null && FromHistory )
65
+ {
66
+ var workloadHistoryRecords = _workloadInstaller . GetWorkloadHistoryRecords ( _sdkFeatureBand . ToString ( ) ) . OrderBy ( r => r . TimeStarted ) . ToList ( ) ;
67
+ if ( workloadHistoryRecords . Count == 0 )
68
+ {
69
+ throw new GracefulException ( Update . LocalizableStrings . NoWorkloadHistoryRecords , isUserError : true ) ;
70
+ }
71
+
72
+ var displayRecords = WorkloadHistoryDisplay . ProcessWorkloadHistoryRecords ( workloadHistoryRecords , out _ ) ;
73
+
74
+ if ( _fromHistorySpecified < 1 || _fromHistorySpecified > displayRecords . Count )
75
+ {
76
+ throw new GracefulException ( Update . LocalizableStrings . WorkloadHistoryRecordInvalidIdValue , isUserError : true ) ;
77
+ }
78
+
79
+ _workloadHistoryRecord = displayRecords [ _fromHistorySpecified - 1 ] . HistoryState ;
80
+ }
81
+
82
+ return _workloadHistoryRecord ;
83
+ }
84
+ }
53
85
54
86
public InstallingWorkloadCommand (
55
87
ParseResult parseResult ,
@@ -61,6 +93,7 @@ public InstallingWorkloadCommand(
61
93
string tempDirPath )
62
94
: base ( parseResult , reporter : reporter , tempDirPath : tempDirPath , nugetPackageDownloader : nugetPackageDownloader )
63
95
{
96
+ _arguments = parseResult . GetArguments ( ) ;
64
97
_printDownloadLinkOnly = parseResult . GetValue ( InstallingWorkloadCommandParser . PrintDownloadLinkOnlyOption ) ;
65
98
_fromCacheOption = parseResult . GetValue ( InstallingWorkloadCommandParser . FromCacheOption ) ;
66
99
_includePreviews = parseResult . GetValue ( InstallingWorkloadCommandParser . IncludePreviewOption ) ;
@@ -105,19 +138,24 @@ public InstallingWorkloadCommand(
105
138
_globalJsonPath = SdkDirectoryWorkloadManifestProvider . GetGlobalJsonPath ( Environment . CurrentDirectory ) ;
106
139
_workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider . GlobalJsonReader . GetWorkloadVersionFromGlobalJson ( _globalJsonPath ) ;
107
140
108
- if ( SpecifiedWorkloadSetVersionInGlobalJson && ( SpecifiedWorkloadSetVersionOnCommandLine || UseRollback ) )
141
+ if ( SpecifiedWorkloadSetVersionInGlobalJson && ( SpecifiedWorkloadSetVersionOnCommandLine || UseRollback || FromHistory ) )
109
142
{
110
143
throw new GracefulException ( string . Format ( Strings . CannotSpecifyVersionOnCommandLineAndInGlobalJson , _globalJsonPath ) , isUserError : true ) ;
111
144
}
112
-
113
- if ( SpecifiedWorkloadSetVersionOnCommandLine && UseRollback )
145
+ else if ( SpecifiedWorkloadSetVersionOnCommandLine && UseRollback )
114
146
{
115
147
throw new GracefulException ( string . Format ( Update . LocalizableStrings . CannotCombineOptions ,
116
148
InstallingWorkloadCommandParser . FromRollbackFileOption . Name ,
117
149
InstallingWorkloadCommandParser . WorkloadSetVersionOption . Name ) , isUserError : true ) ;
118
150
}
151
+ else if ( SpecifiedWorkloadSetVersionOnCommandLine && FromHistory )
152
+ {
153
+ throw new GracefulException ( string . Format ( Update . LocalizableStrings . CannotCombineOptions ,
154
+ InstallingWorkloadCommandParser . WorkloadSetVersionOption . Name ,
155
+ WorkloadUpdateCommandParser . FromHistoryOption . Name ) , isUserError : true ) ;
156
+ }
119
157
120
- // At this point, at most one of SpecifiedWorkloadSetVersionOnCommandLine, UseRollback, and SpecifiedWorkloadSetVersionInGlobalJson is true
158
+ // At this point, at most one of SpecifiedWorkloadSetVersionOnCommandLine, UseRollback, FromHistory, and SpecifiedWorkloadSetVersionInGlobalJson is true
121
159
}
122
160
123
161
protected static Dictionary < string , string > GetInstallStateContents ( IEnumerable < ManifestVersionUpdate > manifestVersionUpdates ) =>
@@ -141,10 +179,16 @@ public static bool ShouldUseWorkloadSetMode(SdkFeatureBand sdkFeatureBand, strin
141
179
return GetCurrentInstallState ( sdkFeatureBand , dotnetDir ) . UseWorkloadSets ?? false ;
142
180
}
143
181
144
- protected void UpdateWorkloadManifests ( ITransactionContext context , DirectoryPath ? offlineCache )
182
+ protected void UpdateWorkloadManifests ( WorkloadHistoryRecorder recorder , ITransactionContext context , DirectoryPath ? offlineCache )
145
183
{
146
- var updateToLatestWorkloadSet = ShouldUseWorkloadSetMode ( _sdkFeatureBand , _workloadRootDir ) ;
147
- if ( UseRollback && updateToLatestWorkloadSet )
184
+ var updateToLatestWorkloadSet = ShouldUseWorkloadSetMode ( _sdkFeatureBand , _workloadRootDir ) && ! SpecifiedWorkloadSetVersionInGlobalJson ;
185
+ if ( FromHistory && ! string . IsNullOrWhiteSpace ( _WorkloadHistoryRecord . WorkloadSetVersion ) )
186
+ {
187
+ // This is essentially the same as updating to a specific workload set version, and we're now past the error check,
188
+ // so we can just use the same code path.
189
+ _workloadSetVersionFromCommandLine = _WorkloadHistoryRecord . WorkloadSetVersion ;
190
+ }
191
+ else if ( ( UseRollback || FromHistory ) && updateToLatestWorkloadSet )
148
192
{
149
193
// Rollback files are only for loose manifests. Update the mode to be loose manifests.
150
194
Reporter . WriteLine ( Update . LocalizableStrings . UpdateFromRollbackSwitchesModeToLooseManifests ) ;
@@ -163,10 +207,15 @@ protected void UpdateWorkloadManifests(ITransactionContext context, DirectoryPat
163
207
{
164
208
_workloadInstaller . UpdateInstallMode ( _sdkFeatureBand , true ) ;
165
209
}
210
+
211
+ if ( SpecifiedWorkloadSetVersionInGlobalJson )
212
+ {
213
+ recorder . HistoryRecord . GlobalJsonVersion = _workloadSetVersionFromGlobalJson ;
214
+ }
166
215
}
167
216
168
217
string resolvedWorkloadSetVersion = _workloadSetVersionFromGlobalJson ?? _workloadSetVersionFromCommandLine ;
169
- if ( string . IsNullOrWhiteSpace ( resolvedWorkloadSetVersion ) && ! UseRollback )
218
+ if ( string . IsNullOrWhiteSpace ( resolvedWorkloadSetVersion ) && ! UseRollback && ! FromHistory )
170
219
{
171
220
_workloadManifestUpdater . UpdateAdvertisingManifestsAsync ( _includePreviews , updateToLatestWorkloadSet , offlineCache ) . Wait ( ) ;
172
221
if ( updateToLatestWorkloadSet )
@@ -188,7 +237,8 @@ protected void UpdateWorkloadManifests(ITransactionContext context, DirectoryPat
188
237
}
189
238
else
190
239
{
191
- manifestsToUpdate = UseRollback ? _workloadManifestUpdater . CalculateManifestRollbacks ( _fromRollbackDefinition ) :
240
+ manifestsToUpdate = UseRollback ? _workloadManifestUpdater . CalculateManifestRollbacks ( _fromRollbackDefinition , recorder ) :
241
+ FromHistory ? _workloadManifestUpdater . CalculateManifestUpdatesFromHistory ( _WorkloadHistoryRecord ) :
192
242
_workloadManifestUpdater . CalculateManifestUpdates ( ) . Select ( m => m . ManifestUpdate ) ;
193
243
}
194
244
@@ -204,9 +254,10 @@ protected void UpdateWorkloadManifests(ITransactionContext context, DirectoryPat
204
254
205
255
if ( ! SpecifiedWorkloadSetVersionInGlobalJson )
206
256
{
207
- if ( UseRollback )
257
+ if ( UseRollback || ( FromHistory && string . IsNullOrWhiteSpace ( _WorkloadHistoryRecord . WorkloadSetVersion ) ) )
208
258
{
209
259
_workloadInstaller . SaveInstallStateManifestVersions ( _sdkFeatureBand , GetInstallStateContents ( manifestsToUpdate ) ) ;
260
+ _workloadInstaller . AdjustWorkloadSetInInstallState ( _sdkFeatureBand , null ) ;
210
261
}
211
262
else if ( SpecifiedWorkloadSetVersionOnCommandLine )
212
263
{
@@ -253,17 +304,12 @@ protected void UpdateWorkloadManifests(ITransactionContext context, DirectoryPat
253
304
254
305
private IEnumerable < ManifestVersionUpdate > InstallWorkloadSet ( ITransactionContext context , string workloadSetVersion )
255
306
{
256
- PrintWorkloadSetTransition ( workloadSetVersion ) ;
307
+ Reporter . WriteLine ( string . Format ( Strings . NewWorkloadSet , workloadSetVersion ) ) ;
257
308
var workloadSet = _workloadInstaller . InstallWorkloadSet ( context , workloadSetVersion ) ;
258
309
259
310
return _workloadManifestUpdater . CalculateManifestUpdatesForWorkloadSet ( workloadSet ) ;
260
311
}
261
312
262
- private void PrintWorkloadSetTransition ( string newVersion )
263
- {
264
- Reporter . WriteLine ( string . Format ( Strings . NewWorkloadSet , newVersion ) ) ;
265
- }
266
-
267
313
protected async Task < List < WorkloadDownload > > GetDownloads ( IEnumerable < WorkloadId > workloadIds , bool skipManifestUpdate , bool includePreview , string downloadFolder = null ,
268
314
IReporter reporter = null , INuGetPackageDownloader packageDownloader = null )
269
315
{
0 commit comments