Skip to content

Commit 3e23e22

Browse files
authored
Merge pull request #97 from sfoslund/VS4MacVersionProtection
Visual Studio for Mac version protection
2 parents 1f74396 + 86ad67a commit 3e23e22

21 files changed

+787
-349
lines changed

src/dotnet-core-uninstall/LocalizableStrings.Designer.cs

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

src/dotnet-core-uninstall/LocalizableStrings.resx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,21 +320,32 @@ Uninstalling this item will cause Visual Studio to break.
320320
<data name="UpperLimitRequirement" xml:space="preserve">
321321
<value>Cannot uninstall version {0} and above</value>
322322
</data>
323-
<data name="RequirementExplainationString" xml:space="preserve">
323+
<data name="WindowsRequirementExplainationString" xml:space="preserve">
324324
<value>Maybe needed for Visual Studio{0}. Specify individually or use —-force to remove</value>
325325
</data>
326326
<data name="ForceOptionDescriptionWindows" xml:space="preserve">
327327
<value>Force removal of versions that might be used by Visual Studio.</value>
328328
</data>
329329
<data name="ForceOptionDescriptionMac" xml:space="preserve">
330-
<value>Force removal of versions that might be used by Visual Studio or SDK.</value>
330+
<value>Force removal of versions that might be used by Visual Studio for Mac or SDKs.</value>
331331
</data>
332-
<data name="ListCommandOutput" xml:space="preserve">
332+
<data name="WindowsListCommandOutput" xml:space="preserve">
333333
<value>
334334
This tool can not uninstall versions of the runtime or SDK that are installed using Visual Studio 2019 Update 3 or via zip/scripts. The versions that can be uninstalled with this tool are:
335335
</value>
336336
</data>
337337
<data name="UninstallNoOptionDescriptionMac" xml:space="preserve">
338338
<value>Remove specified .NET Core SDKs or Runtimes. This tool can only uninstall items that were installed using Visual Studio, .NET Core SDK, or Runtime installers. By default, this tool does not uninstall versions that might be needed for Visual Studio or SDKs. Read the documentation for the .NET Core Uninstall Tool at https://aka.ms/dotnet-core-uninstall.</value>
339339
</data>
340+
<data name="MacRuntimeRequirementExplainationString" xml:space="preserve">
341+
<value>Maybe needed for Visual Studio for Mac or SDKs. Specify individually or use —-force to remove</value>
342+
</data>
343+
<data name="MacSDKRequirementExplainationString" xml:space="preserve">
344+
<value>Maybe needed for Visual Studio for Mac. Specify individually or use —-force to remove</value>
345+
</data>
346+
<data name="MacListCommandOutput" xml:space="preserve">
347+
<value>
348+
This tool can not uninstall versions of the runtime or SDK that are installed using zip/scripts. The versions that can be uninstalled with this tool are:
349+
</value>
350+
</data>
340351
</root>

src/dotnet-core-uninstall/Shared/Commands/CommandBundleFilter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.CommandLine;
1212
using Microsoft.DotNet.Tools.Uninstall.Shared.VSVersioning;
1313
using NuGet.Versioning;
14-
using Microsoft.DotNet.Tools.Uninstall.Shared.Configs.Verbosity;
1514

