Notes on writing justfiles

Just is a modern command runner, a good alternative to the older make.

Some features

Setting the shell

set shell := ["bash", "-euco", "pipefail"]

Getting the file directory

JUST_DIR := justfile_directory()

Extend justfile

For better a better structure just recipes can be distributed among different files. These other files have to be referenced in the main justfile, note the comment which will be printed when listing the recipes:

# other module docs
mod other ".just/other.just"

Invoking recipes from other.just

just other cpu-model

Documentation

# Some comment about the recipe
[doc('Serve directory')]
run-py-server:
    python3 -m http.server

Will generate the same comment as:

# Serve directory
run-py-server:
    python3 -m http.server

Note how the doc syntax can be used to liberate the comments for other purpose.

Asking for confirmation

[confirm("are you sure you want to install? y/n")]
sources:
    echo "snap, apt, cargo"

Grouping recipes

Grouping can be used for better documentation

[doc('Serve directory')]
[group('utils')]
run-py-server:
    python3 -m http.server

Setting default recipe

Useful to set the default to print the different options:

# which recipe runs when no argument is passed
default: _help

# list-submodules for other files
[group('utils')]
_help:
    @just --list --list-submodules

Chaining recipes

all: echo-pwd cpu-model parse-smth

Shebang

To write recipes using a certaing languange:

[doc('Bash example')]
[group('json')]
parse-smth:
    #!/usr/bin/env bash
    input="{\"value\":1}"
    echo $input
    echo $input | jq '.value'

Some commands

List recipes

just --list

To also print all subdmodules use:

just --list --list-submodules

List and select recipe

This will open a small TUI which will show all recipes and their code:

just --choose

Check format with built in linter

just --justfile secrets.just --fmt --unstable --check

Format the file using built in linter

just --justfile secrets.just --fmt --unstable

Example

Directory structure

project
├── justfile
├── .just
│  └── other.just

justfile

set positional-arguments := true

set shell := ["bash", "-euco", "pipefail"]

# Define the directory of the justfile

JUST_DIR := justfile_directory()

# other module docs
mod other ".just/other.just"


# which recipe runs when no argument is passed
default: _help

# list-submodules for other files
[group('utils')]
_help:
    @just --list --list-submodules

[group('utils')]
combined:
    just -f .just/other.just cpu-model

# ask for confirmation
[confirm("are you sure you want to install? y/n")]
[group('install')]
sources:
    echo "snap, apt, cargo"

# [doc('Serve directory')]
[group('utils')]
run-py-server:
    python3 -m http.server

other.just

set positional-arguments := true

set shell := ["bash", "-euco", "pipefail"]

# Define the directory of the justfile

JUST_DIR := justfile_directory()


[group('utils')]
_help:
    @just -f other.just --list

[doc('Print cpu model')]
[group('system-info')]
cpu-model:
    @echo "This is an  machine".
    lscpu | grep "Model name:" | sed -r 's/Model name:\s{1,}//g'

[doc('Bash example')]
[group('json')]
parse-smth:
    #!/usr/bin/env bash
    input="{\"value\":1}"
    echo $input
    echo $input | jq '.value'

echo-pwd:
    pwd

all: echo-pwd cpu-model parse-smth

Some outputs

Working directory values depend on where the file is:

just echo-pwd
pwd
/home/user/project/justfiles

just other echo-pwd
pwd
/home/user/project/justfiles/.just