casey / casey/just

Improvements to cross-platform path environment variable manipulation

Open
#2,314 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
35.8k
Forks
846
Avg merge
27m
Merged PRs (30d)
3

Description

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

```justfile
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):

```justfile
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:

```justfile
# 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"
```

Contributor guide

Open the contributing guide

Research direction

No file or test is named. Start by reviewing the existing env(), os_family(), join(), and export PATH behavior, then compare the proposed path_env_add() and os_path_delim()/join_list() APIs across Windows and Unix. Done means one consistent cross-platform approach is selected, implemented, and covered for separators, Path/PATH handling, and duplicate entries.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.