Skip to content
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

Unable to pass arguments starting with a dash to ceylon run #1228

Closed
loicrouchon opened this issue Aug 1, 2013 · 23 comments
Closed

Unable to pass arguments starting with a dash to ceylon run #1228

loicrouchon opened this issue Aug 1, 2013 · 23 comments
Assignees
Milestone

Comments

@loicrouchon
Copy link
Member

Launching command ceylon run mymodule/1.0.0 -Dfoo=bar ends with the following error:

ceylon run: Unrecognised short option '-D' to command 'run' (in combined options '-Dfoo=bar')

Usage:
ceylon run [--d] [--offline] [--rep=<url>...] [--run=<toplevel>] [--sysrep=<url>] [--verbose[=<flags>]] [--] <module> [<args...>]

Did you mean?
    --d

Run 'ceylon help run' for more help

(same issue with ceylon run-js)

However, without the dash (ceylon run mymodule/1.0.0 foo=bar), it's working fine

This is an issue because it means that you can't use parameters starting with a dash in a ceylon applications

@FroMage
Copy link
Member

FroMage commented Aug 1, 2013

This used to work before we moved to git-like tools.

@quintesse
Copy link
Member

Btw, I think that if you put -- before the module name it will work (I mean like this ceylon run -- mymodule/1.0.0 -Dfoo=bar)

@FroMage
Copy link
Member

FroMage commented Aug 1, 2013

Perhaps, but it shouldn't have to

@quintesse
Copy link
Member

Sure, but it was so @loicrouchon knows there is a "work-around" so he can continue what he was doing.

@FroMage
Copy link
Member

FroMage commented Aug 2, 2013

@tombentley if this is more than an hour's work, it will have to wait for 1.0

@gavinking
Copy link
Member

@quintesse want to take a look at this one?

@quintesse
Copy link
Member

@tombentley I didn't take too good a look at this, but at far as I can tell -- is the only way to force that the rest of the arguments aren't considered as options, right? And this is probably because the basic parsing is done without knowing anything about what options exist and if they take an argument or not.

I deduce this because I can write ceylon compile --user --help test which will show the help text instead of taking --help to be the argument to --user. A generic parser (that doesn't know about possible options) can of course never solve this ambiguity (AFAIK. Btw --user=--help will of course work just fine).

So this is most likely not an easy fix, right?

@quintesse
Copy link
Member

Of course another option would be to do what the language module does with its namedArgumentValue() which is to not allow the form --argtakingoption ---value-that-starts-with-dash (meaning that you could only write something like that using the concatenated form --argtakingoption=---value-that-starts-with-dash)

@quintesse
Copy link
Member

Of course this still won't be able to fix the problem for something like ceylon run --user mymodule/1.0.0 -Dfoo=bar if the parser doesn't know wether --user takes an argument or not.

@tombentley
Copy link
Member

--help is a bit of a special case that's handled by the top level tool.

We could (I suppose should) fix the parsing so that it treated the -Dfoo=bar as an argument to the run tool, rather than an option to it. There would still be an ambiguity if the ceylon application wanted to have an option named the same as any of the options supported by the run tool (e.g. --run). I'm not sure what the "right" thing to do in that case would be, I think requiring -- for it would be fine.

@FroMage
Copy link
Member

FroMage commented Sep 2, 2013

Can't we just stop processing arguments the minute one doesn't start with -? I want all things starting with - (or --) following the module name to be passed as-is to the Ceylon program.

@quintesse
Copy link
Member

@FroMage the thing is that the parser doesn't know anything about arguments (at least that's how I understand things) so it doesn't know what "following the module name" means.

@tombentley
Copy link
Member

We could use an @Rest property to collect all the options which we can't match against the tool's options and pass those to the ceylon application. Not certain whether that will respect the relative ordering of options and arguments though:

ceylon run mymodule/1.0.0 baz -Dfoo=bar

@quintesse
Copy link
Member

But that wouldn't be correct, the program we're running might have any number of similar options. The parser should be clever enough to figure out that it should stop parsing at the first non-option argument.

@quintesse
Copy link
Member

I would imagine the parser to behave somewhat like this:

  1. get the first argument
  2. end if it doesn't start with - or --
  3. look up the corresponding attribute in the tool
  4. check if it needs a value
  5. set the value using the current argument (if of the form --foo=bar) or use the next argument
  6. get next argument
  7. goto 2

what's left over should be the non-option arguments to the tool.
The tool itself can then decide what to do with those.

@ghost ghost assigned quintesse Sep 6, 2013
@quintesse
Copy link
Member

Ok, I'm seeing a situation where we actually allow option to appear after arguments to the tool. An example is ceylon help --output=/foo/bar ..... This should be disallowed then, right? Because I don't see how we can detect a situation like ceylon run --run test.run mymodule/1.0 --myoption foobar and at the same time allow the other command line to parse as well.

@FroMage
Copy link
Member

FroMage commented Sep 6, 2013

I don't get your comment. In ceylon help --output=/foo/bar .... there are only options to the tool. There's nothing without a - after the tool name help.

@quintesse
Copy link
Member

Well actually what you call the "tool name" is an argument to the toplevel tool "ceylon".

But later thinking about it I thought this should actually be passed on to the sub tool and for that one the option should actually be it's first argument, so I'm not sure why it doesn't work the way I thought it would. I need to study it some more.

@quintesse
Copy link
Member

Ok, the actual example is something like this: ceylon help compile --output=/foo/bar
So the tool being activated is help which gets passed compile --output=/foo/bar.
According to the rules that would make ceylon run possible we would need to stop after the first non-option argument (in this case compile) and treat the rest as "left over" arguments that the tool itself will know how to handle. In this particular case that would mean that the help tool a) does not get it's output attribute set and b) will complain about unknown extra arguments.

@quintesse
Copy link
Member

The only solution I can see is to require that any options appear before the first non-option argument. (eg. ceylon help --output=/foo/bar compile)

@quintesse
Copy link
Member

Maybe there's another option: for tools that do not define a @Rest annotation (which are most of them) we will do what we do know and continue parsing options until the end of the command line while for tools that do define them we stop at the first non-option argument. That would be a usable compromise.

quintesse added a commit to ceylon/ceylon-common that referenced this issue Sep 7, 2013
@quintesse
Copy link
Member

Ok, seems to work just fine. Closing.

@tombentley
Copy link
Member

@quintesse this is roughly the way I was expecting to fix this, though I was thinking of adding a flag to @Rest to control the "end of options" behaviour. But this is sufficient for now I think. Thanks!.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants