forked from dotnet/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ShowMissingWorkloads.cs
100 lines (85 loc) · 4.61 KB
/
ShowMissingWorkloads.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Globalization;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.DotNet.Configurer;
using Microsoft.NET.Sdk.WorkloadManifestReader;
using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver;
namespace Microsoft.NET.Build.Tasks
{
public class ShowMissingWorkloads : TaskBase
{
private static readonly string MauiCrossPlatTopLevelVSWorkloads = "Microsoft.VisualStudio.Workload.NetCrossPlat";
private static readonly string MauiComponentGroupVSWorkload = "Microsoft.VisualStudio.ComponentGroup.Maui.All";
private static readonly string WasmTopLevelVSWorkload = "Microsoft.VisualStudio.Workload.NetWeb";
private static readonly HashSet<string> MauiWorkloadIds = new(StringComparer.OrdinalIgnoreCase)
{ "android", "android-aot", "ios", "maccatalyst", "macos", "maui", "maui-android",
"maui-desktop", "maui-ios", "maui-maccatalyst", "maui-mobile", "maui-windows", "tvos" };
private static readonly HashSet<string> WasmWorkloadIds = new(StringComparer.OrdinalIgnoreCase)
{ "wasm-tools", "wasm-tools-net6", "wasm-tools-net7" };
public ITaskItem[] MissingWorkloadPacks { get; set; }
public string NetCoreRoot { get; set; }
public string NETCoreSdkVersion { get; set; }
public bool GenerateErrorsForMissingWorkloads { get; set; }
[Output]
public ITaskItem[] SuggestedWorkloads { get; set; }
protected override void ExecuteCore()
{
if (MissingWorkloadPacks.Any())
{
string? userProfileDir = CliFolderPathCalculatorCore.GetDotnetUserProfileFolderPath();
// 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 = Create(workloadManifestProvider, NetCoreRoot, NETCoreSdkVersion, userProfileDir);
var suggestedWorkloads = workloadResolver.GetWorkloadSuggestionForMissingPacks(
MissingWorkloadPacks.Select(item => new WorkloadPackId(item.ItemSpec)).ToList(),
out ISet<WorkloadPackId> unsatisfiablePacks
);
if (GenerateErrorsForMissingWorkloads)
{
if (suggestedWorkloads is not null)
{
var errorMessage = string.Format(CultureInfo.CurrentCulture,
Strings.WorkloadNotInstalled, string.Join(" ", suggestedWorkloads.Select(w => w.Id)));
Log.LogError(errorMessage);
}
else
{
Log.LogError(Strings.WorkloadNotAvailable, string.Join(" ", unsatisfiablePacks));
}
}
if (suggestedWorkloads is not null)
{
SuggestedWorkloads = suggestedWorkloads.Select(suggestedWorkload =>
{
var suggestedWorkloadsList = GetSuggestedWorkloadsList(suggestedWorkload);
var taskItem = new TaskItem(suggestedWorkload.Id);
taskItem.SetMetadata("VisualStudioComponentId", ToSafeId(suggestedWorkload.Id));
taskItem.SetMetadata("VisualStudioComponentIds", string.Join(";", suggestedWorkloadsList));
return taskItem;
}).ToArray();
}
}
}
internal static string ToSafeId(string id)
{
return id.Replace("-", ".").Replace(" ", ".").Replace("_", ".");
}
private static IEnumerable<string> GetSuggestedWorkloadsList(WorkloadInfo workloadInfo)
{
yield return ToSafeId(workloadInfo.Id);
if (MauiWorkloadIds.Contains(workloadInfo.Id.ToString()))
{
yield return MauiCrossPlatTopLevelVSWorkloads;
yield return MauiComponentGroupVSWorkload;
}
if (WasmWorkloadIds.Contains(workloadInfo.Id.ToString()))
{
yield return WasmTopLevelVSWorkload;
}
}
}
}