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

Improvements to cross-platform path environment variable manipulation #2314

Open
W1M0R opened this issue Aug 21, 2024 · 2 comments
Open

Improvements to cross-platform path environment variable manipulation #2314

W1M0R opened this issue Aug 21, 2024 · 2 comments

Comments

@W1M0R
Copy link

W1M0R commented Aug 21, 2024

I find it helpful to run just recipes within a specific PATH environment. Here is an example:

path_sep := if os_family() == 'windows' {
  ';'
} else {
  ':'
}

aqua_bin := join(env("AQUA_ROOT_DIR"), "bin")
proto_shims := join(env("PROTO_HOME"), "shims")
proto_bin := join(env("PROTO_HOME"), "bin")
local_gobin := clean(join(source_directory(), ".go/bin"))
tms_bin := clean(join(source_directory(), "tms/build/bin"))
tms_node_bin := clean(join(source_directory(), "tms/node_modules/.bin"))

export PATH := if os_family() == 'windows' {
  aqua_bin + path_sep + proto_shims + path_sep + proto_bin + path_sep + local_gobin+ path_sep + tms_bin + path_sep + tms_node_bin + path_sep + env("PATH")
} else {
  # on Linux we don't use aqua and proto
  local_gobin+ path_sep + tms_bin + path_sep + tms_node_bin + path_sep + env("PATH")
}

the-job:
  echo "executing in the just path environment"

This approach is quite convenient as it allows me to set the PATH on windows and linux without shelling out to powershell in windows and bash/sh on linux. This also ensures that all my recipes have access to the tools that I want them to have access to.

One side-effect of this approach that is not ideal, but also not problematic for my use case, is that calling one recipe from another recipe leads to duplication in the path environment.

It would be great if the syntax around this pattern could be improved.

Some might suggest using direnv, but direnv doesn't work on windows. And just is already doing so well in this front, that needing to introduce another tool for this task, seems unnecessary.

Inspired by direnv, one approach might be to have a built-in function (env_add("PATH", "bla") or path_env_add("bla")) that knows how to work with the PATH environment variable (this hides away operating system details like the path separator and whether we need to work with PATH or Path and avoiding duplicate entries, etc):

aqua_bin := join(env("AQUA_ROOT_DIR"), "bin")
proto_shims := join(env("PROTO_HOME"), "shims")
proto_bin := join(env("PROTO_HOME"), "bin")
local_gobin := clean(join(source_directory(), ".go/bin"))
tms_bin := clean(join(source_directory(), "tms/build/bin"))
tms_node_bin := clean(join(source_directory(), "tms/node_modules/.bin"))

path_env_add(aqua_bin)
path_env_add(proto_shims)
path_env_add(proto_bin)
path_env_add(local_gobin)
path_env_add(tms_bin)
path_env_add(tms_node_bin)

the-job:
  echo "executing in the just path environment"

Another option could be to introduce functions that can join/concat strings using the os-specific path delimiter:

# join_list first param is the separator, and rest params are the strings to join
export PATH := join_list(os_path_delim(), aqua_bin, proto_bin, local_gobin, tms_bin, tms_node_bin, env("PATH"))

the-job:
  echo "executing in the just path environment"
@woutervh
Copy link

+10 for helper-functions to add directories to $PATH

@casey
Copy link
Owner

casey commented Sep 10, 2024

This definitely seems useful.

I think that regardless of the mechanism for constructing the PATH variable value, the way that it gets exported should be via an export PATH statement, since it's clear and uses functionality that already exists.

As for the mechanism for constructing the path variable value, I think maybe join_path_var(env("PATH"), …components) is probably the way to go. join_path_var would split all arguments using the system path variable delimiter, and then join them, discarding any duplicates.

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

No branches or pull requests

3 participants