J.U.S.T.

just

When working on a project, it often becomes necessary to run many long commands. Similar to how a makefile connects targets with a string of commands, just gives an easy way to create a set of targets to execute easily. Unlike a makefile, it has two key distinctions

  • It’s not a makefile, but uses a Justfile in bash instead. Bash is easier than make for simple tasks

  • It works on Windows (when bash is installed via Git for Windows or similar), macOS (which uses bash 3.2) and Linux with no additional dependencies.

Features

  • Tab completion (.just)

  • Comment generated help

  • Subcommands (e.g. just program run, run can be a subcommand of the program target)

  • Executing multiple targets in one call

See also

Justfile

Blah justfile

.just

Tab completion for bash

just help

Print out basic help based on the comments it the Justfile. In order to achieve this, case statements and comments need to be structured in a specific way for the parser to pick up. The same mechanism is used by tab completion in bash

Note

Currently this does not work for all bash cases. A few bash patterns are matched to make this behavior working, since bash does not have source reflection.

Basic example:

In the simplest case, a regular case pattern followed by )# (with optional spaces) will be picked up by help

foo) # Runs the foo routine

Long comment lines

A long comment can be split up into many lines by ending a line with \ (that means no space after \), and the comment on the next line continue.

command) # To write a long help message, end the line in a backslash (\) \
         # and start the next line with a # to continue the comment. \
         # Can be as long as you want.

Multiple targets at once:

The pattern pattern1|pattern2...)# will also be parsed as a single help entry

cat|dog) # Routine for cats and dogs

Multiple targets:

You can actually add any of the other patterns as a comment for the sole purpose of populating the help and tab completion

# cat) # Comment just for cat
# dog) # Comment just for dog
cat|\
dog) # A comment here would be for both cat and dog, but not needed

Subcommand example:

foo_cat) # Runs the foo routine for cat
foo_dog) # Runs the foo routine for dog

Commenting extra help subcommand:

# foo_a) # Runs the foo routine for a
# foo_b) # Runs the foo routine for b
foo_*)
## foo_c) # Runs the foo routine for c, but don't tell anyone

The foo_a and foo_b are added to tab complete and help, but using more than one # will disable that line all together. So foo_c is ignored and does not show up in help or tab complete.

Advanced Expansion subcommand array:

When you have a list of subcommands for a command in an array, then that can use that array to generate help/tab completion entries

# Example array
MY_ARRAY=(cat dog)

...

# catch_{MY_ARRAY}) #Catch animal
catch_*)

Help, tab complete, etc. will automatically be expanded to cat and dog. Very useful for DRY and for programmatically determined subtargets. The subtarget name is appended to the end of the comment. So this example will read

catch
    cat - Catch animal cat
    dog - Catch animal dog

Note

Help and tab completion use the exact same mechanism. Everything that adds an entry to the help is adding an entry to tab completion.

JUST_PRELOAD

Preloads a special source file before anything else loads.

In rare case that the project environment file is too late in the just loading, use this file. It is suggested to set the value in the JUST_SETUP_SCRIPT, which defaults to setup.env.

Note

This is left around for debug purposes really, probably never needed.

Note

Must not be set in the project environment files i.e. cannot be set in local.env, project env file or local_post.env. It will not have the desired effect, as this is too late in the load chain. Instead, it can either be exported before calling just (not recommended unless in a container or VM) or exported in the setup file.

JUST_VERBOSE
Values:
  • 1 - Prints any dryrun-able commands as they are executed

  • 2 - Basic bash verbose. Uses set -v

  • 3 - Fully verbose. set -xv plus a useful PS4

JUST_VERBOSE sets verbosity level of just execution. Useful to debug problems, especially in the just executable.

Note

Must not be set in the project environment files i.e. cannot be set in local.env, project env file or local_post.env. It will not have the desired effect, as this is too late in the load chain. Instead, it can either be exported before calling just (not recommended unless in a container or VM) or exported in the setup file.

..envvar:: JUST_IGNORE_EXIT_CODES

A regular expression that represents exit codes that will result in a just stack trace not being printed out. This is good for handling errors that are expected to happen, and do not need a misleading stack track when you know the problem is a known issue, like a missing file, etc… Default: 0, (disabled).

Examples:

# Justfile example
just_target)
  local JUST_IGNORE_EXIT_CODES=2
  bash -c "exit 2"
  ;;

# More example values
25      # Only 25 is ignored
24$|^25 # 24 or 25 is ignored; ^ is implied at the beginning and $ at the end. So it is really: "^24$|^25$"
2.      # 20-29
.*      # All exit codes
3.$|^72 # 30-39 or 72
$|5|^   # Any code with a 5 in it, 5, 15, 25... 50-59, etc
JUST_IN_SCRIPT

JUST_IN_SCRIPT is an unexported variable set by just. Useful in other scripts for determining if they are being sourced by just or not.

Currently one use of this is dual purposing a file, so that it behaves differently when sourced by just or by a user on the prompts

JUST_USER_CWD

Although just does not have to be run from the just project’s root directory, some commands (e.g., docker compose, but also parts of just proper) expect to be run from the project’s root directory. Typically, the Justfile will cd from the current working directory to the project’s root directory, as specified by ${PROJECT_PREFIX}_CWD (thereafter the project’s CWD). JUST_USER_CWD tracks the working directory from which a just command was run.

JUSTFILE

An optional variable for the location of Justfile. The default Justfile that just_common.bsh _just_load_justfile searches for is called Justfile. In order to change this default behavior, this environment variable needs to be set so that just knows what file name to look for, usually not recommended

See also

just_common.bsh _just_load_justfile

Function responsible for loading Justfile

dir_tools.bsh parent_find_files

Function responsible for finding Justfile

JUSTFILE

Changes the name of the default Justfile to a different filename when creating a new project

Note

Must not be set in the project environment files i.e. cannot be set in local.env, project env file or local_post.env. It will not have the desired effect, as this is too late in the load chain. Instead, it can either be exported before calling just (not recommended unless in a container or VM) or exported in the setup file.

Error handling

An error in a Justfile can be extremely hard to debug. Especially when the bug manifests itself deep inside just. For this reason, it is customary to turn set -eu on, so that if a bash command returns false, the script stops. (-u says that if a variable is used without being defined, to throw and error too).

The ERR signal is also trapped by just. When any error occurs, a complete bash stack trace is printed to stdout upon exit.

Call stack
----------
993  _Docker          /opt/projects/just/vsi_common/linux/just_files/docker_functions.bsh
974  Docker           /opt/projects/just/vsi_common/linux/just_files/docker_functions.bsh
120  caseify          /opt/projects/just/vsi_common/Justfile
795  justify          /opt/projects/just/vsi_common/linux/just_files/just_functions.bsh
281  main             /opt/projects/just/vsi_common/linux/just

/opt/projects/just/vsi_common/linux/just_files/docker_functions.bsh: line 993: Returned 2

Call stack
----------
21   caseify  /opt/projects/just/vsi_common/Justfile
795  justify  /opt/projects/just/vsi_common/linux/just_files/just_functions.bsh
281  main     /opt/projects/just/vsi_common/linux/just

/opt/projects/just/vsi_common/Justfile: line 21: Returned 2

Sometimes there are multiple stacks due to the way bash works. However the first one is usually the stack of interest. This stack printout says an error occurred in _Docker line 993, and can be tracked down to Justfile line 120. In this case, a docker command returned non-zero