dotnet / diagnostics

This repository contains the source code for various .NET Core runtime diagnostic tools and documents.
MIT License
1.18k stars 354 forks source link

Design the dotnet tools command-line user experience #109

Closed noahfalk closed 5 years ago

noahfalk commented 5 years ago

Update: dotnet-tools.md has the current design - feedback encouraged

For .Net Core 3.0 we are proposing some related diagnostic experiences that are at least partially on the command-line: 1) Collect and analyze a dump with a command line analysis tool #88 2) Collect perf counters and monitor them live #91 3) Collect a trace that can be analyzed with VS (or PerfView) for memory leaks #86 (CPU), #87 (memory) 4) Install and configure SOS for LLDB #108

In addition to these scenarios this is also a pre-existing dotnet symbol command to gather binaries/symbols/DAC prior to debugging, and in the future we can anticipate more potential command line diagnostic scenarios such as: 1) Capture and print threads/stacks to the console 2) Analyze trace data with a local command line tool 3) Monitor an app until certain trigger conditions are true, then collect dumps/traces/counters 4) Export counter/trace/dump data to an external telemetry aggregation system 5) Monitor an application and display all the results real-time via a tool that hosts a web endpoint + browser

The goal is to design the command-line interface for all the 3.0 scenarios now so that they are: 1) Easy to use 2) Consistent with each other and with pre-existing dotnet CLI conventions 3) Have a reasonable roadmap to add some of the probably future scenarios without feeling convoluted

noahfalk commented 5 years ago

There is design doc we can edit here as needed: https://github.com/dotnet/diagnostics/blob/master/documentation/design-docs/dotnet-tools.md

During some discussion today a few issues emerged, but we need to do investigation to see how much we can decouple them:

1) What particular command line syntax do we have? 2) How many executables do we have? 3) How many distinct installation steps are necessary to get everything? 4) How readily can different command-line UI entrypoints share similar functionality in their implementation?

My current understanding is that a top-level verb in the dotnet syntax requires its own executable, for example dotnet foo requires a dotnet-foo executable to exist. I don't know (and Mike was looking into this) whether installations are required to be 1:1 with executables, or if we can pack multiple executables into a single package. If we can only have 1 executable per installer, that would mean for each 'dotnet foo' command the user has to do a corresponding 'dotnet tool install -g foo', and periodically 'dotnet tool update foo'. In terms of sharing functionality, I am not aware of any constraints that prevent us from factoring into libraries however we wish, and using the same libraries from multiple tools. This should mean that we can factor based on size-on-disk for a scenario and good layering without being too concerned about which particular UI commands expose it.

For deployment I'm expecting we've got a few cases: a) collection/export-only scenario that customers might want to have installed by default on every machine. Size on disk needs to be small. b) collect/export/monitor/analyze dev experience that customers would install on their dev machines, or on demand might install onto a production machine. Probably a strict super-set of what is included in the collection/export scenario and size on disk not a big deal as long as we don't go nuts c) Maybe not right away, but we should also keep in mind the scenario where a user hosts portions of the diagnostic functionality in-proc and might even ship it with his app into production. For example if we built a web service library that can visualize trace data from a separate monitoring process, a dotnet dev might want to take that same library and expose the web endpoint from within his own app to create a built-in admin monitoring portal.

noahfalk commented 5 years ago

cc @shirhatti @mikem8361 @davidfowl @vancem

mikem8361 commented 5 years ago

I have confirmed that we can only have one command per dotnet global tool package i.e. "dotnet foo" will require "dotnet tool install -g foo". And each tool package is self-contained other than the runtime assemblies all the package or project reference assemblies are included. If our separate tools share functionality via common assemblies, those assemblies will be included in each tool package and on disk when installed.

mikem8361 commented 5 years ago

@noahfalk @vancem, @KathleenDollard @tommcdon @shirhatti @davidfowl

Here is some guidelines for dotnet cli commands and extensions:

https://github.com/dotnet/designs/blob/master/accepted/cli-syntax-guideline.md

We are already a little off with the general form of a command with our verbs like "collect", "analyze", "monitor".

