Skip to content

Commit

Permalink
Add support for --first to all relevant commands
Browse files Browse the repository at this point in the history
It's quite common to want to operate on the first match for a given VS selection (i.e. whichever VS is the first that's greater or equal to `16.8`, say). So add an option to automatically select the first match, if any.
  • Loading branch information
kzu committed Nov 20, 2020
1 parent 9093d5a commit d7503af
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 9 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ Usage: vs where [options]
| `int\|internal` | show internal (aka 'dogfood') version |
| `sku:` | Edition, one of `e\|ent\|enterprise`, `p\|pro\|professional`, `c\|com\|community` `b\|build\|buildtools` or `t\|test\|testagent` |
| `filter:` | An expression to filter VS instances. E.g. `x => x.InstanceId = '123'` |
| `first` | show first matching instance. |
| `all` | show all instances. |
| `prop\|property:` | The name of a property to return |
| `requires:` | A workload ID |
Expand Down Expand Up @@ -189,7 +190,7 @@ Usage: vs update [options]
| `int\|internal` | Update internal (aka 'dogfood') version |
| `sku:` | Edition, one of `e\|ent\|enterprise`, `p\|pro\|professional`, `c\|com\|community` `b\|build\|buildtools` or `t\|test\|testagent` |
| `filter:` | An expression to filter VS instances. E.g. `x => x.InstanceId = '123'` |
'123'` |
| `first` | Update first matching instance. |


Examples:
Expand All @@ -211,6 +212,7 @@ Usage: vs modify [options]
| `int\|internal` | modify internal (aka 'dogfood') version |
| `sku:` | Edition, one of `e\|ent\|enterprise`, `p\|pro\|professional`, `c\|com\|community` `b\|build\|buildtools` or `t\|test\|testagent` |
| `filter:` | An expression to filter VS instances. E.g. `x => x.InstanceId = '123'` |
| `first` | Modify first matching instance. |
| `add:` | A workload ID |
| `remove:` | A workload ID |

Expand All @@ -234,6 +236,7 @@ Usage: vs config [options]
| `int\|internal` | open internal (aka 'dogfood') version |
| `sku:` | Edition, one of `e\|ent\|enterprise`, `p\|pro\|professional`, `c\|com\|community` `b\|build\|buildtools` or `t\|test\|testagent` |
| `filter:` | An expression to filter VS instances. E.g. `x => x.InstanceId = '123'` |
| `first` | Use first matching VS instance. |
| `exp\|experimental` | open experimental instance instead of regular. |


Expand All @@ -256,6 +259,7 @@ Usage: vs log [options]
| `int\|internal` | open internal (aka 'dogfood') version |
| `sku:` | Edition, one of `e\|ent\|enterprise`, `p\|pro\|professional`, `c\|com\|community` `b\|build\|buildtools` or `t\|test\|testagent` |
| `filter:` | An expression to filter VS instances. E.g. `x => x.InstanceId = '123'` |
| `first` | Use first matching VS instance. |
| `exp\|experimental` | open experimental instance instead of regular. |


Expand All @@ -279,6 +283,7 @@ Usage: vs kill [options]
| `sku:` | Edition, one of `e\|ent\|enterprise`, `p\|pro\|professional`, `c\|com\|community` `b\|build\|buildtools` or `t\|test\|testagent` |
| `filter:` | An expression to filter VS instances. E.g. `x => x.InstanceId = '123'` |
| `exp\|experimental` | kill experimental instance instead of regular. |
| `first` | kill first matching instance. |
| `all` | kill all instances. |


Expand Down
14 changes: 14 additions & 0 deletions VisualStudio.Tests/VisualStudioOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ public void when_parsing_all_argument_then_all_is_set(string argument, bool expe
Assert.Equal(expectedValue, options.All);
}

[Theory]
[InlineData("", false)]
[InlineData("first", true)]
[InlineData("First", true)]
[InlineData("--first", true)]
public void when_parsing_first_argument_then_first_is_set(string argument, bool expectedValue)
{
var options = VisualStudioOptions.Empty().WithFirst();

options.Parse(new[] { argument });

Assert.Equal(expectedValue, options.First);
}

static (string[] Arguments, Func<VisualStudioOptions, bool> VerifyResult)[] TestCases =>
new (string[] Arguments, Func<VisualStudioOptions, bool> VerifyResult)[]
{
Expand Down
4 changes: 3 additions & 1 deletion VisualStudio/Commands/ClientCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace VisualStudio
{
class ClientCommandDescriptor : CommandDescriptor
{
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("Run").WithExperimental();
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("Run")
.WithFirst()
.WithExperimental();
readonly ClientOptions clientOptions = new ClientOptions();

public ClientCommandDescriptor()
Expand Down
4 changes: 3 additions & 1 deletion VisualStudio/Commands/ConfigCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace VisualStudio
{
class ConfigCommandDescriptor : CommandDescriptor
{
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("open").WithExperimental();
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("open")
.WithFirst()
.WithExperimental();

public ConfigCommandDescriptor()
{
Expand Down
5 changes: 4 additions & 1 deletion VisualStudio/Commands/KillCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ namespace VisualStudio
{
class KillCommandDescriptor : CommandDescriptor
{
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("kill").WithExperimental().WithSelectAll();
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("kill")
.WithExperimental()
.WithFirst()
.WithSelectAll();

public KillCommandDescriptor()
{
Expand Down
4 changes: 3 additions & 1 deletion VisualStudio/Commands/LogCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace VisualStudio
{
class LogCommandDescriptor : CommandDescriptor
{
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("open").WithExperimental();
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("open")
.WithFirst()
.WithExperimental();

public LogCommandDescriptor()
{
Expand Down
5 changes: 4 additions & 1 deletion VisualStudio/Commands/ModifyCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ class ModifyCommandDescriptor : CommandDescriptor
public ModifyCommandDescriptor()
{
Description = "Modifies an installation of Visual Studio.";
Options = VisualStudioOptions.Default("modify").With(addWorkloads).With(removeWorkloads);
Options = VisualStudioOptions.Default("modify")
.WithFirst()
.With(addWorkloads)
.With(removeWorkloads);
}

public ImmutableArray<string> WorkloadsAdded => addWorkloads.Value;
Expand Down
4 changes: 3 additions & 1 deletion VisualStudio/Commands/UpdateCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace VisualStudio
{
class UpdateCommandDescriptor : CommandDescriptor
{
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("Update").WithSelectAll();
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("Update")
.WithFirst()
.WithSelectAll();

public UpdateCommandDescriptor()
{
Expand Down
2 changes: 1 addition & 1 deletion VisualStudio/Commands/WhereCommandDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace VisualStudio
{
class WhereCommandDescriptor : CommandDescriptor
{
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("show");
readonly VisualStudioOptions vsOptions = VisualStudioOptions.Default("show").WithFirst();
readonly SelectPropertyOption propOption = new SelectPropertyOption();
readonly ListOption listOption = new ListOption();
readonly WorkloadOptions workloads = new WorkloadOptions("requires", "--", "-");
Expand Down
21 changes: 21 additions & 0 deletions VisualStudio/Options/FirstOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using Mono.Options;

namespace VisualStudio
{
class FirstOption : OptionSet<bool>
{
public FirstOption(string verb)
{
Add("first", $"{verb} first matching instance.", e => Value = e != null);
}

protected override bool Parse(string argument, OptionContext c)
{
if ("first".Equals(argument, StringComparison.OrdinalIgnoreCase))
argument = "--first";

return base.Parse(argument, c);
}
}
}
4 changes: 4 additions & 0 deletions VisualStudio/Options/VisualStudioOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public static VisualStudioOptions Default(string verb = DefaultVerb) =>

public VisualStudioOptions WithFilter() => new VisualStudioOptions(verb, options.With(new FilterOption()));

public VisualStudioOptions WithFirst() => new VisualStudioOptions(verb, options.With(new FirstOption(verb)));

public VisualStudioOptions WithSelectAll() => new VisualStudioOptions(verb, options.With(new SelectAllOption(verb)));

public VisualStudioOptions WithNickname() => new VisualStudioOptions(verb, options.With(new NicknameOption()));
Expand All @@ -55,6 +57,8 @@ public static VisualStudioOptions Default(string verb = DefaultVerb) =>

public bool All => GetValue<SelectAllOption, bool>();

public bool First => GetValue<FirstOption, bool>();

public string Nickname => GetValue<NicknameOption, string>();

public IOptions With(OptionSet optionSet) => new VisualStudioOptions(verb, options.With(optionSet));
Expand Down
7 changes: 6 additions & 1 deletion VisualStudio/WhereService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ public async Task<IEnumerable<VisualStudioInstance>> GetAllInstancesAsync(IOptio
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});

return instances.Where(await new VisualStudioPredicateBuilder().BuildPredicateAsync(options));
var result = instances.Where(await new VisualStudioPredicateBuilder().BuildPredicateAsync(options));

if (options.GetValue<FirstOption, bool>())
return result.Take(1);

return result;
}

public void ShowUsage(ITextWriter output)
Expand Down

0 comments on commit d7503af

Please sign in to comment.