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

Sharing just arguments between invocations #1829

Open
poliorcetics opened this issue Jan 9, 2024 · 11 comments
Open

Sharing just arguments between invocations #1829

poliorcetics opened this issue Jan 9, 2024 · 11 comments

Comments

@poliorcetics
Copy link
Contributor

In a previous version --command-color was added to allow coloring the command that is run in the stdout output. This works well but it not transferred to inner calls to just:

inner arg:
    just something {{ arg }}

something arg:
    echo {{ arg }}
just --color-command red inner "I am a teapot"
just something "I am a teapot" # <--- colored red
echo "I am a teapot"           # <--- not colored red
I am a teapot

Looking at the manual, this is not something that is easily done right now. It can also cause problems with --yes: top level recipes will be automatically confirmed but not inner ones

I see at leastfour possible solutions:

  1. Allow configuring just through individual env vars: e.g, JUST_CONFIRM="yes" or JUST_COMMAND_COLOR="red" which would be automatically read
  2. Allow configuring just through a single env vars: JUST_EXTRA_ARGS="--yes --command-color red" which would be automatically read
  3. Add a function to inherit args in inner commands: just just_args() something ... in the recipe above
  4. Add a setting to inherit args in inner commands: set inherit-just-args := true

I'm unsure which is the best. The env vars solutions will make it easy to share arguments, for example in CI scripts but could be surprising (maybe a log at the start, saying "using ... from env" ?). It's already something done by lots of programs though, so I don't think that's too bad.

Solutions 3 and 4 have the issue that they need to be set in each Justfile to work, which will be frustrating when adding a new one in a subdirectory for example. Solution 3 especially needs to be set on each invocation, which is quite invasive but offers lots of control.

@laniakea64
Copy link
Contributor

  1. Allow configuring just through individual env vars: e.g, JUST_CONFIRM="yes" or JUST_COMMAND_COLOR="red" which would be automatically read

+1 to this approach and it'd be consistent with existing behavior.

In the case of --command-color, if it would also set the hypothetical JUST_COMMAND_COLOR env var, this would solve #1702 as a side effect. Given the rationale why --command-color was added, it anyway seems wise to have --command-color inherited by default.

@poliorcetics
Copy link
Contributor Author

Oh I didn't know about JUST_UNSTABLE, that is certainly a good point for solution 1, thanks!

@casey
Copy link
Owner

casey commented Jan 9, 2024

I think that some combination of environment variables, and a setting, might be a good approach here. Automatically exporting and inheriting arguments would break backwards compatibility, so a setting would be necessary so that users can opt-in on a per-justfile basis. For example, if users used just --yes on the parent invocation, changing child invocations to behave as if --yes was set would be a change in behavior.

So, if something like set inherit were used, just would automatically export some subset of environment variables, and then child just processes would read them. The setting could be in parent justfiles, with something like set export-args, or in children, with something like set inherit-args.

This setting can be initially made unstable, so that we can tweak which settings are exported. I suspect that there might be some tricky edge cases.

I think that something like --yes or --quiet would be good to start with. The environment variable names should match the argument names, so for --yes, the environment variable would be called JUST_YES, and any value other than the empty string would be interpreted as true.

@casey
Copy link
Owner

casey commented Jan 9, 2024

I labeled this as a good first issue, in case anyone wants to take a crack at it.

@poliorcetics
Copy link
Contributor Author

I'm starting to take a look at this and I have a question: should the setting be "global" set export-args-as-env := true or precise set-export-args-as-env := ["JUST_YES", "JUST_COLOR"] ? Or both maybe ?

@laniakea64
Copy link
Contributor

or precise set-export-args-as-env := ["JUST_YES", "JUST_COLOR"] ?

👍 Nice idea. +1 for the precise proposal. This syntax is intrinsically backwards-compatible with future additions to exported/exportable arguments, and it provides more functionality for justfile authors.

I think naming the setting export-args as casey proposed above would be equally clear while also being more concise.

@casey
Copy link
Owner

casey commented Feb 11, 2024

I like the idea of explicitly specifying what you want to export. There's already a set export, so another name is probably better. And there are things other than args, like settings, which we want to export, so export-args isn't great.

@starthal
Copy link

An idea that might dovetail with this:

Add a function just() which is sugar for (just_executable() + ' --justfile ' + justfile() + ' ' + just_options() + ' -- ')

where just_options() returns the options passed in to the current invocation.

Then I can recurse with

recurse:
    {{ just() }} recurse

while ensuring that

  • No PATH change in the shell stopped me from invoking the binary, or invoked a different version
  • An override of the working directory is preserved
  • Any other non-recipe args are preserved, including --set overrides.

Having written this out, I realize it sounds a lot like $(MAKE) and $(MAKEFLAGS), with the confusion that entails. But it may be an alternative to forwarding options through the environment.

@poliorcetics
Copy link
Contributor Author

That's another option but it has a problem: in a CI environment, it's easier to export JUST_YES=1; export JUST_COLOR=always and all present and future just calls will work on the first try as expected, whereas the {{ just() }} option means each new just call in the CI needs the arguments copied, which I don't think is nice to use

It's the same for local use too, I would like to be able to set JUST_COLOR and never have to worry about it again for normal use

@laniakea64
Copy link
Contributor

An idea that might dovetail with this:

Add a function just() which is sugar for (just_executable() + ' --justfile ' + justfile() + ' ' + just_options() + ' -- ')

where just_options() returns the options passed in to the current invocation.

Although that could be useful, it is not a good "alternative" to environment variables. In addition to what @poliorcetics said, it would be harder for recipes to use the options for something other than passing to recursive just invocations. Also, with the way just currently works, this function might be problematic where justfile() or just_executable() contain whitespace.

@loichyan
Copy link

loichyan commented Jul 30, 2024

Another possible approach:

Export all variables to a single JUST_VARIABLES in some structural format (maybe JSON, it can be serialized or deserialized almost anywhere).

Provide a function var(<name>, <default>), which behaves like env(...), except that it reads from JUST_VARIABLES.

In justfile, when set inherit (or perhaps set export-variables):

  1. If JUST_VARIABLES is not set, export all variables to JUST_VARIABLES;
  2. Otherwise, update them.

Edit: We can also export each variable to different variables, like JUST_VARIABLE_foo, this should be more convenient to check or override. But this can create a lot of env variables.

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