$ dotnet [context] [action] [options] [context specification] [action type] [arguments]

"dump", "events", "counters", "symbol", "sos" would seem to fit as "contexts". I'm just throwing this out for discussion, I'm not attached to the using a context vs the verbs we have already. The problem with the current dotnet global tool implementation is each "context" is a separate install.

As far as where the sos installer fits in all of this, I don't like the idea of dotnet analyze install-sos if we go with the discussion and ideas so far. Installing SOS for native debuggers doesn't fit with "analyze". Something like this makes more sense: dotnet sos install or dotnet sos configure.

KathleenDollard commented 5 years ago

A few thoughts...

In addition to the issue of how global tools currently install, there are also issues of how crowded the dotnet namespace has become. Because of decisions we have already made, anyone can jump into that ecosystem. A couple of implications here

I'm happy to brainstorm or review the CLI that you plan to use.

Also, since I'm working with System.CommandLine as a side project, I'm curious what your intention is for a command line parser and help and whether you plan to support tab completion.

mikem8361 commented 5 years ago

@KathleenDollard what about abbreviations for the tool itself. We have discussed "dotnet-diag" as the base tool/package with the various verbs like "analyze", "dump", "install-sos", "monitor", etc.

I'm not sure if anybody else would agree with dotnet-diag but I want to throw it out there to start discussion.

noahfalk commented 5 years ago

You need to reserve your NuGet package names as soon as you believe you will use a package

Does reserve mean upload a dummy package or is there some other way to reserve NuGet names?

Also, since I'm working with System.CommandLine as a side project, I'm curious what your intention is for a command line parser and help and whether you plan to support tab completion.

Its not an area I had looked into yet. I'd gladly not reinvent the wheel if there is a library that works. For tab completion, I don't see any downsides to supporting it other than work involved, and if System.CommandLine makes that easy then great : )

noahfalk commented 5 years ago

Just fyi, on Friday while chatting with @shirhatti @vancem and @tommcdon I promised I would flesh out a strawman this week. I'll be making updates to our design doc and feedback is welcome at any point. I'll continue to update status here.

KathleenDollard commented 5 years ago

Will or Rob, can you explain how to reserve a NuGet package Id. Is it via a dummy package or slightly different.


From: Noah Falk notifications@github.com Sent: Monday, January 14, 2019 2:24:11 PM To: dotnet/diagnostics Cc: Kathleen Dollard; Mention Subject: Re: [dotnet/diagnostics] Design the dotnet tools command-line user experience (#109)

Just fyi, on Friday while chatting with @shirhattihttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fshirhatti&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Cda60ad5c9a5740a3eb8e08d67a6f027f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636831014535285441&sdata=BitlcAtKo%2B6LgckW%2B9XNEBFkdD37kDFy70EHoCarnp4%3D&reserved=0 @vancemhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fvancem&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Cda60ad5c9a5740a3eb8e08d67a6f027f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636831014535285441&sdata=8j6YsHQBP0yr7lpOHY803VdKddDghNotV20U6sl0xUU%3D&reserved=0 and @tommcdonhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftommcdon&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Cda60ad5c9a5740a3eb8e08d67a6f027f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636831014535295441&sdata=bLFnY%2FnM2yDRwr7b7uIhBdsN0wdAuJi5zqZa6g9kDzs%3D&reserved=0 I promised I would flesh out a strawman this week. I'll be making updates to our design doc and feedback is welcome at any point. I'll continue to update status here.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fdiagnostics%2Fissues%2F109%23issuecomment-454184699&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Cda60ad5c9a5740a3eb8e08d67a6f027f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636831014535295441&sdata=zbj2wZ5HW7yQomqrPza2iCblX%2BV4xpZjWDlV8CgSFSs%3D&reserved=0, or mute the threadhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAFktXglRtREQHaM87i3tFNJI_CZuCxcTks5vDQOLgaJpZM4Z5Svp&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Cda60ad5c9a5740a3eb8e08d67a6f027f%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636831014535305455&sdata=p9GK14E6ESFy7%2B1h5z%2Fm98H1yBKoyRaTiIje%2BNF3pO4%3D&reserved=0.

rrelyea commented 5 years ago

There are 2 ways to reserve package id or package ids on nuget.org 1) publish a package (and keep it hidden if you like) 2) reserve a "namespace" or "id-prefix" of packages: https://docs.microsoft.com/en-us/nuget/reference/id-prefix-reservation

