Skip to content

Commit f528cc9

Browse files
committed
update System.CommandLine
1 parent 63e3113 commit f528cc9

29 files changed

+872
-553
lines changed

Directory.Packages.props

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
<PropertyGroup>
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
5-
65
<RoslynVersion>4.14.0</RoslynVersion>
76
</PropertyGroup>
87
<PropertyGroup Label="Properties used for generating package references (#r nuget) at runtime. Inlining these might cause some tests to fail.">
98
<HumanizerVersion>2.14.1</HumanizerVersion>
109
<MicrosoftDataSqlClientVersion>6.0.2</MicrosoftDataSqlClientVersion>
11-
<MicrosoftIdentityClientVersion>4.66.2</MicrosoftIdentityClientVersion>
10+
<MicrosoftIdentityClientVersion>4.66.1</MicrosoftIdentityClientVersion>
1211
<MicrosoftEntityFrameworkVersion>9.0.5</MicrosoftEntityFrameworkVersion>
1312
</PropertyGroup>
1413
<ItemGroup>
@@ -84,8 +83,7 @@
8483
<PackageVersion Include="SkiaSharp" Version="2.88.6" />
8584
<PackageVersion Include="StreamJsonRpc" Version="2.21.69" />
8685
<PackageVersion Include="System.Collections.Immutable" Version="9.0.5" />
87-
<PackageVersion Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.22272.1" />
88-
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.25121.105" />
86+
<PackageVersion Include="System.CommandLine" Version="2.0.0-rc.1.25413.101" />
8987
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
9088
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.5" />
9189
<PackageVersion Include="System.Drawing.Common" Version="9.0.5" />

NuGet.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<clear />
88
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
99
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
10+
<add key="dotnet-libraries" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
1011
</packageSources>
1112
<packageSourceMapping>
1213
<packageSource key="dotnet-eng">
@@ -22,6 +23,9 @@
2223
<package pattern="Microsoft.SymbolUploader.Build.Task" />
2324
<package pattern="sn" />
2425
</packageSource>
26+
<packageSource key="dotnet-libraries">
27+
<package pattern="System.CommandLine" />
28+
</packageSource>
2529
<packageSource key="dotnet-public">
2630
<package pattern="*" />
2731
</packageSource>

src/Microsoft.DotNet.Interactive.CSharpProject.Tests/(Recipes)/MarkupTestFileFacts.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ public void GetPosition_Should_Return_String_Without_Dollar_Signs()
2424
public void GetPosition_Should_Return_Correct_Position()
2525
{
2626
var input = "some$$string";
27-
string output;
28-
MarkupTestFile.GetPosition(input, out output, out var position);
27+
MarkupTestFile.GetPosition(input, out var output, out var position);
2928
Assert.Equal(4, position);
3029
}
3130

src/Microsoft.DotNet.Interactive.SqlServer/DependencyVersions.g.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ internal static class DependencyVersions
66
public const string HumanizerVersion = "2.14.1";
77
public const string MicrosoftDataSqlClientVersion = "6.0.2";
88
public const string MicrosoftEntityFrameworkVersion = "9.0.5";
9-
public const string MicrosoftIdentityClientVersion = "4.66.2";
9+
public const string MicrosoftIdentityClientVersion = "4.66.1";
1010
}