1615
namespace Microsoft.DotNet.Tools.Uninstall.Shared.Commands
1716
{

src/dotnet-core-uninstall/Shared/Commands/ListCommandExec.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ private static void Execute(
4141
IEnumerable<Bundle> bundles,
4242
IEnumerable<BundleTypePrintInfo> supportedBundleTypes)
4343
{
44-
Console.WriteLine(LocalizableStrings.ListCommandOutput);
44+
Console.WriteLine(RuntimeInfo.RunningOnWindows ? LocalizableStrings.WindowsListCommandOutput : LocalizableStrings.MacListCommandOutput);
4545

4646
var listCommandParseResult = CommandLineConfigs.ListCommand.Parse(Environment.GetCommandLineArgs());
4747

src/dotnet-core-uninstall/Shared/Configs/CommandLineConfigs.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.CommandLine;
4+
using System.CommandLine.Builder;
45
using System.CommandLine.Invocation;
56
using System.Linq;
67
using Microsoft.DotNet.Tools.Uninstall.Shared.BundleInfo;
@@ -227,7 +228,9 @@ static CommandLineConfigs()
227228
DryRunCommand.Handler = CommandHandler.Create(ExceptionHandler.HandleException(() => DryRunCommandExec.Execute()));
228229
RemoveCommand.Handler = CommandHandler.Create(ExceptionHandler.HandleException(() => UninstallCommandExec.Execute()));
229230

230-
CommandLineParseResult = UninstallRootCommand.Parse(Environment.GetCommandLineArgs());
231+
var parser = new CommandLineBuilder(UninstallRootCommand)
232+
.Build();
233+
CommandLineParseResult = parser.Parse(Environment.GetCommandLineArgs());
231234
}
232235

233236
public static Option GetUninstallMainOption(this CommandResult commandResult)

src/dotnet-core-uninstall/Shared/VSVersioning/VisualStudioSafeVersionsExtractor.cs

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ internal static class VisualStudioSafeVersionsExtractor
1414

1515
// Must keep one of each of these divisions to ensure Visual Studio works.
1616
// Pairs are [inclusive, exclusive)
17-
private static readonly Dictionary<(SemanticVersion, SemanticVersion), string> VersionDivisionsToExplaination = new Dictionary<(SemanticVersion, SemanticVersion), string>
17+
private static readonly Dictionary<(SemanticVersion, SemanticVersion), string> WindowsVersionDivisionsToExplaination = new Dictionary<(SemanticVersion, SemanticVersion), string>
1818
{
19-
{ (new SemanticVersion(1, 0, 0), new SemanticVersion(2, 0, 0)), string.Format(LocalizableStrings.RequirementExplainationString, "") },
20-
{ (new SemanticVersion(2, 0, 0), new SemanticVersion(2, 1, 300)), string.Format(LocalizableStrings.RequirementExplainationString, "") },
21-
{ (new SemanticVersion(2, 1, 300), new SemanticVersion(2, 1, 600)), string.Format(LocalizableStrings.RequirementExplainationString, " 2017") },
22-
{ (new SemanticVersion(2, 1, 600), new SemanticVersion(2, 1, 900)), string.Format(LocalizableStrings.RequirementExplainationString, " 2019") },
23-
{ (new SemanticVersion(2, 2, 100), new SemanticVersion(2, 2, 200)), string.Format(LocalizableStrings.RequirementExplainationString, " 2017") },
24-
{ (new SemanticVersion(2, 2, 200), new SemanticVersion(2, 2, 500)), string.Format(LocalizableStrings.RequirementExplainationString, " 2019") },
25-
{ (new SemanticVersion(2, 2, 500), UpperLimit), string.Format(LocalizableStrings.RequirementExplainationString, "") }
19+
{ (new SemanticVersion(1, 0, 0), new SemanticVersion(2, 0, 0)), string.Format(LocalizableStrings.WindowsRequirementExplainationString, "") },
20+
{ (new SemanticVersion(2, 0, 0), new SemanticVersion(2, 1, 300)), string.Format(LocalizableStrings.WindowsRequirementExplainationString, "") },
21+
{ (new SemanticVersion(2, 1, 300), new SemanticVersion(2, 1, 600)), string.Format(LocalizableStrings.WindowsRequirementExplainationString, " 2017") },
22+
{ (new SemanticVersion(2, 1, 600), new SemanticVersion(2, 1, 900)), string.Format(LocalizableStrings.WindowsRequirementExplainationString, " 2019") },
23+
{ (new SemanticVersion(2, 2, 100), new SemanticVersion(2, 2, 200)), string.Format(LocalizableStrings.WindowsRequirementExplainationString, " 2017") },
24+
{ (new SemanticVersion(2, 2, 200), new SemanticVersion(2, 2, 500)), string.Format(LocalizableStrings.WindowsRequirementExplainationString, " 2019") },
25+
{ (new SemanticVersion(2, 2, 500), UpperLimit), string.Format(LocalizableStrings.WindowsRequirementExplainationString, "") }
2626
};
2727

28-
private static (IDictionary<IEnumerable<Bundle>, string>, IEnumerable<Bundle>) ApplyVersionDivisions(IEnumerable<Bundle> bundleList)
28+
private static (IDictionary<IEnumerable<Bundle>, string>, IEnumerable<Bundle>) ApplyWindowsVersionDivisions(IEnumerable<Bundle> bundleList)
2929
{
3030
var dividedBundles = new Dictionary<IEnumerable<Bundle>, string>();
31-
foreach (var (division, explaination) in VersionDivisionsToExplaination)
31+
foreach (var (division, explaination) in WindowsVersionDivisionsToExplaination)
3232
{
3333
var bundlesInRange = bundleList.Where(bundle => bundle.Version is SdkVersion && division.Item1 <= bundle.Version.SemVer && bundle.Version.SemVer < division.Item2);
3434
bundleList = bundleList.Except(bundlesInRange);
@@ -41,13 +41,43 @@ private static (IDictionary<IEnumerable<Bundle>, string>, IEnumerable<Bundle>) A
4141
return (dividedBundles, bundleList);
4242
}
4343

44-
public static IEnumerable<Bundle> GetUninstallableBundles(IEnumerable<Bundle> bundles)
44+
private static (IDictionary<IEnumerable<Bundle>, string>, IEnumerable<Bundle>) ApplyMacVersionDivisions(IEnumerable<Bundle> bundleList)
4545
{
46-
if (!RuntimeInfo.RunningOnWindows)
46+
var bundlesAboveLimit = bundleList.Where(bundle => bundle.Version.SemVer >= UpperLimit);
47+
bundleList = bundleList.Except(bundlesAboveLimit);
48+
49+
var dividedBundles = bundleList
50+
.Where(bundle => bundle.Version is RuntimeVersion)
51+
.GroupBy(bundle => bundle.Version.MajorMinor)
52+
.Select(pair => (pair as IEnumerable<Bundle>, LocalizableStrings.MacRuntimeRequirementExplainationString))
53+
.ToDictionary(key => key.Item1, value => value.Item2);
54+
55+
var sdks = bundleList.Where(bundle => bundle.Version is SdkVersion);
56+
if (sdks != null && sdks.Count() > 0)
4757
{
48-
return bundles;
58+
dividedBundles.Add(sdks, LocalizableStrings.MacSDKRequirementExplainationString);
4959
}
5060

61+
var remainingBundles = bundleList
62+
.Where(bundle => !(bundle.Version is RuntimeVersion || bundle.Version is SdkVersion))
63+
.Concat(bundlesAboveLimit);
64+
return (dividedBundles, remainingBundles);
65+
}
66+
67+
private static (IDictionary<IEnumerable<Bundle>, string>, IEnumerable<Bundle>) ApplyVersionDivisions(IEnumerable<Bundle> bundles)
68+
{
69+
if (RuntimeInfo.RunningOnWindows)
70+
{
71+
return ApplyWindowsVersionDivisions(bundles);
72+
}
73+
else
74+
{
75+
return ApplyMacVersionDivisions(bundles);
76+
}
77+
}
78+
79+
public static IEnumerable<Bundle> GetUninstallableBundles(IEnumerable<Bundle> bundles)
80+
{
5181
var required = new List<Bundle>();
5282
var (bundlesByDivisions, remainingBundles) = ApplyVersionDivisions(bundles);
5383

@@ -63,12 +93,6 @@ public static IEnumerable<Bundle> GetUninstallableBundles(IEnumerable<Bundle> bu
6393

6494
public static Dictionary<Bundle, string> GetReasonRequiredStrings(IEnumerable<Bundle> allBundles)
6595
{
66-
if (!RuntimeInfo.RunningOnWindows)
67-
{
68-
return allBundles.Select(bundle => (bundle, string.Empty))
69-
.ToDictionary(i => i.bundle, i => i.Item2);
70-
}
71-
7296
var (bundlesByDivisions, remainingBundles) = ApplyVersionDivisions(allBundles);
7397

7498
var bundlesAboveUpperLimit = remainingBundles.Where(bundle => bundle.Version.SemVer >= UpperLimit);

0 commit comments

Comments
 (0)