Skip to content

Commit 2e2c56a

Browse files
committed
Add support for updating/modifying Build Tools and other installed builds
Instead of supporting a fixed list of channels used in our internal well-known list, also support arbitrary channels for cases where we can readily inspect their URI, such as for modify and update commands. This allows us to update/modify even 2017 SKUs, or branch builds.
1 parent e5da6f6 commit 2e2c56a

7 files changed

+40
-23
lines changed

src/VisualStudio.Tests/VisualStudioInstanceExtensions.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using VisualStudio;
34

45
namespace vswhere
@@ -30,7 +31,10 @@ public static VisualStudioInstance WithSku(this VisualStudioInstance vsInstance,
3031

3132
public static VisualStudioInstance WithChannel(this VisualStudioInstance vsInstance, Channel channel)
3233
{
33-
vsInstance.ChannelId = productIdByChannel[channel];
34+
vsInstance.ChannelId = productIdByChannel.TryGetValue(channel, out var channelId) ?
35+
vsInstance.ChannelId = channelId :
36+
throw new NotSupportedException("Cannot filter instances by the given channel.");
37+
3438
return vsInstance;
3539
}
3640
}

src/VisualStudio.Tests/VisualStudioPredicateBuilderTests.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Threading.Tasks;
1+
using System;
2+
using System.Threading.Tasks;
23
using vswhere;
34
using Xunit;
45

src/VisualStudio/Channel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ public enum Channel
55
Release,
66
Preview,
77
IntPreview,
8-
Main
8+
Main,
99
}
1010
}

src/VisualStudio/Commands/ModifyCommand.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ public override async Task ExecuteAsync(TextWriter output)
3939

4040
args.AddRange(Descriptor.ExtraArguments);
4141

42-
await installerService.ModifyAsync(instance.GetChannel(), instance.GetSku(), args, output);
42+
// If the channel is not a built-in one, use the existing Uri for updates.
43+
var channel = instance.GetChannel();
44+
if (channel != null)
45+
await installerService.ModifyAsync(instance.GetChannel(), instance.GetSku(), args, output);
46+
else
47+
await installerService.ModifyAsync(instance.ChannelUri.Replace("/channel", ""), instance.GetSku(), args, output);
4348
}
4449
}
4550
}

src/VisualStudio/Commands/UpdateCommand.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ public override async Task ExecuteAsync(TextWriter output)
3939
instance.InstallationPath
4040
};
4141

42-
await installerService.UpdateAsync(instance.GetChannel(), instance.GetSku(), args, output);
42+
// If the channel is not a built-in one, use the existing Uri for updates.
43+
var channel = instance.GetChannel();
44+
if (channel != null)
45+
await installerService.UpdateAsync(instance.GetChannel(), instance.GetSku(), args, output);
46+
else
47+
await installerService.UpdateAsync(instance.ChannelUri.Replace("/channel", ""), instance.GetSku(), args, output);
4348
}
4449
}
4550
}

src/VisualStudio/InstallerService.cs

+17-15
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,33 @@
44
using System.IO;
55
using System.Linq;
66
using System.Net.Http;
7-
using System.Text;
87
using System.Threading.Tasks;
98

109
namespace VisualStudio
1110
{
1211
class InstallerService
1312
{
14-
public Task InstallAsync(Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output) =>
15-
RunAsync(string.Empty, channel, sku, args, output);
13+
public Task InstallAsync(Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output)
14+
=> RunAsync(string.Empty, channel, sku, args, output);
1615

17-
public Task UpdateAsync(Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output) =>
18-
RunAsync("update", channel, sku, args, output);
16+
public Task UpdateAsync(Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output)
17+
=> RunAsync("update", channel, sku, args, output);
1918

20-
public Task ModifyAsync(Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output) =>
21-
RunAsync("modify", channel, sku, args, output);
19+
public Task ModifyAsync(Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output)
20+
=> RunAsync("modify", channel, sku, args, output);
2221

23-
async Task RunAsync(string command, Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output)
24-
{
25-
var uri = new StringBuilder("https://aka.ms/vs/16/");
26-
uri = uri.Append(MapChannel(channel));
27-
uri = uri.Append("/vs_");
28-
uri = uri.Append(MapSku(sku));
29-
uri = uri.Append(".exe");
22+
public Task UpdateAsync(string channelUri, Sku? sku, IEnumerable<string> args, TextWriter output)
23+
=> RunAsync("update", channelUri, sku, args, output);
24+
25+
public Task ModifyAsync(string channelUri, Sku? sku, IEnumerable<string> args, TextWriter output)
26+
=> RunAsync("modify", channelUri, sku, args, output);
3027

31-
var bootstrapper = await DownloadAsync(uri.ToString(), output);
28+
Task RunAsync(string command, Channel? channel, Sku? sku, IEnumerable<string> args, TextWriter output)
29+
=> RunAsync(command, "https://aka.ms/vs/16/" + MapChannel(channel), sku, args, output);
30+
31+
async Task RunAsync(string command, string channelUri, Sku? sku, IEnumerable<string> args, TextWriter output)
32+
{
33+
var bootstrapper = await DownloadAsync($"{channelUri}/vs_{MapSku(sku)}.exe", output);
3234

3335
var psi = new ProcessStartInfo(bootstrapper)
3436
{

src/VisualStudio/VisualStudioInstanceExtensions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public static Sku GetSku(this VisualStudioInstance vsInstance)
1717
_ => throw new ArgumentException($"Invalid SKU {vsInstance.ProductId}. Must be one of {string.Join(", ", Enum.GetNames(typeof(Sku)).Select(x => x.ToLowerInvariant()))}.", "sku"),
1818
};
1919

20-
public static Channel GetChannel(this VisualStudioInstance vsInstance)
20+
public static Channel? GetChannel(this VisualStudioInstance vsInstance)
2121
=> vsInstance.ChannelId switch
2222
{
2323
"VisualStudio.16.Release" => Channel.Release,
2424
"VisualStudio.16.Preview" => Channel.Preview,
2525
"VisualStudio.16.IntPreview" => Channel.IntPreview,
2626
"VisualStudio.16.int.main" => Channel.Main,
27-
_ => throw new ArgumentException($"Invalid ChannelId {vsInstance.ChannelId}. Must be one of {string.Join(", ", Enum.GetNames(typeof(Channel)).Select(x => x.ToLowerInvariant()))}.", "sku"),
27+
_ => null,
2828
};
2929
}
3030
}

0 commit comments

Comments
 (0)