/cc @anangaur

noahfalk commented 5 years ago

Sorry I know I said I would flesh out a design over two weeks ago and I still don't have a complete draft. Partly I've been getting pulled into other issues and partly the design itself is taking longer than I was expecting. I do have my own series of updates in this branch https://github.com/noahfalk/diagnostics/tree/cli_tools_spec if you want to see my incomplete thoughts.

KathleenDollard commented 5 years ago

Noah,

This is quite nice, the examples were very helpful. You may want to add approximate help output. This may get built for you (like System.CommandLine does), but it will be nice to see your switches together and give them a description in this document.

You need to reserve all these names as soon as possible as NuGet packages. Immo Landwerth can help and let me know if you have trouble. This is super important.

Do you anticipate updating the terminal in response to this command or others (like trace):

dotnet counters monitor --processId 1902 process,runtime,aspnet

If so, could you reach out to @jonsequitur about when we'll have rendering support to do that on different shells

Maybe this could be a bit less verbose:

dotnet trace run -- /usr/bin/dotnet exec ~/my-app/bin/release/netcoreapp2.2/my-app.dll -some -args

Maybe switch argument and switch in convert. But that is probably a docs issue

I don't know what the --number switch might do.

How do you plan to build the REPL for analyze?

You probably need to tell your customers to uninstall dotnet-sos after they use it to install.

On the alternate installation mechanism that lets you avoid the SDK. Could you please file an issue against the CLI explaining what you want and why. We would like to support global tools where the runtime but not SDK is installed. I don't know if we can get it done in time for you, but we could use a specific reason somebody needs it.

You may also file an issue regarding wanting multiple tool-commands in one package.

I'd like to meet to sketch out the multi-purpose tool for comparison. There were a couple misconceptions in that text, but I there's a good chance you'll stick with the separate tools.

How would a stand-alone collector differ.

System.CommandLine has plans for response files, but it's a ways out. Nothing in CLI itself currently supports them.

You mentioned parsing - I highly recommend using System.CommandLine. It will save a ton of time and is used elsewhere in the div. It can support either -- or /. As you say, CLI only supports -- at present. Also, we request very careful use of one letter abbreviations and conversations to keep them consistent with other MS tools.

As far as the name - will this tool support running code that is not .NET Core?


From: Noah Falk notifications@github.com Sent: Thursday, January 31, 2019 5:03:22 AM To: dotnet/diagnostics Cc: Kathleen Dollard; Mention Subject: Re: [dotnet/diagnostics] Design the dotnet tools command-line user experience (#109)

Sorry I know I said I would flesh out a design over two weeks ago and I still don't have a complete draft. Partly I've been getting pulled into other issues and partly the design itself is taking longer than I was expecting. I do have my own series of updates in this branch https://github.com/noahfalk/diagnostics/tree/cli_tools_spechttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnoahfalk%2Fdiagnostics%2Ftree%2Fcli_tools_spec&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7C27ebb1276fc84071e22208d6877c7add%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636845366039907751&sdata=iCmibJ6x1R1EDAb3ySy3QibXqxgaTpCTSRgprGxc6n4%3D&reserved=0 if you want to see my incomplete thoughts.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fdiagnostics%2Fissues%2F109%23issuecomment-459336273&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7C27ebb1276fc84071e22208d6877c7add%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636845366039917748&sdata=Vt5akNCNGXaRdV45gzt35CA7s21khO%2BmCJlmJCEMMnA%3D&reserved=0, or mute the threadhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAFktXrEqr8ylyonHF3xk5NwZEI9wT7a0ks5vIumagaJpZM4Z5Svp&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7C27ebb1276fc84071e22208d6877c7add%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636845366039917748&sdata=qAg%2FHnd2bLjQ4LfhlGls780fmQoiP67JHjnN3Iw9eY8%3D&reserved=0.

noahfalk commented 5 years ago

I just posted a PR #120 that I welcome you guys to make mince-meat of (err ... give feedback on ; )

@KathleenDollard - I just saw your comment here now, thanks! I'll work on getting names reserved right away and then follow up with you on that feedback.

noahfalk commented 5 years ago

@KathleenDollard - I've reserved all the suggested tool names in the doc.

You may want to add approximate help output.

The new PR has a more extensive reference that should approximate what the help will eventually look like. I imagine we may want to add more descriptive text, but I didn't want to go too far down that route before getting feedback. Happy to continue refining as needed.

Do you anticipate updating the terminal in response to this command or others (like trace):

Yes, I was hoping some of the commands would have interactive GUI. If that is too much of an issue we could try to work around it, but I didn't constrain the design in that regard thus far.

Maybe this could be a bit less verbose: ...

I've eliminated the 'run' command entirely in this next revision to lessen the amount of implementation work we'd have to do behind it. We might want to implement something like it in the future though so the CLI feedback is still useful. Fundamentally the command I envisioned was:

dotnet-trace run -- <command_line_of_the_executable_to_trace>

It just happens that the command line of thing I was running wasn't short. I could have done a little better by not providing the full path to dotnet and assuming I'd be running it from inside the my-app directory where other dotnet project commands would be run. That gets it down to:

dotnet trace run -- dotnet exec bin/release/netcoreapp2.2/my-app.dll -some -args

I didn't follow what you meant "Maybe switch argument and switch in convert."

I don't know what the --number switch might do.

Hopefully clarified in the newer PR, dotnet-dump --number N takes N dumps over time. I was duplicating the prior art in ProcDump which has a -n argument that does the same thing.

How do you plan to build the REPL for analyze?

I didn't have a plan yet but its possible @mikem8361 already has one waiting to go based on some past work he did. Did you have a suggestion of something we could use or worried it would be an issue?

You probably need to tell your customers to uninstall dotnet-sos after they use it to install.

I didn't follow? Were you trying to save customers some disk space or is there another issue lurking?

You may also file an issue regarding wanting multiple tool-commands in one package.

While thinking about it, another nice option might be allowing multiple tools to be specified on the dotnet tool install command line. Looking through the usage I think it may wind up being a low pri issue in the end but I'm still happy to file either/both of those requests if you want them. Let me know if you have a preference.

I'd like to meet to sketch out the multi-purpose tool for comparison. There were a couple misconceptions in that text, but I there's a good chance you'll stick with the separate tools.

Thanks! I'd appreciate your help clearing those misconceptions up ; ) I'll set up a time when I am in the office tomorrow.

How would a stand-alone collector differ.

I followed up on that with more detail in the latest PR. Originally it was conceived that we'd save size on disk by separating the collection portion of the tools from the data processing/viewing parts of the command. Although true, thinking through it I believe there are some more salient differences that we should be concerned about first. My plan for now was just make sure we have some reasonable layering and if we need some persistent monitoring/collector later it can be its own tool that happens to reuse some of the same functionality in the currently proposed tools.

Also, we request very careful use of one letter abbreviations and conversations to keep them consistent with other MS tools.

I did make use of some, but I am happy to remove them if you know (or merely suspect) it would cause confusion with other tools.

As far as the name - will this tool support running code that is not .NET Core?

counters, trace, and sos have no utility outside of .Net Core right now. dotnet-dump could be used as a general purpose process dump tool though I had no intention to promote it for that role. In the future if dotnet-trace added support for other platform specific tracing mechanisms (ETW/lttng/perf) it could also be used in a more general purpose way but I think its relatively low value to go there and no need to market it for that purpose.

Thanks!

mikem8361 commented 5 years ago

How do you plan to build the REPL for analyze?

I didn't have a plan yet but its possible @mikem8361 already has one waiting to go based on some past work he did. Did you have a suggestion of something we could use or worried it would be an issue?

I’m curious @KathleenDollard if you have any recommendations for existing REPL implementations? I know you are recommending System.CommandLine for the tool command options, but I don’t think it handles REPL command and option parsing. I do have some past work I can start with, but I want to look into any existing implementations.

jonsequitur commented 5 years ago

@mikem8361 Can you expand on what "REPL command and option parsing" entails? I think System.CommandLine might be able to handle this and if it doesn't I'd like to understand the scenario better.

mikem8361 commented 5 years ago

It means that we have an interactive global tool that when started accepts “commands” with “options” at a prompt parses them and “runs” it. System.CommandLine seems to good at parsing the global tool options/subcommands themselves but I don’t see it working in a REPL.

$ dotnet dump /tmp/coredump.23333

sos ClrStack

sos GCRoot … exit $
jonsequitur commented 5 years ago

System.CommandLine doesn't currently provide interaction, but it can be used to parse subsequent input to the REPL, e.g. passing Console.ReadLine input to a parser. What is the grammar for your REPL input?

KathleenDollard commented 5 years ago

You may want to add approximate help output.

The new PR has a more extensive reference that should approximate what the help will eventually look like. I imagine we may want to add more descriptive text, but I didn't want to go too far down that route before getting feedback. Happy to continue refining as needed.

I think it is a really valuable exercise to create the help system as you want it to look in 3 years in a Word document or similar to plan for consistency across your expected surface area. Code is great for what's there now, but it isn't so good for planning what isn't there yet. You're creating the groundwork for that future CLI.

KathleenDollard commented 5 years ago

@jonsequitur Can you comment on the state of the renderer for updating screens and whether you are comfortable with teams taking a dependency on that part of the System.CommandLine work.

KathleenDollard commented 5 years ago

I didn't follow what you meant "Maybe switch argument and switch in convert."

That wasn't clear ;) Just a suggestion to make the option the argument and the argument the option.

KathleenDollard commented 5 years ago

You probably need to tell your customers to uninstall dotnet-sos after they use it to install.

I didn't follow? Were you trying to save customers some disk space or is there another issue lurking?

Global tools remain on the user's path. If there is no reason to run it again, that just sounds like trouble. For example, if you later change your installation (like to align with runtime only installations) someone might run the old out of date installer and mess up their installation.

jonsequitur commented 5 years ago

System.CommandLine.Rendering is still very unstable. That said, if this functionality is needed, I'm happy to work with anyone who wants to help move it forward.

KathleenDollard commented 5 years ago

As far as the name - will this tool support running code that is not .NET Core?

\Not really\

I asked because the different tools your supplying makes me wonder if it would be better to provide a top level command...something like (dotdiag, diagnet, ?).

dotdiag <all the stuff you have now>

This is just a discoverability question for your users. I agree that

dotnet diag <all hte stuff you have now> 

is too long. But going with the separate tools means that folks have to separately find, install and then remember their names. Combining them would supply the lovely experience:

dotdiag -h

as well as single installation.

mikem8361 commented 5 years ago

I see the "dotnet-sos" installer as the way to update and uninstall SOS after the initial install. The workflow would look like this:

Initial install:

dotnet tool install -g dotnet-sos
dotnet sos --install

When there is a new version of SOS or to check if there is a new SOS:

dotnet tool update -g dotnet-sos
dotnet sos --install

To uninstall:

dotnet sos --uninstall
dotnet tool uninstall -g dotnet-sos

Even though the workflow is a little wordy, it is the best I've come up with given what we have. If the cli global tool install/update/uninstall would allow some kind of call out that would allow us to run some code, this work flow could be a lot simpler.

mikem8361 commented 5 years ago

System.CommandLine doesn't currently provide interaction, but it can be used to parse subsequent input to the REPL, e.g. passing Console.ReadLine input to a parser. What is the grammar for your REPL input?

The grammar would be pretty simple: . The first part of this interactive mode needs to be more than Console.ReadLine; a user really needs command line editing and even a simple history. The second part of parsing the command and arguments may be something System.CommandLine can do. The third part is dispatching to some class/code that implements the command.

jonsequitur commented 5 years ago

The first part of this interactive mode needs to be more than Console.ReadLine; a user really needs command line editing and even a simple history.

This interaction model isn't something we support but it's becoming a common enough question that it might be worth building something to address it. System.CommandLine.Rendering exists to provide richer output capabilities. Richer input capabilities are likely also worthwhile but we left them out of scope for now. A spike on this might inform the design of our ITerminal abstraction.

The second part of parsing the command and arguments may be something System.CommandLine can do. The third part is dispatching to some class/code that implements the command.

These are both core System.CommandLine functionality, and there's nothing requiring you use them just to handle the input from Main. The parser will work against a string, not just against string[]. Binding and dispatch are in your control.

noahfalk commented 5 years ago

@KathleenDollard - I just updated the PR with the feedback from our chat (hopefully I remembered it propoerly). One follow-up around dotnet trace convert...

In our meeting I think you suggested to use the --input option instead of a raw argument, and above you suggested switching the option and argument. I also found the linux tool perf has a little prior art for trace conversion syntax:

perf convert --to-ctf -i input_trace_file

ctf is the name of the format in this case. 1) Is there a pattern dotnet tools follow for when to use --input vs. just making the argument? It made a little sad to think about putting --input on all the commands which use an input file, because they are fairly concise right now:

     dotnet trace pack mytrace.netperf
     dotnet dump analyze mydump.dmp 

