-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Use Microsoft.Extensions.CommandLineUtils and Microsoft.Extensions.Tools.Internal in service ref programs #13323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
f5458a9
to
f2520e8
Compare
I'll get dotnet/extensions#2210 in tomorrow morning (giving reviewers a bit more time) and this won't build until dependencies flow to this repo. But, I wanted to give reviewers more time with this. Reviewers feel free to add others familiar with our command-line tools if I missed anyone. @pranavkm I know you're probably the most familiar w/ the service ref code 🥇 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This area seems to be without tests, that's tracked here but we should be careful that that doesn't slip out beyond like the 3.1 milestone.
I'll leave final approval for whoever has been doing your other approvals on this work.
…ols.Internal in service ref programs - add '--quiet' option - add '--debug' option (when building Debug configuration) - support `--` in `dotnet-getdocument`; users may want to explictly add options for GetDocument.Insider - remove '--no-color' option - use `IReporter` extension methods instead of static `Reporter` class - reduce `static` use to ease testing (coming soon) and share the `IConsole` and `IReporter` - add `ProgramBase` - allow mix of known and unknown command-line arguments - maintain existing behaviour using switch added in dotnet/extensions#2210 nits: - add a couple more `CommandLineApplicationExtensions` methods - take VS suggestions
f2520e8
to
1d512c4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If everyone else is good with getting this in then it's fine with me 😉
public ProgramBase(IConsole console) | ||
{ | ||
_console = console ?? throw new ArgumentNullException(nameof(console)); | ||
_reporter = new ConsoleReporter(_console, verbose: false, quiet: false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make more sense to treat quiet/verbose similar to debug and pre-parse those arguments -> Create a reporter at the top level -> flow to any command interested? I ask because you create a reporter here in ProgramBase
, the CommandBase
constructor and in the CommandBase
configure. Seems like a whole lot of maintenance for a reporter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--debug
is "special" because it's supported only as the first command-line argument, not understood by any CommandOption
, and generally hidden. The others are real options that can appear anywhere in the command line. Besides that, this is the pattern we've used elsewhere.
BTW the truly-extra Reporter
instances are created for Exception
handling in Program
classes whether or not the command line has been parsed. The --quiet
and --verbose
options don't matter when writing errors.
} | ||
catch (Exception ex) | ||
{ | ||
if (ex is CommandException || ex is CommandParsingException) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just translate this into a catch -> when for clarity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will file a follow-up issue for this and replacing ReporterExtensions
AllowArgumentSeparator = !throwOnUnexpectedArg, | ||
Error = _console.Error, | ||
FullName = Resources.CommandFullName, | ||
Name = Resources.CommandFullName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these really be resources? If the command name gets localized doesn't that lead to misinformation on how to invoke the command?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually, perhaps. However most of our tools are not yet localizable and I'd rather stick w/ the norm until / unless we decide to change that all up.
|
||
namespace Microsoft.Extensions.ApiDescription.Tool | ||
{ | ||
internal static class ReporterExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just write your own type that inherits from ConsoleReporter? Seems sketchy to have a global static to control prefixing the output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one but it was specific to dotnet-watch
until @ryanbrandenburg checked in the OpenAPI global tool (CLI for adding references that use the Microsoft.Extensions.ApiDescription.Client infrastructure). So, the timing didn't work out but we could reconsider in 3.1.
Will file a follow-up issue for this and your catch
clarity suggestion.
@@ -21,6 +21,17 @@ public static void OnExecute(this CommandLineApplication app, Action action) | |||
return 0; | |||
}); | |||
|
|||
public static CommandOption Option(this CommandLineApplication command, string template, string description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed? I don't see it used anywhere. Also seems a little too magical for a general use-case extension
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it's needed; none of the Option(...)
calls in these tools pass a CommandOptionType
.
@@ -32,100 +34,30 @@ internal static class Exe | |||
startInfo.WorkingDirectory = workingDirectory; | |||
} | |||
|
|||
using (var process = Process.Start(startInfo)) | |||
using var process = Process.Start(startInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change to use this variant of using
? Having the block level using makes it clear when you expect the process has exited.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compiler goodies. Remove the bracket will help in defining the terse syntax for using scope and that it is pinned to function.
template, | ||
description, | ||
template.IndexOf('<') != -1 | ||
? template.EndsWith(">...") ? CommandOptionType.MultipleValue : CommandOptionType.SingleValue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks odd, could you explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a copy / paste from https://github.com/aspnet/AspNetCore/pull/13323/files#diff-e22cb33793ce6707b3111cac914249dfL8 (the old CommandLineApplicationExtensions
used in these tools). The idea is to infer the CommandOptionType
from the template. It's a compact version of the template parsing CommandLineApplication
does when trying to determine the name of an option's value. The three cases are
- no '<' indicates the option has no value
- if there is a '<', ">..." indicates the option accepts multiple values
- otherwise, the option accepts a single value
Yes, the code ignores the possibility of '<' without a matching '>' but the CommandLineApplication
template will throw in that case IIRC. If not, it's a general bug in the Extensions repo.
Getting this in. The only failure was of a test that's marked flaky but seems to be running everywhere. |
--
indotnet-getdocument
; users may want to explictly add options for GetDocument.InsiderIReporter
extension methods instead of staticReporter
classstatic
use to ease testing (coming soon) and share theIConsole
andIReporter
ProgramBase
nits:
CommandLineApplicationExtensions
methods