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

command line separation with -- broken in several context #1695

Closed
borkdude opened this issue May 23, 2024 · 10 comments
Closed

command line separation with -- broken in several context #1695

borkdude opened this issue May 23, 2024 · 10 comments
Projects

Comments

@borkdude
Copy link
Collaborator

Given a script cmd.clj:

$ cat /tmp/cmd.clj
(prn *command-line-args*)

The following should not have the hyphen probably?

$ bb -f /tmp/cmd.clj -- asdf sdf
("asdf" "sdf")
$ bb /tmp/cmd.clj -- asdf sdf
("--" "asdf" "sdf")
$ bb -- asdf sdf <<< '*command-line-args*'
nil
$ bb repl -- asdf sdf <<< '*command-line-args*'
----- Error --------------------------------------------------------------------
Type:     java.lang.Exception
Message:  File does not exist: asdf
@borkdude borkdude added this to High priority in Babashka May 23, 2024
@bobisageek
Copy link
Contributor

I agree (I think) that in all of these cases, the -- should not be an arg, and *command-line-args* should align with the first example.
The repl example is sort of interesting, but I guess at the end of the day, the idea of passing args into a REPL isn't really any different.

@felixdo
Copy link

felixdo commented May 24, 2024

Hmm, we have -- in use in git, also in kubectl. For those to work I guess they need -- as an arg no?

@bobisageek
Copy link
Contributor

Regarding scenario 2 (file name without -f), this appears to be the special handling for files in main/parse-opts. If the arg is a file,

(parse-file-opt options opts-map)
gets called, which puts everything after the file name (including --) into :command-line-args.
The first idea that comes to mind is doing a recur thing sort of like how subcommands are handled, except maybe assoc'ing :file onto opts-map, and recurring with (next options) and the updated opts-map. I'm not too sure yet if that has unwanted consequences, because parse-file-opt is called from two places, so tweaking that could be problematic.

There's another potential scenario, which is a file that doesn't exist (bb i-dont-exist.clj -- asdf), and can get set to :file if we get to the fallthrough at

(assoc opts-map
(if (str/ends-with? opt ".jar")
:jar
:file) opt
:command-line-args (next options)))))))

I think this is actually what's happening in scenario 4, because if I'm working this out correctly,
("--repl")
(let [options (next options)]
(recur (next options)
(assoc opts-map
:repl true)))

means that when --repl (or repl which gets re-written to --repl), this code consumes both --repl and the option after it, which in case of scenario 4 means the -- is getting swallowed. Adding a throw-away option eliminates the file not found error:

$ bb repl -- asdf sdf
----- Error --------------------------------------------------------------------
Type:     java.lang.Exception
Message:  File does not exist: asdf

$ bb repl junk -- asdf sdf
Babashka v1.3.190 REPL
...

The fact that *command-line-args* is nil is (I think) sort of orthogonal, and I think it's tied to core/command-line-args only being bound in the expressions path in main

core/command-line-args command-line-args]

@borkdude
Copy link
Collaborator Author

@bobisageek If you want to work on a PR to address (some of) these, you're welcome to do so.

@bobisageek
Copy link
Contributor

I'm trying to think through some of the possibilities where a change here could change existing behavior in an undesired way.

There are a couple existing tests

(is (= ["--version"] (bb nil (fs/file "test-resources" "script_with_overlapping_opts.clj") "--version")))
(is (= ["version"] (bb nil (fs/file "test-resources" "script_with_overlapping_opts.clj") "version")))))

that I think sort of imply "if the first argument is a file (with no -f), then everything afterwards is an arg to the file".
Put a different way, 'fixing' scenario 2 might break those existing tests (and obviously, scripts that rely on that).
If we sort of flip scenario 2 around to match those tests:

; this is the existing test - pass a file without `-f` and we don't process any more args...
(main/main "test-resources/script_with_overlapping_opts.clj" "--version")
("--version") ; this is the prn of *command-line-args*
=> 0 ;exit code

; but if we use `-f`, then subsequent args are still processed as potential args to `bb`
(main/main "-f" "test-resources/script_with_overlapping_opts.clj" "--version")
babashka v1.3.191-SNAPSHOT ; just print the version text, script effectively does nothing
=> 0

So, as a solution that I think would preserve that existing behavior, we could special-case that if we're 'inferring' a file (as opposed to being told with -f), then remove -- if it's the first argument after the file name. I'm sort of not crazy about that approach (feels a little dirty to me).
More generally, I wonder if we want to think about the with-and-without -f scenarios working the same way. This might fix scenario 2, but I think would break the existing test.
I'd like to get some feedback before pushing too far down one road or the other, because it feels like a trade-off situation.

@borkdude
Copy link
Collaborator Author

OK, we can ignore changing -f right now I guess. The real issues were the latter two in the original post. Let's just focus on those then.

@borkdude
Copy link
Collaborator Author

Somehow the docker step on master started acting up after merging this. Not sure if it's related.

@bobisageek
Copy link
Contributor

The Github action 'docker' looks like it's disabled. Is there a different docker step I should be looking at?

@borkdude
Copy link
Collaborator Author

CircleCI

@borkdude
Copy link
Collaborator Author

Oh I see:

:err "curl: (23) Failed writing received data to disk/application\n

This has nothing to do with your PR.

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

No branches or pull requests

3 participants