2) I kind of like putting the format name in the option name as perf did. What do you think of:

     dotnet trace convert --to-speedscope foo.netperf
jonsequitur commented 5 years ago

The simplest guideline that I use is if it's optional, it should be an option, and if it's required (or it has a default value, i.e. your program requires some value), it should be an argument.

In grammatical terms, I think of it like this:

KathleenDollard commented 5 years ago

On what Jon said - it generally works that you pull off "dotnet" before thinking about it this way. In this example "trace" or "dump" are the subjects. But that's a great short analogy and I plan to include it when I update syntax guidelines. I would add that an argument only works well when there is a single fairly obvious/predictable thing it could be.

In addition...no (non-trivial) CLI that I have found is 100% consistent. The guidelines get you close enough for things to feel consistent, I hope.

Prior art is important, but I think consistency in the .NET space is a bit more important. I would definitely not make everyone type more because of prior art. I believe in your space, the argument is obvious.

Jon can you comment on how important ordering is for System.CommandLine and Posix. For Noah's case, it would be easiest to remember if it was

dotnet trace convert foo.netperf --to-speedscope


From: Jon Sequeira notifications@github.com Sent: Friday, February 15, 2019 5:52:46 AM To: dotnet/diagnostics Cc: Kathleen Dollard; Mention Subject: Re: [dotnet/diagnostics] Design the dotnet tools command-line user experience (#109)

The simplest guideline that I use is if it's optional, it should be an option, and if it's required (or it has a default value, i.e. your program requires some value), it should be an argument.

In grammatical terms, I think of it like this:

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fdiagnostics%2Fissues%2F109%23issuecomment-464057607&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Ce9a8bca50e8a42dfa7b908d6934cddba%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636858355677420350&sdata=DyGN3qYlqyN443O5ch3XfsIUbadUV93eVIw%2FRRe6PqE%3D&reserved=0, or mute the threadhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAFktXptmvTsxtDOYB66vg6RNzy5rMz-Dks5vNruugaJpZM4Z5Svp&data=02%7C01%7Ckathleen.dollard%40microsoft.com%7Ce9a8bca50e8a42dfa7b908d6934cddba%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636858355677420350&sdata=XYBUYO5F6A56xfu49s%2Fs73NfHbHLDowRcRpYv34%2FmvI%3D&reserved=0.

noahfalk commented 5 years ago

If the ordering is flexible I agree putting the argument first is a nicer presentation I'd happily make use of.

jonsequitur commented 5 years ago

System.CommandLine allows the options and arguments to be entered in any order after the command that owns them.

noahfalk commented 5 years ago

I'm going to go ahead mark this complete. I suspect we'll continue to make adjustments over time as we get more feedback, but this issue has served its purpose to get a nominal design in place.