-
Notifications
You must be signed in to change notification settings - Fork 514
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
Argument forwarding doesn't work with spaces in strings #647
Comments
As a workaround escape the double quotes with > just w -- -a \"D:\\foo bar baz.mp3\" |
Unfortunately this is an issue that I don't have a good solution for. Each recipe line is passed to the shell as a single string, and just has no knowledge of the shell's splitting and quoting rules. It might be possible to add logic to quote argument values when interpolating, but this would probably be flakey and not always do what you wanted. One possibility would be to allow arguments to be exported as environment variables, since I believe that most shells ignore spaces when interpolating into strings:
This is definitely ugly and weird though. |
Actually, I don't think exporting the argument as an environment variable does what you would want, so scratch that. |
I think this could be resolved by single quoting the values in the argument interpolation. For the Just invoc
Say our justfile is: foo +args:
ls {{args}} We'd get the desired behaviour by evaluating the |
There are a couple issue that I can think of with automatically adding quotes, one is that it might not always be desired. For example:
If the Another is that it's shell specific. Just supports both switching the shell with the |
Just to clarify I meant quoting each arg as parsed by the shell rather than the entire expansion.
Using this justfile I would expect an implementation of quoting on expansion to give:
Hmm yeah, this one is tricky. Intuitively it feels like Just should respect the argument quoting. Without applying some sort of quoting to the argument expansion I'm not sure how else this could be achieved (without introducing weird new syntax for expansion behaviours). Perhaps with #604 there could be an attribute to opt-out of quoting on expansion of variadic arguments? This would mean that expansion would "just work" by default, but the quoting could still be disabled to satisfy cases where it's not desired. |
This would have to be applied as the last step in interpolation. For example:
If you do Concatenating a variadic and non variadic argument is also tricky:
What should Also, if anything is inserted into a string literal, and not passed to the shell, then quoting would be undesirable:
|
Escaping |
@runeimp You mean that |
@Boscop Yes, |
There could be a function to shell escape its argument. |
I added a However, having to call the This would have some downsides:
I'm not sure such a setting would be worth it, and it might be better addressed in other ways. |
@casey The For example, with this justfile: run +args:
cargo run -- {{quote(args)}} When you type I agree with @runeimp that escaping spaces would be a solution: |
This is a limitation of how variadic arguments work. Just merges them into one space-separated string before they get to the The best way to solve this is probably to pass arguments positionally:
|
@casey Thanks, this worked! One nit: |
Whoops, too much Rust 😅 |
Does this work?
|
I think the recommended way to avoid splitting is to use |
@casey would you accept this contribution?
to quote each variadic arg like this: |
@MayCXC That would not work the way you think. In Although, maybe that could be helped with a |
maybe we can just make a separate parameter Line 2 in d3bbde0
set positional-args does stuff with them here https://github.com/casey/just/blob/d3bbde0c6049eb124d56fac396b670397e2c3977/src/justfile.rs#L335C18-L335C37 , so i think just already has everything it needs to do this, except a syntax.
|
how about with a |
Yah, @MayCXC, @laniakea64 is correct, by the time any variable gets to a function, it has already been turned into a string, so there's no way to know if it was a variadic parameter. Changing this would be a huge change to the code. I actually have a very wacky idea for how to fix this, but is such a huge undertaking that it is almost certainly not worth it. The idea is this: Just currently has a simple and safe static type system, because everything is a string. However, lists of strings are not supported, which prevents things like quoting variadic arguments, and also prevents implementing a lot of things that people want. So, what you could do is make it so that every value is a list of strings, with all existing constructs producing a length-one list, with the exception of variadic arguments, which produce a variable-length list of strings. For backwards compatibility, all existing functions must behave the same as they currently do, which means space-joining the list to produce a single value, and then operating on that value, but then you can add new functions which can do something different, for example quoting, or doing something for each entry in the list. But, like I said, this would be a massive code change, so probably isn't worth it. |
should i give it a shot and see if it's doable in like ~500LoC? you already have functions like Line 62 in d3bbde0
*NAME in a &[String] position, or a +NAME in a &str, &[String] position. VARGS is still just a string, so everywhere but function argument sequences should be able to ignore the change, and raise a parse error if a VariadicArgument value appears.
|
If you can do it simply, then why not, although I suspect you'll run into issues and it'll start to balloon. The core issue is that, by the time anything happens, the var arg is just a single string. |
Related to #631
The text was updated successfully, but these errors were encountered: