diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index a7c2f759e982..f9bfe0e6c5a1 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -25,18 +25,18 @@
https://github.com/dotnet/symreader
27e584661980ee6d82c419a2a471ae505b7d122e
-
+
https://github.com/dotnet/command-line-api
- 02fe27cd6a9b001c8feb7938e6ef4b3799745759
+ 8374d5fca634a93458c84414b1604c12f765d1ab
-
+
https://github.com/dotnet/command-line-api
- 02fe27cd6a9b001c8feb7938e6ef4b3799745759
+ 8374d5fca634a93458c84414b1604c12f765d1ab
-
+
https://github.com/dotnet/command-line-api
- 02fe27cd6a9b001c8feb7938e6ef4b3799745759
+ 8374d5fca634a93458c84414b1604c12f765d1ab
diff --git a/eng/Versions.props b/eng/Versions.props
index d53cabee7b6c..a0fbac4322d3 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -17,8 +17,8 @@
- 2.0.0-beta4.23307.1
- 0.4.0-alpha.23307.1
+ 2.0.0-beta4.22564.1
+ 0.4.0-alpha.22564.1
10.3.0
diff --git a/src/CommandLineExtensions.cs b/src/CommandLineExtensions.cs
new file mode 100644
index 000000000000..9cd803c68538
--- /dev/null
+++ b/src/CommandLineExtensions.cs
@@ -0,0 +1,102 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.CommandLine;
+using System.CommandLine.Parsing;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+
+namespace Microsoft.CodeAnalysis.Tools
+{
+ internal static class CommandLineExtensions
+ {
+ internal static OptionResult? GetOptionResult(this ParseResult result, string alias)
+ {
+ return GetOptionResult(result.CommandResult, alias);
+ }
+
+ internal static ArgumentResult? GetArgumentResult(this ParseResult result, string alias)
+ {
+ return GetArgumentResult(result.CommandResult, alias);
+ }
+
+ internal static OptionResult? GetOptionResult(this CommandResult result, string alias)
+ {
+ return result.Children.GetByAlias(alias) as OptionResult;
+ }
+
+ internal static ArgumentResult? GetArgumentResult(this CommandResult result, string alias)
+ {
+ return result.Children.GetByAlias(alias) as ArgumentResult;
+ }
+
+ internal static SymbolResult? GetByAlias(this IReadOnlyList results, string alias)
+ {
+ return results.SingleOrDefault(result => result.Symbol.Name.Equals(alias) || result.Symbol is IdentifierSymbol id && id.HasAlias(alias));
+ }
+
+ [return: MaybeNull]
+ internal static T GetValueForArgument(this ParseResult result, string alias)
+ {
+ return GetValueForArgument(result.CommandResult, alias);
+ }
+
+ [return: MaybeNull]
+ internal static T GetValueForArgument(this ParseResult result, Argument argument)
+ {
+ return GetValueForArgument(result.CommandResult, argument);
+ }
+
+ [return: MaybeNull]
+ internal static T GetValueForOption(this ParseResult result, string alias)
+ {
+ return GetValueForOption(result.CommandResult, alias);
+ }
+
+ [return: MaybeNull]
+ internal static T GetValueForArgument(this CommandResult result, Argument argumentDefinition)
+ {
+ var arguments = result.Children.Where(x => x.Symbol.Name == argumentDefinition.Name).ToArray();
+ if (arguments.Length == 1 &&
+ arguments.SingleOrDefault() is ArgumentResult argument &&
+ argument.GetValueOrDefault() is T t)
+ {
+ return t;
+ }
+
+ return default;
+ }
+
+ [return: MaybeNull]
+ internal static T GetValueForArgument(this CommandResult result, string alias)
+ {
+ if (result.GetArgumentResult(alias) is ArgumentResult argument &&
+ argument.GetValueOrDefault() is { } t)
+ {
+ return t;
+ }
+
+ return default;
+ }
+
+ [return: MaybeNull]
+ internal static T GetValueForOption(this CommandResult result, string alias)
+ {
+ if (result.GetOptionResult(alias) is OptionResult option &&
+ option.GetValueOrDefault() is { } t)
+ {
+ return t;
+ }
+
+ return default;
+ }
+
+ internal static bool WasOptionUsed(this ParseResult result, params string[] aliases)
+ {
+ return result.Tokens
+ .Where(token => token.Type == TokenType.Option)
+ .Any(token => aliases.Contains(token.Value));
+ }
+ }
+}
diff --git a/src/Commands/FormatAnalyzersCommand.cs b/src/Commands/FormatAnalyzersCommand.cs
index 4ecbb180c3f1..994a73735d69 100644
--- a/src/Commands/FormatAnalyzersCommand.cs
+++ b/src/Commands/FormatAnalyzersCommand.cs
@@ -2,8 +2,8 @@
using System.Collections.Immutable;
using System.CommandLine;
-using System.CommandLine.IO;
-using System.Threading;
+using System.CommandLine.Invocation;
+using System.CommandLine.Parsing;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using static Microsoft.CodeAnalysis.Tools.FormatCommandCommon;
@@ -14,43 +14,44 @@ internal static class FormatAnalyzersCommand
{
private static readonly FormatAnalyzersHandler s_analyzerHandler = new();
- internal static CliCommand GetCommand()
+ internal static Command GetCommand()
{
- var command = new CliCommand("analyzers", Resources.Run_3rd_party_analyzers__and_apply_fixes)
+ var command = new Command("analyzers", Resources.Run_3rd_party_analyzers__and_apply_fixes)
{
DiagnosticsOption,
ExcludeDiagnosticsOption,
SeverityOption,
};
command.AddCommonOptions();
- command.Action = s_analyzerHandler;
+ command.Handler = s_analyzerHandler;
return command;
}
- private class FormatAnalyzersHandler : CliAction
+ private class FormatAnalyzersHandler : ICommandHandler
{
- public override int Invoke(ParseResult parseResult) => InvokeAsync(parseResult, CancellationToken.None).GetAwaiter().GetResult();
+ public int Invoke(InvocationContext context) => InvokeAsync(context).GetAwaiter().GetResult();
- public override async Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
+ public async Task InvokeAsync(InvocationContext context)
{
+ var parseResult = context.ParseResult;
var formatOptions = parseResult.ParseVerbosityOption(FormatOptions.Instance);
- var logger = new SystemConsole().SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
+ var logger = context.Console.SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
formatOptions = parseResult.ParseCommonOptions(formatOptions, logger);
formatOptions = parseResult.ParseWorkspaceOptions(formatOptions);
- if (parseResult.GetResult(SeverityOption) is not null &&
+ if (parseResult.HasOption(SeverityOption) &&
parseResult.GetValue(SeverityOption) is string { Length: > 0 } analyzerSeverity)
{
formatOptions = formatOptions with { AnalyzerSeverity = GetSeverity(analyzerSeverity) };
}
- if (parseResult.GetResult(DiagnosticsOption) is not null &&
+ if (parseResult.HasOption(DiagnosticsOption) &&
parseResult.GetValue(DiagnosticsOption) is string[] { Length: > 0 } diagnostics)
{
formatOptions = formatOptions with { Diagnostics = diagnostics.ToImmutableHashSet() };
}
- if (parseResult.GetResult(ExcludeDiagnosticsOption) is not null &&
+ if (parseResult.HasOption(ExcludeDiagnosticsOption) &&
parseResult.GetValue(ExcludeDiagnosticsOption) is string[] { Length: > 0 } excludeDiagnostics)
{
formatOptions = formatOptions with { ExcludeDiagnostics = excludeDiagnostics.ToImmutableHashSet() };
@@ -58,7 +59,7 @@ public override async Task InvokeAsync(ParseResult parseResult, Cancellatio
formatOptions = formatOptions with { FixCategory = FixCategory.Analyzers };
- return await FormatAsync(formatOptions, logger, cancellationToken).ConfigureAwait(false);
+ return await FormatAsync(formatOptions, logger, context.GetCancellationToken()).ConfigureAwait(false);
}
}
}
diff --git a/src/Commands/FormatCommandCommon.cs b/src/Commands/FormatCommandCommon.cs
index d2ed8fad0cbe..5cccf1bbde2a 100644
--- a/src/Commands/FormatCommandCommon.cs
+++ b/src/Commands/FormatCommandCommon.cs
@@ -2,6 +2,7 @@
using System;
using System.CommandLine;
+using System.CommandLine.Parsing;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
@@ -26,80 +27,44 @@ internal static class FormatCommandCommon
private static string[] VerbosityLevels => new[] { "q", "quiet", "m", "minimal", "n", "normal", "d", "detailed", "diag", "diagnostic" };
private static string[] SeverityLevels => new[] { "info", "warn", "error" };
- public static readonly CliArgument SlnOrProjectArgument = new CliArgument(Resources.SolutionOrProjectArgumentName)
+ public static readonly Argument SlnOrProjectArgument = new Argument(Resources.SolutionOrProjectArgumentName)
{
Description = Resources.SolutionOrProjectArgumentDescription,
Arity = ArgumentArity.ZeroOrOne
}.DefaultToCurrentDirectory();
- internal static readonly CliOption FolderOption = new("--folder")
+ internal static readonly Option FolderOption = new(new[] { "--folder" }, Resources.Whether_to_treat_the_workspace_argument_as_a_simple_folder_of_files);
+ internal static readonly Option NoRestoreOption = new(new[] { "--no-restore" }, Resources.Doesnt_execute_an_implicit_restore_before_formatting);
+ internal static readonly Option VerifyNoChanges = new(new[] { "--verify-no-changes" }, Resources.Verify_no_formatting_changes_would_be_performed_Terminates_with_a_non_zero_exit_code_if_any_files_would_have_been_formatted);
+ internal static readonly Option DiagnosticsOption = new(new[] { "--diagnostics" }, () => Array.Empty(), Resources.A_space_separated_list_of_diagnostic_ids_to_use_as_a_filter_when_fixing_code_style_or_3rd_party_issues)
{
- Description = Resources.Whether_to_treat_the_workspace_argument_as_a_simple_folder_of_files,
+ AllowMultipleArgumentsPerToken = true
};
- internal static readonly CliOption NoRestoreOption = new("--no-restore")
+ internal static readonly Option ExcludeDiagnosticsOption = new(new[] { "--exclude-diagnostics" }, () => Array.Empty(), Resources.A_space_separated_list_of_diagnostic_ids_to_ignore_when_fixing_code_style_or_3rd_party_issues)
{
- Description = Resources.Doesnt_execute_an_implicit_restore_before_formatting,
+ AllowMultipleArgumentsPerToken = true
};
- internal static readonly CliOption VerifyNoChanges = new("--verify-no-changes")
+ internal static readonly Option SeverityOption = new Option("--severity", Resources.The_severity_of_diagnostics_to_fix_Allowed_values_are_info_warn_and_error).AcceptOnlyFromAmong(SeverityLevels);
+ internal static readonly Option IncludeOption = new(new[] { "--include" }, () => Array.Empty(), Resources.A_list_of_relative_file_or_folder_paths_to_include_in_formatting_All_files_are_formatted_if_empty)
{
- Description = Resources.Verify_no_formatting_changes_would_be_performed_Terminates_with_a_non_zero_exit_code_if_any_files_would_have_been_formatted,
+ AllowMultipleArgumentsPerToken = true
};
- internal static readonly CliOption DiagnosticsOption = new("--diagnostics")
+ internal static readonly Option ExcludeOption = new(new[] { "--exclude" }, () => Array.Empty(), Resources.A_list_of_relative_file_or_folder_paths_to_exclude_from_formatting)
{
- AllowMultipleArgumentsPerToken = true,
- DefaultValueFactory = _ => Array.Empty(),
- Description = Resources.A_space_separated_list_of_diagnostic_ids_to_use_as_a_filter_when_fixing_code_style_or_3rd_party_issues,
+ AllowMultipleArgumentsPerToken = true
};
- internal static readonly CliOption ExcludeDiagnosticsOption = new("--exclude-diagnostics")
+ internal static readonly Option IncludeGeneratedOption = new(new[] { "--include-generated" }, Resources.Format_files_generated_by_the_SDK);
+ internal static readonly Option VerbosityOption = new Option(new[] { "--verbosity", "-v" }, Resources.Set_the_verbosity_level_Allowed_values_are_quiet_minimal_normal_detailed_and_diagnostic).AcceptOnlyFromAmong(VerbosityLevels);
+ internal static readonly Option BinarylogOption = new Option(new[] { "--binarylog" }, Resources.Log_all_project_or_solution_load_information_to_a_binary_log_file)
{
- AllowMultipleArgumentsPerToken = true,
- DefaultValueFactory = _ => Array.Empty(),
- Description = Resources.A_space_separated_list_of_diagnostic_ids_to_ignore_when_fixing_code_style_or_3rd_party_issues,
- };
- internal static readonly CliOption SeverityOption = new CliOption("--severity")
- {
- Description = Resources.The_severity_of_diagnostics_to_fix_Allowed_values_are_info_warn_and_error,
- };
- internal static readonly CliOption IncludeOption = new("--include")
- {
- AllowMultipleArgumentsPerToken = true,
- DefaultValueFactory = _ => Array.Empty(),
- Description = Resources.A_list_of_relative_file_or_folder_paths_to_include_in_formatting_All_files_are_formatted_if_empty,
- };
- internal static readonly CliOption ExcludeOption = new("--exclude")
- {
- AllowMultipleArgumentsPerToken = true,
- DefaultValueFactory = _ => Array.Empty(),
- Description = Resources.A_list_of_relative_file_or_folder_paths_to_exclude_from_formatting,
- };
- internal static readonly CliOption IncludeGeneratedOption = new("--include-generated")
- {
- Description = Resources.Format_files_generated_by_the_SDK,
- };
- internal static readonly CliOption VerbosityOption = new CliOption("--verbosity", "-v")
- {
- Description = Resources.Set_the_verbosity_level_Allowed_values_are_quiet_minimal_normal_detailed_and_diagnostic,
- };
- internal static readonly CliOption BinarylogOption = new CliOption("--binarylog")
- {
- HelpName = "binary-log-path",
- Arity = ArgumentArity.ZeroOrOne,
- Description = Resources.Log_all_project_or_solution_load_information_to_a_binary_log_file,
- };
- internal static readonly CliOption ReportOption = new CliOption("--report")
- {
- HelpName = "report-path",
- Arity = ArgumentArity.ZeroOrOne,
- Description = Resources.Accepts_a_file_path_which_if_provided_will_produce_a_json_report_in_the_given_directory,
- };
-
- static FormatCommandCommon()
+ ArgumentHelpName = "binary-log-path",
+ Arity = ArgumentArity.ZeroOrOne
+ }.AcceptLegalFilePathsOnly();
+ internal static readonly Option ReportOption = new Option(new[] { "--report" }, Resources.Accepts_a_file_path_which_if_provided_will_produce_a_json_report_in_the_given_directory)
{
- SeverityOption.AcceptOnlyFromAmong(SeverityLevels);
- VerbosityOption.AcceptOnlyFromAmong(VerbosityLevels);
- BinarylogOption.AcceptLegalFilePathsOnly();
- ReportOption.AcceptLegalFilePathsOnly();
- }
+ ArgumentHelpName = "report-path",
+ Arity = ArgumentArity.ZeroOrOne
+ }.AcceptLegalFilePathsOnly();
internal static async Task FormatAsync(FormatOptions formatOptions, ILogger logger, CancellationToken cancellationToken)
{
@@ -133,22 +98,22 @@ internal static async Task FormatAsync(FormatOptions formatOptions, ILogger
return formatResult.GetExitCode(formatOptions.ChangesAreErrors);
}
- public static void AddCommonOptions(this CliCommand command)
+ public static void AddCommonOptions(this Command command)
{
- command.Arguments.Add(SlnOrProjectArgument);
- command.Options.Add(NoRestoreOption);
- command.Options.Add(VerifyNoChanges);
- command.Options.Add(IncludeOption);
- command.Options.Add(ExcludeOption);
- command.Options.Add(IncludeGeneratedOption);
- command.Options.Add(VerbosityOption);
- command.Options.Add(BinarylogOption);
- command.Options.Add(ReportOption);
+ command.AddArgument(SlnOrProjectArgument);
+ command.AddOption(NoRestoreOption);
+ command.AddOption(VerifyNoChanges);
+ command.AddOption(IncludeOption);
+ command.AddOption(ExcludeOption);
+ command.AddOption(IncludeGeneratedOption);
+ command.AddOption(VerbosityOption);
+ command.AddOption(BinarylogOption);
+ command.AddOption(ReportOption);
}
- public static CliArgument DefaultToCurrentDirectory(this CliArgument arg)
+ public static Argument DefaultToCurrentDirectory(this Argument arg)
{
- arg.DefaultValueFactory = _ => EnsureTrailingSlash(Directory.GetCurrentDirectory());
+ arg.SetDefaultValue(EnsureTrailingSlash(Directory.GetCurrentDirectory()));
return arg;
}
@@ -172,7 +137,7 @@ public static int GetExitCode(this WorkspaceFormatResult formatResult, bool chec
public static FormatOptions ParseVerbosityOption(this ParseResult parseResult, FormatOptions formatOptions)
{
- if (parseResult.GetResult(VerbosityOption) is not null &&
+ if (parseResult.HasOption(VerbosityOption) &&
parseResult.GetValue(VerbosityOption) is string { Length: > 0 } verbosity)
{
formatOptions = formatOptions with { LogLevel = GetLogLevel(verbosity) };
@@ -187,23 +152,23 @@ public static FormatOptions ParseVerbosityOption(this ParseResult parseResult, F
public static FormatOptions ParseCommonOptions(this ParseResult parseResult, FormatOptions formatOptions, ILogger logger)
{
- if (parseResult.GetResult(NoRestoreOption) is not null)
+ if (parseResult.HasOption(NoRestoreOption))
{
formatOptions = formatOptions with { NoRestore = true };
}
- if (parseResult.GetResult(VerifyNoChanges) is not null)
+ if (parseResult.HasOption(VerifyNoChanges))
{
formatOptions = formatOptions with { ChangesAreErrors = true };
formatOptions = formatOptions with { SaveFormattedFiles = false };
}
- if (parseResult.GetResult(IncludeGeneratedOption) is not null)
+ if (parseResult.HasOption(IncludeGeneratedOption))
{
formatOptions = formatOptions with { IncludeGeneratedFiles = true };
}
- if (parseResult.GetResult(IncludeOption) is not null || parseResult.GetResult(ExcludeOption) is not null)
+ if (parseResult.HasOption(IncludeOption) || parseResult.HasOption(ExcludeOption))
{
var fileToInclude = parseResult.GetValue(IncludeOption) ?? Array.Empty();
var fileToExclude = parseResult.GetValue(ExcludeOption) ?? Array.Empty();
@@ -211,7 +176,7 @@ public static FormatOptions ParseCommonOptions(this ParseResult parseResult, For
formatOptions = formatOptions with { FileMatcher = SourceFileMatcher.CreateMatcher(fileToInclude, fileToExclude) };
}
- if (parseResult.GetResult(ReportOption) is not null)
+ if (parseResult.HasOption(ReportOption))
{
formatOptions = formatOptions with { ReportPath = string.Empty };
@@ -221,7 +186,7 @@ public static FormatOptions ParseCommonOptions(this ParseResult parseResult, For
}
}
- if (parseResult.GetResult(BinarylogOption) is not null)
+ if (parseResult.HasOption(BinarylogOption))
{
formatOptions = formatOptions with { BinaryLogPath = "format.binlog" };
@@ -323,7 +288,7 @@ public static FormatOptions ParseWorkspaceOptions(this ParseResult parseResult,
if (parseResult.GetValue(SlnOrProjectArgument) is string { Length: > 0 } slnOrProject)
{
- if (parseResult.GetResult(FolderOption) is not null)
+ if (parseResult.HasOption(FolderOption))
{
formatOptions = formatOptions with { WorkspaceFilePath = slnOrProject };
formatOptions = formatOptions with { WorkspaceType = WorkspaceType.Folder };
diff --git a/src/Commands/FormatStyleCommand.cs b/src/Commands/FormatStyleCommand.cs
index cddf23cad785..e915e9936b6d 100644
--- a/src/Commands/FormatStyleCommand.cs
+++ b/src/Commands/FormatStyleCommand.cs
@@ -2,8 +2,8 @@
using System.Collections.Immutable;
using System.CommandLine;
-using System.CommandLine.IO;
-using System.Threading;
+using System.CommandLine.Invocation;
+using System.CommandLine.Parsing;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using static Microsoft.CodeAnalysis.Tools.FormatCommandCommon;
@@ -14,43 +14,44 @@ internal static class FormatStyleCommand
{
private static readonly FormatStyleHandler s_styleHandler = new();
- internal static CliCommand GetCommand()
+ internal static Command GetCommand()
{
- var command = new CliCommand("style", Resources.Run_code_style_analyzers_and_apply_fixes)
+ var command = new Command("style", Resources.Run_code_style_analyzers_and_apply_fixes)
{
DiagnosticsOption,
ExcludeDiagnosticsOption,
SeverityOption,
};
command.AddCommonOptions();
- command.Action = s_styleHandler;
+ command.Handler = s_styleHandler;
return command;
}
- private class FormatStyleHandler : CliAction
+ private class FormatStyleHandler : ICommandHandler
{
- public override int Invoke(ParseResult parseResult) => InvokeAsync(parseResult, CancellationToken.None).GetAwaiter().GetResult();
+ public int Invoke(InvocationContext context) => InvokeAsync(context).GetAwaiter().GetResult();
- public override async Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
+ public async Task InvokeAsync(InvocationContext context)
{
+ var parseResult = context.ParseResult;
var formatOptions = parseResult.ParseVerbosityOption(FormatOptions.Instance);
- var logger = new SystemConsole().SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
+ var logger = context.Console.SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
formatOptions = parseResult.ParseCommonOptions(formatOptions, logger);
formatOptions = parseResult.ParseWorkspaceOptions(formatOptions);
- if (parseResult.GetResult(SeverityOption) is not null &&
+ if (parseResult.HasOption(SeverityOption) &&
parseResult.GetValue(SeverityOption) is string { Length: > 0 } styleSeverity)
{
formatOptions = formatOptions with { CodeStyleSeverity = GetSeverity(styleSeverity) };
}
- if (parseResult.GetResult(DiagnosticsOption) is not null &&
+ if (parseResult.HasOption(DiagnosticsOption) &&
parseResult.GetValue(DiagnosticsOption) is string[] { Length: > 0 } diagnostics)
{
formatOptions = formatOptions with { Diagnostics = diagnostics.ToImmutableHashSet() };
}
- if (parseResult.GetResult(ExcludeDiagnosticsOption) is not null &&
+ if (parseResult.HasOption(ExcludeDiagnosticsOption) &&
parseResult.GetValue(ExcludeDiagnosticsOption) is string[] { Length: > 0 } excludeDiagnostics)
{
formatOptions = formatOptions with { ExcludeDiagnostics = excludeDiagnostics.ToImmutableHashSet() };
@@ -58,7 +59,7 @@ public override async Task InvokeAsync(ParseResult parseResult, Cancellatio
formatOptions = formatOptions with { FixCategory = FixCategory.CodeStyle };
- return await FormatAsync(formatOptions, logger, cancellationToken).ConfigureAwait(false);
+ return await FormatAsync(formatOptions, logger, context.GetCancellationToken()).ConfigureAwait(false);
}
}
}
diff --git a/src/Commands/FormatWhitespaceCommand.cs b/src/Commands/FormatWhitespaceCommand.cs
index de62c51cd39e..953f4c018f9a 100644
--- a/src/Commands/FormatWhitespaceCommand.cs
+++ b/src/Commands/FormatWhitespaceCommand.cs
@@ -1,9 +1,8 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
using System.CommandLine;
-using System.CommandLine.IO;
+using System.CommandLine.Invocation;
using System.CommandLine.Parsing;
-using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using static Microsoft.CodeAnalysis.Tools.FormatCommandCommon;
@@ -29,53 +28,52 @@ internal delegate Task Handler(
private static readonly FormatWhitespaceHandler s_formattingHandler = new();
- internal static CliCommand GetCommand()
+ internal static Command GetCommand()
{
- var command = new CliCommand("whitespace", Resources.Run_whitespace_formatting)
+ var command = new Command("whitespace", Resources.Run_whitespace_formatting)
{
FolderOption
};
command.AddCommonOptions();
- command.Validators.Add(EnsureFolderNotSpecifiedWithNoRestore);
- command.Validators.Add(EnsureFolderNotSpecifiedWhenLoggingBinlog);
- command.Action = s_formattingHandler;
+ command.AddValidator(EnsureFolderNotSpecifiedWithNoRestore);
+ command.AddValidator(EnsureFolderNotSpecifiedWhenLoggingBinlog);
+ command.Handler = s_formattingHandler;
return command;
}
internal static void EnsureFolderNotSpecifiedWithNoRestore(CommandResult symbolResult)
{
- var folder = symbolResult.GetValue(FolderOption);
- var noRestore = symbolResult.GetResult(NoRestoreOption);
- if (folder && noRestore != null)
- {
- symbolResult.AddError(Resources.Cannot_specify_the_folder_option_with_no_restore);
- }
+ var folder = symbolResult.GetValueForOption("--folder");
+ var noRestore = symbolResult.GetOptionResult("--no-restore");
+ symbolResult.ErrorMessage = folder && noRestore != null
+ ? Resources.Cannot_specify_the_folder_option_with_no_restore
+ : null;
}
internal static void EnsureFolderNotSpecifiedWhenLoggingBinlog(CommandResult symbolResult)
{
- var folder = symbolResult.GetValue(FolderOption);
- var binarylog = symbolResult.GetResult(BinarylogOption);
- if (folder && binarylog is not null && !binarylog.Implicit)
- {
- symbolResult.AddError(Resources.Cannot_specify_the_folder_option_when_writing_a_binary_log);
- }
+ var folder = symbolResult.GetValueForOption("--folder");
+ var binarylog = symbolResult.GetOptionResult("--binarylog");
+ symbolResult.ErrorMessage = folder && binarylog is not null && !binarylog.IsImplicit
+ ? Resources.Cannot_specify_the_folder_option_when_writing_a_binary_log
+ : null;
}
- private class FormatWhitespaceHandler : CliAction
+ private class FormatWhitespaceHandler : ICommandHandler
{
- public override int Invoke(ParseResult parseResult) => InvokeAsync(parseResult, CancellationToken.None).GetAwaiter().GetResult();
+ public int Invoke(InvocationContext context) => InvokeAsync(context).GetAwaiter().GetResult();
- public override async Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
+ public async Task InvokeAsync(InvocationContext context)
{
+ var parseResult = context.ParseResult;
var formatOptions = parseResult.ParseVerbosityOption(FormatOptions.Instance);
- var logger = new SystemConsole().SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
+ var logger = context.Console.SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
formatOptions = parseResult.ParseCommonOptions(formatOptions, logger);
formatOptions = parseResult.ParseWorkspaceOptions(formatOptions);
formatOptions = formatOptions with { FixCategory = FixCategory.Whitespace };
- return await FormatAsync(formatOptions, logger, cancellationToken).ConfigureAwait(false);
+ return await FormatAsync(formatOptions, logger, context.GetCancellationToken()).ConfigureAwait(false);
}
}
}
diff --git a/src/Commands/RootFormatCommand.cs b/src/Commands/RootFormatCommand.cs
index 79faa8edb12b..7f04ecfa791d 100644
--- a/src/Commands/RootFormatCommand.cs
+++ b/src/Commands/RootFormatCommand.cs
@@ -2,8 +2,8 @@
using System.Collections.Immutable;
using System.CommandLine;
-using System.CommandLine.IO;
-using System.Threading;
+using System.CommandLine.Invocation;
+using System.CommandLine.Parsing;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using static Microsoft.CodeAnalysis.Tools.FormatCommandCommon;
@@ -14,9 +14,9 @@ internal static class RootFormatCommand
{
private static readonly FormatCommandDefaultHandler s_formatCommandHandler = new();
- public static CliRootCommand GetCommand()
+ public static RootCommand GetCommand()
{
- var formatCommand = new CliRootCommand(Resources.Formats_code_to_match_editorconfig_settings)
+ var formatCommand = new RootCommand(Resources.Formats_code_to_match_editorconfig_settings)
{
FormatWhitespaceCommand.GetCommand(),
FormatStyleCommand.GetCommand(),
@@ -26,35 +26,36 @@ public static CliRootCommand GetCommand()
SeverityOption,
};
formatCommand.AddCommonOptions();
- formatCommand.Action = s_formatCommandHandler;
+ formatCommand.Handler = s_formatCommandHandler;
return formatCommand;
}
- private class FormatCommandDefaultHandler : CliAction
+ private class FormatCommandDefaultHandler : ICommandHandler
{
- public override int Invoke(ParseResult parseResult) => InvokeAsync(parseResult, CancellationToken.None).GetAwaiter().GetResult();
+ public int Invoke(InvocationContext context) => InvokeAsync(context).GetAwaiter().GetResult();
- public override async Task InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
+ public async Task InvokeAsync(InvocationContext context)
{
+ var parseResult = context.ParseResult;
var formatOptions = parseResult.ParseVerbosityOption(FormatOptions.Instance);
- var logger = new SystemConsole().SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
+ var logger = context.Console.SetupLogging(minimalLogLevel: formatOptions.LogLevel, minimalErrorLevel: LogLevel.Warning);
formatOptions = parseResult.ParseCommonOptions(formatOptions, logger);
formatOptions = parseResult.ParseWorkspaceOptions(formatOptions);
- if (parseResult.GetResult(SeverityOption) is not null &&
+ if (parseResult.HasOption(SeverityOption) &&
parseResult.GetValue(SeverityOption) is string { Length: > 0 } defaultSeverity)
{
formatOptions = formatOptions with { AnalyzerSeverity = GetSeverity(defaultSeverity) };
formatOptions = formatOptions with { CodeStyleSeverity = GetSeverity(defaultSeverity) };
}
- if (parseResult.GetResult(DiagnosticsOption) is not null &&
+ if (parseResult.HasOption(DiagnosticsOption) &&
parseResult.GetValue(DiagnosticsOption) is string[] { Length: > 0 } diagnostics)
{
formatOptions = formatOptions with { Diagnostics = diagnostics.ToImmutableHashSet() };
}
- if (parseResult.GetResult(ExcludeDiagnosticsOption) is not null &&
+ if (parseResult.HasOption(ExcludeDiagnosticsOption) &&
parseResult.GetValue(ExcludeDiagnosticsOption) is string[] { Length: > 0 } excludeDiagnostics)
{
formatOptions = formatOptions with { ExcludeDiagnostics = excludeDiagnostics.ToImmutableHashSet() };
@@ -62,7 +63,7 @@ public override async Task InvokeAsync(ParseResult parseResult, Cancellatio
formatOptions = formatOptions with { FixCategory = FixCategory.Whitespace | FixCategory.CodeStyle | FixCategory.Analyzers };
- return await FormatAsync(formatOptions, logger, cancellationToken).ConfigureAwait(false);
+ return await FormatAsync(formatOptions, logger, context.GetCancellationToken()).ConfigureAwait(false);
}
}
}
diff --git a/src/Program.cs b/src/Program.cs
index 91ec85b660c3..5ffb0f8dbf44 100644
--- a/src/Program.cs
+++ b/src/Program.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
-using System.Threading;
+using System.CommandLine;
+using System.CommandLine.Parsing;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Tools.Commands;
@@ -11,7 +12,7 @@ internal class Program
private static async Task Main(string[] args)
{
var rootCommand = RootFormatCommand.GetCommand();
- return await rootCommand.Parse(args).InvokeAsync(CancellationToken.None);
+ return await rootCommand.InvokeAsync(args);
}
}
}
diff --git a/tests/ProgramTests.cs b/tests/ProgramTests.cs
index 7c5181025268..488f4955d7d5 100644
--- a/tests/ProgramTests.cs
+++ b/tests/ProgramTests.cs
@@ -1,5 +1,8 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+using System.Collections.Generic;
+using System.CommandLine;
+using System.CommandLine.Parsing;
using Microsoft.CodeAnalysis.Tools.Commands;
using Xunit;
@@ -55,18 +58,18 @@ public void CommandLine_OptionsAreParsedCorrectly()
Assert.Equal(0, result.Errors.Count);
Assert.Equal(0, result.UnmatchedTokens.Count);
Assert.Equal(0, result.UnmatchedTokens.Count);
- result.GetValue(FormatCommandCommon.NoRestoreOption);
- Assert.Collection(result.GetValue(FormatCommandCommon.IncludeOption),
+ result.GetValueForOption("--no-restore");
+ Assert.Collection(result.GetValueForOption>("--include"),
i0 => Assert.Equal("include1", i0),
i1 => Assert.Equal("include2", i1));
- Assert.Collection(result.GetValue(FormatCommandCommon.ExcludeOption),
+ Assert.Collection(result.GetValueForOption>("--exclude"),
i0 => Assert.Equal("exclude1", i0),
i1 => Assert.Equal("exclude2", i1));
- Assert.True(result.GetValue(FormatCommandCommon.VerifyNoChanges));
- Assert.Equal("binary-log-path", result.GetValue(FormatCommandCommon.BinarylogOption));
- Assert.Equal("report", result.GetValue(FormatCommandCommon.ReportOption));
- Assert.Equal("detailed", result.GetValue(FormatCommandCommon.VerbosityOption));
- Assert.True(result.GetValue(FormatCommandCommon.IncludeGeneratedOption));
+ Assert.True(result.GetValueForOption("--verify-no-changes"));
+ Assert.Equal("binary-log-path", result.GetValueForOption("--binarylog"));
+ Assert.Equal("report", result.GetValueForOption("--report"));
+ Assert.Equal("detailed", result.GetValueForOption("--verbosity"));
+ Assert.True(result.GetValueForOption("--include-generated"));
}
[Fact]
@@ -80,7 +83,7 @@ public void CommandLine_ProjectArgument_Simple()
// Assert
Assert.Equal(0, result.Errors.Count);
- Assert.Equal("workspaceValue", result.GetValue(FormatCommandCommon.SlnOrProjectArgument));
+ Assert.Equal("workspaceValue", result.GetValueForArgument(FormatCommandCommon.SlnOrProjectArgument));
}
[Fact]
@@ -94,8 +97,8 @@ public void CommandLine_ProjectArgument_WithOption_AfterArgument()
// Assert
Assert.Equal(0, result.Errors.Count);
- Assert.Equal("workspaceValue", result.GetValue(FormatCommandCommon.SlnOrProjectArgument));
- Assert.Equal("detailed", result.GetValue(FormatCommandCommon.VerbosityOption));
+ Assert.Equal("workspaceValue", result.GetValueForArgument(FormatCommandCommon.SlnOrProjectArgument));
+ Assert.Equal("detailed", result.GetValueForOption("--verbosity"));
}
[Fact]
@@ -109,8 +112,8 @@ public void CommandLine_ProjectArgument_WithOption_BeforeArgument()
// Assert
Assert.Equal(0, result.Errors.Count);
- Assert.Equal("workspaceValue", result.GetValue(FormatCommandCommon.SlnOrProjectArgument));
- Assert.Equal("detailed", result.GetValue(FormatCommandCommon.VerbosityOption));
+ Assert.Equal("workspaceValue", result.GetValueForArgument(FormatCommandCommon.SlnOrProjectArgument));
+ Assert.Equal("detailed", result.GetValueForOption("--verbosity"));
}
[Fact]
@@ -176,7 +179,7 @@ public void CommandLine_BinaryLog_DoesNotFailIfPathNotSpecified()
// Assert
Assert.Equal(0, result.Errors.Count);
- Assert.NotNull(result.GetResult(FormatCommandCommon.BinarylogOption));
+ Assert.True(result.WasOptionUsed("--binarylog"));
}
[Fact]
@@ -190,7 +193,7 @@ public void CommandLine_BinaryLog_DoesNotFailIfPathIsSpecified()
// Assert
Assert.Equal(0, result.Errors.Count);
- Assert.NotNull(result.GetResult(FormatCommandCommon.BinarylogOption));
+ Assert.True(result.WasOptionUsed("--binarylog"));
}
[Fact]