-
Notifications
You must be signed in to change notification settings - Fork 74
Add support for '--' argument separator #159
Conversation
7c24650
to
3c816f3
Compare
var options = CommandLineOptions.Parse(args, _out); | ||
if (options == null) | ||
{ | ||
_error.WriteLine("Unexpected error parsing command line arguments"); |
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 print details? If not, how do I know the error so I can fix it?
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 "should never happen" condition...maybe I should use Debug.Assert instead...?
Is there any plan to add any arguments right now? If not, I'm not sure that we want this change yet /cc @glennc |
I was thinking of adding |
Sync with @glennc , I think he should approve that. Right now you have way to pass it. I think if the number of options we plan to add to dotnet watch is small (<5), we shouldn't complicate the command line, especially if those options are used by very few people. |
Most usages don't need '--'. It's an optional arg that makes definitive which args are "mine" vs "theirs". IMO it's not a matter of complicating/simplifying the command line. This is about env variables. Long environment var names are hard to discover and clunky to set. Adding '--' would allows us to do command line args for these settings (e.g. cc @glennc |
Talked with @glennc. The clarify this, the primary purpose of '--' is to make deterministic the split between which args belong to dotnet-watch (subset 1) and which should be passed through to the inside command (subset 2). The only good example we have of this at the moment is '--help'
But let's say we start adding more options, like
|
3c816f3
to
3333b1c
Compare
### How To Install | ||
|
||
Add `Microsoft.DotNet.Watcher.Tools` to the `tools` section of your `project.json` file: | ||
|
||
``` | ||
```js |
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.
json
?
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.
The json
highlighter doesn't parse the '...' well.
8c17c45
to
1bd19dc
Compare
Ping @glennc. Are you okay with "--" support in syntax for dotnet-watch? |
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.
Looks mostly good - just a few minor issues.
[InlineData(new object[] { new string[0] })] | ||
public void HelpArgs(string[] args) | ||
{ | ||
// arrange |
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.
nit: I am not sure what is the style in this repo but I personally don't find these comments useful.
.WatchAsync(projectToWatch, options.RemainingArguments, _cancellationToken) | ||
.Wait(); | ||
} | ||
catch (AggregateException ex) when (ex.InnerExceptions.Count == 1 && ex.InnerException is TaskCanceledException) |
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.
you could make MainInternal async and then catch only TaskCanceledException. You would .Wait()
in Main instead of here.
var app = new CommandLineApplication(throwOnUnexpectedArg: false) | ||
{ | ||
Name = "dotnet watch", | ||
FullName = "Microsoft DotNet File Watcher", |
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 correct casing (DotNet)?
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 looks a little weird, but it's what the DotNet team uses.
throw new ArgumentNullException(nameof(args)); | ||
} | ||
|
||
var app = new CommandLineApplication(throwOnUnexpectedArg: 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.
what happens in an unexpected argument appears before --
? (e.g. dotnet watch --help --bogus
)
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.
As per https://github.com/dotnet/cli/blob/rel/1.0.0/src/dotnet/CommandLine/CommandLineApplication.cs#L16-L18 I guess --bogus
will be added to RemainingArgs and then we will just exit In Program l. 82
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.
--bogus will be added to RemainingArgs
Yes, that's what will happen. The heuristic for RemainingArgs is: RemainingArgs = all args starting with the first unrecognized arg or the first arg after the '--'
[Theory] | ||
[InlineData(new object[] { new[] { "-h" } })] | ||
[InlineData(new object[] { new[] { "-?" } })] | ||
[InlineData(new object[] { new[] { "--help" } })] |
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.
add a case where there is an argument after --help
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.DotNet.Watcher.Tools | ||
{ | ||
public class Program | ||
{ | ||
private readonly ILoggerFactory _loggerFactory; | ||
private readonly CancellationToken _cancellationToken; | ||
private readonly TextWriter _error; |
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 being used at all?
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.
Not at the moment. Will remove.
{ | ||
internal class CommandLineOptions | ||
{ | ||
public bool IsHelp { get; set; } |
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 should not be settable outside this class.
internal class CommandLineOptions | ||
{ | ||
public bool IsHelp { get; set; } | ||
public IList<string> RemainingArguments { get; set; } |
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.
Not that this matter as much (you can always change contents) but it should not be settable outside this class.
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.
actually both could have just getters...
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.
IReadOnlyList with a private setter?
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.
I would stick just to IList<string>
with a private setter. No reason to make it more complicated than this...
|
||
app.HelpOption("-?|-h|--help"); | ||
|
||
var options = new CommandLineOptions(); |
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.
nit: move down where you actually need it.
🆙 📅 |
|
||
public Program() | ||
public Program(CancellationToken cancellationToken) |
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 ctor needed at all? Why not make the other one public and remove this one? We don't seem to use it (unless there are some tests using it)..
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.
Yeah, can be removed. Opened this PR so long ago I can't remember what I was thinking when I added the public/internal ctor split.
One small comment and then 🚢🇮🇹 |
dc7900a
to
9026b61
Compare
Also refactors command line parsing into a separate class.
9026b61
to
f90594a
Compare
Depends on dotnet/extensions#145.✅ mergedLays the foundation for allowing dotnet-watch to have command line flags such as
--verbose
.Update README.md.
cc @victorhurdugaci