-
Notifications
You must be signed in to change notification settings - Fork 386
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
708181b
commit 39afcc0
Showing
8 changed files
with
289 additions
and
6 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
src/System.CommandLine.Subsystems.Tests/DiagramSubsystemTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using FluentAssertions; | ||
using System.CommandLine.Directives; | ||
using System.CommandLine.Parsing; | ||
using Xunit; | ||
|
||
namespace System.CommandLine.Subsystems.Tests; | ||
|
||
public class DiagramSubsystemTests | ||
{ | ||
|
||
[Theory] | ||
[ClassData(typeof(TestData.Diagram))] | ||
public void Diagram_is_activated_only_when_requested(string input, bool expectedIsActive) | ||
{ | ||
CliRootCommand rootCommand = [new CliCommand("x")]; | ||
var configuration = new CliConfiguration(rootCommand); | ||
var subsystem = new DiagramSubsystem(); | ||
var args = CliParser.SplitCommandLine(input).ToList().AsReadOnly(); | ||
|
||
Subsystem.Initialize(subsystem, configuration, args); | ||
var parseResult = CliParser.Parse(rootCommand, input, configuration); | ||
var isActive = Subsystem.GetIsActivated(subsystem, parseResult); | ||
|
||
isActive.Should().Be(expectedIsActive); | ||
} | ||
|
||
[Theory] | ||
[ClassData(typeof(TestData.Diagram))] | ||
public void String_directive_supplies_string_or_default_and_is_activated_only_when_requested(string input, bool expectedIsActive) | ||
{ | ||
CliRootCommand rootCommand = [new CliCommand("x")]; | ||
var configuration = new CliConfiguration(rootCommand); | ||
var subsystem = new DiagramSubsystem(); | ||
var args = CliParser.SplitCommandLine(input).ToList().AsReadOnly(); | ||
|
||
Subsystem.Initialize(subsystem, configuration, args); | ||
var parseResult = CliParser.Parse(rootCommand, input, configuration); | ||
var isActive = Subsystem.GetIsActivated(subsystem, parseResult); | ||
|
||
isActive.Should().Be(expectedIsActive); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
180 changes: 180 additions & 0 deletions
180
src/System.CommandLine.Subsystems/Directives/DiagramSubsystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.CommandLine.Subsystems; | ||
using System.Text; | ||
using System.CommandLine.Parsing; | ||
|
||
namespace System.CommandLine.Directives; | ||
|
||
public class DiagramSubsystem( IAnnotationProvider? annotationProvider = null) | ||
: DirectiveSubsystem("diagram", SubsystemKind.Diagram, annotationProvider) | ||
{ | ||
//protected internal override bool GetIsActivated(ParseResult? parseResult) | ||
// => parseResult is not null && option is not null && parseResult.GetValue(option); | ||
|
||
protected internal override CliExit Execute(PipelineContext pipelineContext) | ||
{ | ||
// Gather locations | ||
//var locations = pipelineContext.ParseResult.LocationMap | ||
// .Concat(Map(pipelineContext.ParseResult.Configuration.PreProcessedLocations)); | ||
|
||
pipelineContext.ConsoleHack.WriteLine("Output diagram"); | ||
return CliExit.SuccessfullyHandled(pipelineContext.ParseResult); | ||
} | ||
|
||
|
||
// TODO: Capture logic in previous diagramming, shown below | ||
/// <summary> | ||
/// Formats a string explaining a parse result. | ||
/// </summary> | ||
/// <param name="parseResult">The parse result to be diagrammed.</param> | ||
/// <returns>A string containing a diagram of the parse result.</returns> | ||
internal static StringBuilder Diagram(ParseResult parseResult) | ||
{ | ||
var builder = new StringBuilder(100); | ||
|
||
|
||
Diagram(builder, parseResult.RootCommandResult, parseResult); | ||
|
||
// TODO: Unmatched tokens | ||
/* | ||
var unmatchedTokens = parseResult.UnmatchedTokens; | ||
if (unmatchedTokens.Count > 0) | ||
{ | ||
builder.Append(" ???-->"); | ||
for (var i = 0; i < unmatchedTokens.Count; i++) | ||
{ | ||
var error = unmatchedTokens[i]; | ||
builder.Append(' '); | ||
builder.Append(error); | ||
} | ||
} | ||
*/ | ||
|
||
return builder; | ||
} | ||
|
||
private static void Diagram( | ||
StringBuilder builder, | ||
SymbolResult symbolResult, | ||
ParseResult parseResult) | ||
{ | ||
if (parseResult.Errors.Any(e => e.SymbolResult == symbolResult)) | ||
{ | ||
builder.Append('!'); | ||
} | ||
|
||
switch (symbolResult) | ||
{ | ||
// TODO: Directives | ||
/* | ||
case DirectiveResult { Directive: not DiagramDirective }: | ||
break; | ||
*/ | ||
|
||
// TODO: This logic is deeply tied to internal types/properties. These aren't things we probably want to expose like SymbolNode. See #2349 for alternatives | ||
/* | ||
case ArgumentResult argumentResult: | ||
{ | ||
var includeArgumentName = | ||
argumentResult.Argument.FirstParent!.Symbol is CliCommand { HasArguments: true, Arguments.Count: > 1 }; | ||
if (includeArgumentName) | ||
{ | ||
builder.Append("[ "); | ||
builder.Append(argumentResult.Argument.Name); | ||
builder.Append(' '); | ||
} | ||
if (argumentResult.Argument.Arity.MaximumNumberOfValues > 0) | ||
{ | ||
ArgumentConversionResult conversionResult = argumentResult.GetArgumentConversionResult(); | ||
switch (conversionResult.Result) | ||
{ | ||
case ArgumentConversionResultType.NoArgument: | ||
break; | ||
case ArgumentConversionResultType.Successful: | ||
switch (conversionResult.Value) | ||
{ | ||
case string s: | ||
builder.Append($"<{s}>"); | ||
break; | ||
case IEnumerable items: | ||
builder.Append('<'); | ||
builder.Append( | ||
string.Join("> <", | ||
items.Cast<object>().ToArray())); | ||
builder.Append('>'); | ||
break; | ||
default: | ||
builder.Append('<'); | ||
builder.Append(conversionResult.Value); | ||
builder.Append('>'); | ||
break; | ||
} | ||
break; | ||
default: // failures | ||
builder.Append('<'); | ||
builder.Append(string.Join("> <", symbolResult.Tokens.Select(t => t.Value))); | ||
builder.Append('>'); | ||
break; | ||
} | ||
} | ||
if (includeArgumentName) | ||
{ | ||
builder.Append(" ]"); | ||
} | ||
break; | ||
} | ||
default: | ||
{ | ||
OptionResult? optionResult = symbolResult as OptionResult; | ||
if (optionResult is { Implicit: true }) | ||
{ | ||
builder.Append('*'); | ||
} | ||
builder.Append("[ "); | ||
if (optionResult is not null) | ||
{ | ||
builder.Append(optionResult.IdentifierToken?.Value ?? optionResult.Option.Name); | ||
} | ||
else | ||
{ | ||
builder.Append(((CommandResult)symbolResult).IdentifierToken.Value); | ||
} | ||
foreach (SymbolResult child in symbolResult.SymbolResultTree.GetChildren(symbolResult)) | ||
{ | ||
if (child is ArgumentResult arg && | ||
(arg.Argument.ValueType == typeof(bool) || | ||
arg.Argument.Arity.MaximumNumberOfValues == 0)) | ||
{ | ||
continue; | ||
} | ||
builder.Append(' '); | ||
Diagram(builder, child, parseResult); | ||
} | ||
builder.Append(" ]"); | ||
break; | ||
} | ||
} | ||
*/ | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.CommandLine.Directives; | ||
|
||
namespace System.CommandLine; | ||
|
||
public class StandardPipeline : Pipeline | ||
{ | ||
{ | ||
public StandardPipeline() { | ||
Help = new HelpSubsystem(); | ||
Version = new VersionSubsystem(); | ||
ErrorReporting = new ErrorReportingSubsystem(); | ||
Completion = new CompletionSubsystem(); | ||
Diagram = new DiagramSubsystem(); | ||
ErrorReporting = new ErrorReportingSubsystem(); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/System.CommandLine.Subsystems/Subsystems/Annotations/DiagramAnnotations.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) .NET Foundation and contributors. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace System.CommandLine.Subsystems.Annotations; | ||
|
||
/// <summary> | ||
/// IDs for well-known diagram annotations. | ||
/// </summary> | ||
public static class DiagramAnnotations | ||
{ | ||
public static string Prefix { get; } = nameof(SubsystemKind.Diagram); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,5 @@ public enum SubsystemKind | |
Version, | ||
ErrorReporting, | ||
Completion, | ||
Diagram, | ||
} |