Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Add support for '--' argument separator #159

Merged
merged 1 commit into from
Sep 26, 2016
Merged

Add support for '--' argument separator #159

merged 1 commit into from
Sep 26, 2016

Conversation

natemcmaster
Copy link
Contributor

@natemcmaster natemcmaster commented Sep 6, 2016

Depends on dotnet/extensions#145. ✅ merged

Lays the foundation for allowing dotnet-watch to have command line flags such as --verbose.

Update README.md.

cc @victorhurdugaci

@natemcmaster natemcmaster force-pushed the namc/arguments branch 2 times, most recently from 7c24650 to 3c816f3 Compare September 6, 2016 22:56
var options = CommandLineOptions.Parse(args, _out);
if (options == null)
{
_error.WriteLine("Unexpected error parsing command line arguments");
Copy link
Contributor

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?

Copy link
Contributor Author

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...?

@victorhurdugaci
Copy link
Contributor

Is there any plan to add any arguments right now? If not, I'm not sure that we want this change yet /cc @glennc

@natemcmaster
Copy link
Contributor Author

I was thinking of adding --log <LEVEL> and/or --verbose

@victorhurdugaci
Copy link
Contributor

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.

@natemcmaster
Copy link
Contributor Author

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. --log or --polling).

cc @glennc

@natemcmaster
Copy link
Contributor Author

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'

Input How dotnet-watch splits args into the sub command
dotnet watch --help dotnet watch --help / (no sub args)
dotnet watch -- --help dotnet watch / --help

But let's say we start adding more options, like --verbose, here are implications:

Input How dotnet-watch splits args into the sub command
dotnet watch --verbose -- run --verbose -- a b c dotnet watch --verbose / run --verbose -- a b c
dotnet watch -- run --verbose -- a b c dotnet watch --verbose / run --verbose -- a b c
dotnet watch run --verbose -- a b c dotnet watch / run --verbose -- a b c
dotnet watch --verbose run dotnet watch --verbose / run
dotnet watch -- --verbose run dotnet watch / --verbose run
dotnet watch --verbose --verbose run Error!
dotnet watch --verbose -- --verbose run dotnet watch --verbose / --verbose run

### How To Install

Add `Microsoft.DotNet.Watcher.Tools` to the `tools` section of your `project.json` file:

```
```js

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

json?

Copy link
Contributor Author

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.

@natemcmaster natemcmaster force-pushed the namc/arguments branch 2 times, most recently from 8c17c45 to 1bd19dc Compare September 20, 2016 00:26
@natemcmaster
Copy link
Contributor Author

Ping @glennc. Are you okay with "--" support in syntax for dotnet-watch?

@natemcmaster
Copy link
Contributor Author

Talked with @glennc. We're okay moving ahead with this.
cc @moozzyk

Copy link
Contributor

@moozzyk moozzyk left a 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
Copy link
Contributor

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)
Copy link
Contributor

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",
Copy link
Contributor

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)?

Copy link
Contributor Author

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)
Copy link
Contributor

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)

Copy link
Contributor

@moozzyk moozzyk Sep 24, 2016

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

Copy link
Contributor Author

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" } })]
Copy link
Contributor

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;
Copy link
Contributor

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?

Copy link
Contributor Author

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; }
Copy link
Contributor

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; }
Copy link
Contributor

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.

Copy link
Contributor

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...

Copy link
Contributor Author

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?

Copy link
Contributor

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();
Copy link
Contributor

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.

@natemcmaster
Copy link
Contributor Author

🆙 📅


public Program()
public Program(CancellationToken cancellationToken)
Copy link
Contributor

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)..

Copy link
Contributor Author

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.

@moozzyk
Copy link
Contributor

moozzyk commented Sep 26, 2016

One small comment and then 🚢🇮🇹

Also refactors command line parsing into a separate class.
@natemcmaster natemcmaster merged commit f90594a into dev Sep 26, 2016
@natemcmaster natemcmaster deleted the namc/arguments branch September 26, 2016 17:26
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants