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

Feature request: Enable setting Variables in a Recipe #1023

Open
kurtbuilds opened this issue Nov 9, 2021 · 6 comments
Open

Feature request: Enable setting Variables in a Recipe #1023

kurtbuilds opened this issue Nov 9, 2021 · 6 comments

Comments

@kurtbuilds
Copy link
Contributor

kurtbuilds commented Nov 9, 2021

There's already a great docs section that talks about Setting Variables in a Recipe.

This is a feature that I frequently miss, and sometimes I want to avoid the suggested solution of using a single shell for the recipe using the she-bang line. (Typically, this is when I want the exit-code behavior of just, as using a she-bang line changes that functionality.)

It seems like it could be achieved by mimicking a shell's export behavior; that is, if the recipe line starts with export then add the resulting variable to the just process environment.

Since each line is within a shell, any current shell line with export NAME=variable is effectively a no-op, so this feature only extends, but does not modify, existing functionality.

@runeimp
Copy link

runeimp commented Nov 20, 2021

Though not likely, this could be a breaking change for some recipes. Maybe a special function you could call at the end of the recipe could give back the normal just exit code behavior? Might that be a possibility @casey ?

@casey
Copy link
Owner

casey commented Nov 20, 2021

I wouldn't do this as a breaking change, since that would be too disruptive, so this would have to have syntax that didn't conflict with normal shell syntax. Also, just is very static-analysis heavy, which I think is one of its strengths. I.e. it checks that all variable accesses are valid ahead of time, and resolves dependencies between them. So this feature would also have to have the same properties, i.e. not possible to misspell a variable.

@kurtbuilds
Copy link
Contributor Author

kurtbuilds commented Nov 20, 2021

Though not likely, this could be a breaking change for some recipes. Maybe a special function you could call at the end of the recipe could give back the normal just exit code behavior? Might that be a possibility @casey ?

I realized that the exit on non-zero codes can be recovered with #!/bin/sh -e. With that realization, it's easy for work around not having this feature in my current use.

This feature might still be nice, as I think setting variables within scripts, without needing to add the she-bang line, would be more intuitive for users seeing just for the first time. Specifically, I think it's surprising and somewhat counter-intuitive to have to change the execution context with a shebang line just to set variables.

@runeimp What scenario would be a breaking change? As I mentioned above, if the syntax was export NAME=value, such a line is a no-op in the shell-per-line context that just uses to execute recipes, so I don't see how that feature could break existing functionality. I'm curious to hear a possible counter-examples where it could be a breaking change, but I can't think of any.

Using the export syntax has the advantage, in my opinion, of being "less surprising" to new users, since it's giving just the exact same variable behavior that shells follow. Namely, a line NAME=value is a no-op unless there's a command on the same line, whereas export NAME=value causes subsequent executions to have NAME in its environment.

@runeimp
Copy link

runeimp commented Nov 20, 2021

@kurtbuilds hm, I'd thought of one immediately as I was reading the suggestion originally. But now I'm drawing a blank. Like I said it would be rare. But on the off chance it comes up it would likely be a complete nightmare to debug. And could effect recipes already in use that may be part of a CI/CD process. If I think of an, or remember my, example I'll update this issue. Sorry, my brain is done for the day I think. 😇

@page-down
Copy link

This feature might still be nice, as I think setting variables within scripts ...

Similar feature request was discussed in a previous issue.

#1011

It would be more useful to set the value computed within the shell process.

k := ""
demo:
  v=$(program); just --rpc-client k := "$v";
  $a="{{k}}"; if [ $a = "ok" ]; then just --rpc-client run-code-in-parent-just-process; \
  else just --rpc-client issue-cmd-from-child-process; fi

If this feature just sets a fixed value (defined at the time of writing the justfile) when running to the specific line, the usage scenario is limited.

Also, just is very static-analysis heavy ... I.e. it checks that all variable accesses are valid ahead of time ...

The above can be written as v=$(program); {| k := "$v" |};, after doing static analysis, dynamically converted to the corresponding shell command when executed. For example, v=$(program); just --rpc-client k := "$v";
The parent just process receives the instruction and changes the corresponding variable.

@giorgiga
Copy link

giorgiga commented Apr 7, 2023

A clean way to do this could be a recipe attribute with parameters that allows to declare environment variables should be passed on to subsequent recipes.

Something like:

[ env VAR1 VAR2 ]
recipe1:
    #!/bin/sh
    export VAR1="hello"
    export VAR2="world"

recipe2: recipe1
    #!/bin/sh
   echo $VAR1 $VAR2 # will output "hello world"

could work if just inspects the environment after running recipe1 and makes (only) the variables declared in env available before running recipe2 (there's probably some better name than "env" for this).

I'm using a shebang in recipe1 above, but the same thing may work for non-shebang recipes, as long as the environment is inspected after each line is executed.

This could also make things like this work

[env GREETING]
recipe:
    export GREETING="hello"
    echo "$GREETING world"

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