src/Microsoft.DotNet.Interactive.Telemetry/StartupTelemetryEventBuilder.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public IEnumerable<TelemetryEvent> GetTelemetryEventsFrom(ParseResult parseResul
8080

8181
var commandResult = parseResult.CommandResult;
8282

83-
var frontendName = GetFrontendName(parseResult.Directives, parseResult.CommandResult);
83+
var frontendName = GetFrontendName(parseResult, parseResult.CommandResult);
8484
entryItems.Add(new KeyValuePair<string, string>("frontend", frontendName));
8585

8686
foreach (var item in rule.Items)
@@ -94,7 +94,10 @@ public IEnumerable<TelemetryEvent> GetTelemetryEventsFrom(ParseResult parseResul
9494
switch (item)
9595
{
9696
case OptionItem optItem:
97-
var optionValue = commandResult.Children.OfType<OptionResult>().FirstOrDefault(o => o.Option.HasAlias(optItem.Option))?.GetValueOrDefault()?.ToString();
97+
var optionResult = commandResult.Children.OfType<OptionResult>().FirstOrDefault(o => o.Option.Name == optItem.Option);
98+
99+
var optionValue = optionResult?.GetValue<object>(optItem.Option)?.ToString();
100+
98101
if (optionValue is not null && optItem.Values.Contains(optionValue))
99102
{
100103
entryItems.Add(new KeyValuePair<string, string>(optItem.EntryKey, optionValue));
@@ -259,23 +262,23 @@ private static CommandRuleItem Ignore(TokenType type, bool isOptional)
259262
};
260263

261264
private static string GetFrontendName(
262-
DirectiveCollection directives,
265+
ParseResult parseResult,
263266
CommandResult commandResult)
264267
{
265268
if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("CODESPACES")))
266269
{
267270
return "gitHubCodeSpaces";
268271
}
269272

270-
foreach (var directive in directives)
273+
foreach (var directive in parseResult.Tokens.Where(t => t is { Type: TokenType.Directive }))
271274
{
272-
switch (directive.Key)
275+
switch (directive.Value)
273276
{
274-
case "jupyter":
275-
case "synapse":
276-
case "vscode":
277-
case "vs":
278-
return directive.Key;
277+
case "[jupyter]":
278+
case "[synapse]":
279+
case "[vscode]":
280+
case "[vs]":
281+
return directive.Value.Trim('[', ']');
279282
}
280283
}
281284

src/Microsoft.DotNet.Interactive.Telemetry/TelemetrySender.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.CommandLine;
67
using System.CommandLine.Parsing;
78
using System.Diagnostics;
89
using System.Reflection;

src/Microsoft.DotNet.Interactive/KernelHost.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ internal KernelHost(
4141
_kernel = kernel;
4242
_defaultSender = sender;
4343
_receiver = receiver;
44-
_defaultConnector = async (name) =>
44+
_defaultConnector = async name =>
4545
{
4646
var connector = new DefaultKernelConnector(
4747
_defaultSender,
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.CommandLine;
4+
using System.Linq;
5+
using Microsoft.DotNet.Interactive.App.Tests.Extensions;
6+
7+
namespace Microsoft.DotNet.Interactive.App.Tests.CommandLine;
8+
9+
public static class CommandExtensions
10+
{
11+
/// <summary>
12+
/// Throws an exception if the parser configuration is ambiguous or otherwise not valid.
13+
/// </summary>
14+
/// <remarks>Due to the performance cost of this method, it is recommended to be used in unit testing or in scenarios where the parser is configured dynamically at runtime.</remarks>
15+
/// <exception cref="InvalidOperationException">Thrown if the configuration is found to be invalid.</exception>
16+
public static void ThrowIfInvalid(this Command command)
17+
{
18+
if (command.Parents.FlattenBreadthFirst(c => c.Parents).Any(ancestor => ancestor == command))
19+
{
20+
throw new InvalidOperationException($"Cycle detected in command tree. Command '{command.Name}' is its own ancestor.");
21+
}
22+
23+
int count = command.Subcommands.Count + command.Options.Count;
24+
for (var i = 0; i < count; i++)
25+
{
26+
Symbol symbol1 = GetChild(i, command, out HashSet<string> aliases1);
27+
28+
for (var j = i + 1; j < count; j++)
29+
{
30+
Symbol symbol2 = GetChild(j, command, out HashSet<string> aliases2);
31+
32+
if (symbol1.Name.Equals(symbol2.Name, StringComparison.Ordinal)
33+
|| aliases1 is not null && aliases1.Contains(symbol2.Name))
34+
{
35+
throw new InvalidOperationException($"Duplicate alias '{symbol2.Name}' found on command '{command.Name}'.");
36+
}
37+
else if (aliases2 is not null && aliases2.Contains(symbol1.Name))
38+
{
39+
throw new InvalidOperationException($"Duplicate alias '{symbol1.Name}' found on command '{command.Name}'.");
40+
}
41+
42+
if (aliases1 is not null && aliases2 is not null)
43+
{
44+
// take advantage of the fact that we are dealing with two hash sets
45+
if (aliases1.Overlaps(aliases2))
46+
{
47+
foreach (string symbol2Alias in aliases2)
48+
{
49+
if (aliases1.Contains(symbol2Alias))
50+
{
51+
throw new InvalidOperationException($"Duplicate alias '{symbol2Alias}' found on command '{command.Name}'.");
52+
}
53+
}
54+
}
55+
}
56+
}
57+
58+
if (symbol1 is Command childCommand)
59+
{
60+
childCommand.ThrowIfInvalid();
61+
}
62+
}
63+
64+
static Symbol GetChild(int index, Command command, out HashSet<string> aliases)
65+
{
66+
if (index < command.Subcommands.Count)
67+
{
68+
aliases = command.Subcommands[index].Aliases.ToHashSet();
69+
return command.Subcommands[index];
70+
}
71+
72+
aliases = command.Options[index - command.Subcommands.Count].Aliases.ToHashSet();
73+
return command.Options[index - command.Subcommands.Count];
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)