8000 GitHub - bolone-sengkuni/just: πŸ€– Just a command runner
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

bolone-sengkuni/just

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Table of Contents↗️

just


just is a handy way to save and run project-specific commands.

This readme is also available as a book. The book reflects the latest release, whereas the readme on GitHub reflects latest master.

(δΈ­ζ–‡ζ–‡ζ‘£εœ¨ θΏ™ι‡Œ, εΏ«ηœ‹θΏ‡ζ₯!)

Commands, called recipes, are stored in a file called justfile with syntax inspired by make:

screenshot

You can then run them with just RECIPE:

$ just test-all
cc *.c -o main
./test --all
Yay, all your tests passed!

just has a ton of useful features, and many improvements over make:

  • just is a command runner, not a build system, so it avoids much of make's complexity and idiosyncrasies. No need for .PHONY recipes!

  • Linux, MacOS, Windows, and other reasonable unices are supported with no additional dependencies. (Although if your system doesn't have an sh, you'll need to choose a different shell.)

  • Errors are specific and informative, and syntax errors are reported along with their source context.

  • Recipes can accept command line arguments.

  • Wherever possible, errors are resolved statically. Unknown recipes and circular dependencies are reported before anything runs.

  • just loads .env files, making it easy to populate environment variables.

  • Recipes can be listed from the command line.

  • Command line completion scripts are available for most popular shells.

  • Recipes can be written in arbitrary languages, like Python or NodeJS.

  • just can be invoked from any subdirectory, not just the directory that contains the justfile.

  • And much more!

If you need help with just please feel free to open an issue or ping me on Discord. Feature requests and bug reports are always welcome!

Installation

Prerequisites

just should run on any system with a reasonable sh, including Linux, MacOS, and the BSDs.

On Windows, just works with the sh provided by Git for Windows, GitHub Desktop, or Cygwin.

If you'd rather not install sh, you can use the shell setting to use the shell of your choice.

Like PowerShell:

# use PowerShell instead of sh:
set shell := ["powershell.exe", "-c"]

hello:
  Write-Host "Hello, world!"

…or cmd.exe:

# use cmd.exe instead of sh:
set shell := ["cmd.exe", "/c"]

list:
  dir

You can also set the shell using command-line arguments. For example, to use PowerShell, launch just with --shell powershell.exe --shell-arg -c.

(PowerShell is installed by default on Windows 7 SP1 and Windows Server 2008 R2 S1 and later, and cmd.exe is quite fiddly, so PowerShell is recommended for most Windows users.)

Packages

Cross-platform

Package Manager Package Command
asdf just asdf plugin add just
asdf install just <version>
Cargo just cargo install just
Conda just conda install -c conda-forge just
Homebrew just brew install just
Nix just nix-env -iA nixpkgs.just
npm rust-just npm install -g rust-just
PyPI rust-just pipx install rust-just
Snap just snap install --edge --classic just

BSD

Operating System Package Manager Package Command
FreeBSD pkg just pkg install just

Linux

Operating System Package Manager Package Command
Alpine apk-tools just apk add just
Arch pacman just pacman -S just
Debian 13 (unreleased) and Ubuntu 24.04 derivatives apt just apt install just
Debian and Ubuntu derivatives MPR just git clone https://mpr.makedeb.org/just
cd just
makedeb -si
Debian and Ubuntu derivatives Prebuilt-MPR just You must have the Prebuilt-MPR set up on your system in order to run this command.
apt install just
Fedora DNF just dnf install just
Gentoo Portage guru/dev-build/just eselect repository enable guru
emerge --sync guru
emerge dev-build/just
NixOS Nix just nix-env -iA nixos.just
openSUSE Zypper just zypper in just
Solus eopkg just eopkg install just
Void XBPS just xbps-install -S just

Windows

Package Manager Package Command
Chocolatey just choco install just
Scoop just scoop install just
Windows Package Manager Casey/Just winget install --id Casey.Just --exact

macOS

Package Manager Package Command
MacPorts just port install just

just package version table

Pre-Built Binaries

Pre-built binaries for Linux, MacOS, and Windows can be found on the releases page.

You can use the following command on Linux, MacOS, or Windows to download the latest release, just replace DEST with the directory where you'd like to put just:

curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to DEST

For example, to install just to ~/bin:

# create ~/bin
mkdir -p ~/bin

# download and extract just to ~/bin/just
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/bin

# add `~/bin` to the paths that your shell searches for executables
# this line should be added to your shells initialization file,
# e.g. `~/.bashrc` or `~/.zshrc`
export PATH="$PATH:$HOME/bin"

# just should now be executable
just --help

Note that install.sh may fail on GitHub Actions, or in other environments where many machines share IP addresses. install.sh calls GitHub APIs in order to determine the latest version of just to install, and those API calls are rate-limited on a per-IP basis. To make install.sh more reliable in such circumstances, pass a specific tag to install with --tag.

Releases include a SHA256SUM file which can be used to verify the integrity of pre-built binary archives.

To verify a release, download the pre-built binary archive along with the SHA256SUM file and run:

shasum --algorithm 256 --ignore-missing --check SHA256SUMS

GitHub Actions

just can be installed on GitHub Actions in a few ways.

Using package managers pre-installed on GitHub Actions runners on MacOS with brew install just, and on Windows with choco install just.

With extractions/setup-just:

- uses: extractions/setup-just@v2
  with:
    just-version: 1.5.0  # optional semver specification, otherwise latest

Or with taiki-e/install-action:

- uses: taiki-e/install-action@just

Release RSS Feed

An RSS feed of just releases is available here.

Node.js Installation

just-install can be used to automate installation of just in Node.js applications.

just is a great, more robust alternative to npm scripts. If you want to include just in the dependencies of a Node.js application, just-install will install a local, platform-specific binary as part of the npm install command. This removes the need for every developer to install just independently using one of the processes mentioned above. After installation, the just command will work in npm scripts or with npx. It's great for teams who want to make the set up process for their project as easy as possible.

For more information, see the just-install README file.

Backwards Compatibility

With the release of version 1.0, just features a strong commitment to backwards compatibility and stability.

Future releases will not introduce backwards incompatible changes that make existing justfiles stop working, or break working invocations of the command-line interface.

This does not, however, preclude fixing outright bugs, even if doing so might break justfiles that rely on their behavior.

There will never be a just 2.0. Any desirable backwards-incompatible changes will be opt-in on a per-justfile basis, so users may migrate at their leisure.

Features that aren't yet ready for stabilization are marked as unstable and may be changed or removed at any time. Using unstable features produces an error by default, which can be suppressed with by passing the --unstable flag, set unstable, or setting the environment variable JUST_UNSTABLE, to any value other than false, 0, or the empty string.

Editor Support

justfile syntax is close enough to make that you may want to tell your editor to use make syntax highlighting for just.

Vim and Neovim

Vim version 9.1.1042 or better and Neovim version 0.11 or better support Justfile syntax highlighting out of the box, thanks to pbnj.

vim-just

The vim-just plugin provides syntax highlighting for justfiles.

Install it with your favorite package manager, like Plug:

call plug#begin()

Plug 'NoahTheDuke/vim-just'

call plug#end()

Or with Vim's built-in package support:

mkdir -p ~/.vim/pack/vendor/start
cd ~/.vim/pack/vendor/start
git clone https://github.com/NoahTheDuke/vim-just.git

tree-sitter-just

tree-sitter-just is an Nvim Treesitter plugin for Neovim.

Makefile Syntax Highlighting

Vim's built-in makefile syntax highlighting isn't perfect for justfiles, but it's better than nothing. You can put the following in ~/.vim/filetype.vim:

if exists("did_load_filetypes")
  finish
endif

augroup filetypedetect
  au BufNewFile,BufRead justfile setf make
augroup END

Or add the following to an individual justfile to enable make mode on a per-file basis:

# vim: set ft=make :

Emacs

just-mode provides syntax highlighting and automatic indentation of justfiles. It is available on MELPA as just-mode.

justl provides commands for executing and listing recipes.

You can add the following to an individual justfile to enable make mode on a per-file basis:

# Local Variables:
# mode: makefile
# End:

Visual Studio Code

An extension for VS Code is available here.

Unmaintained VS Code extensions include skellock/vscode-just and sclu1034/vscode-just.

JetBrains IDEs

A plugin for JetBrains IDEs by linux_china is available here.

Kakoune

Kakoune supports justfile syntax highlighting out of the box, thanks to TeddyDD.

Helix

Helix supports justfile syntax highlighting out-of-the-box since version 23.05.

Sublime Text

The Just package by nk9 with just syntax and some other tools is available on PackageControl.

Micro

Micro supports Justfile syntax highlighting out of the box, thanks to tomodachi94.

Zed

The zed-just extension by jackTabsCode is avilable on the Zed extensions page.

Other Editors

Feel free to send me the commands necessary to get syntax highlighting working in your editor of choice so that I may include them here.

Quick Start

See the installation section for how to install just on your computer. Try running just --version to make sure that it's installed correctly.

For an overview of the syntax, check out this cheatsheet.

Once just is installed and working, create a file named justfile in the root of your project with the following contents:

recipe-name:
  echo 'This is a recipe!'

# this is a comment
another-recipe:
  @echo 'This is another recipe.'

When you invoke just it looks for file justfile in the current directory and upwards, so you can invoke it from any subdirectory of your project.

The search for a justfile is case insensitive, so any case, like Justfile, JUSTFILE, or JuStFiLe, will work. just will also look for files with the name .justfile, in case you'd like to hide a justfile.

Running just with no arguments runs the first recipe in the justfile:

$ just
echo 'This is a recipe!'
This is a recipe!

One or more arguments specify the recipe(s) to run:

$ just another-recipe
This is another recipe.

just prints each command to standard error before running it, which is why echo 'This is a recipe!' was printed. This is suppressed for lines starting with @, which is why echo 'This is another recipe.' was not printed.

Recipes stop running if a command fails. Here cargo publish will only run if cargo test succeeds:

publish:
  cargo test
  # tests passed, time to publish!
  cargo publish

Recipes can depend on other recipes. Here the test recipe depends on the build recipe, so build will run before test:

build:
  cc main.c foo.c bar.c -o main

test: build
  ./test

sloc:
  @echo "`wc -l *.c` lines of code"
$ just test
cc main.c foo.c bar.c -o main
./test
testing… all tests passed!

Recipes without dependencies will run in the order they're given on the command line:

$ just build sloc
cc main.c foo.c bar.c -o main
1337 lines of code

Dependencies will always run first, even if they are passed after a recipe that depends on them:

$ just test build
cc main.c foo.c bar.c -o main
./test
testing… all tests passed!

Examples

A variety of justfiles can be found in the examples directory and on GitHub.

Features

The Default Recipe

When just is invoked without a recipe, it runs the first recipe in the justfile. This recipe might be the most frequently run command in the project, like running the tests:

test:
  cargo test

You can also use dependencies to run multiple recipes by default:

default: lint build test

build:
  echo Building…

test:
  echo Testing…

lint:
  echo Linting…

If no recipe makes sense as the default recipe, you can add a recipe to the beginning of your justfile that lists the available recipes:

default:
  just --list

Listing Available Recipes

Recipes can be listed in alphabetical order with just --list:

$ just --list
Available recipes:
    build
    test
    deploy
    lint

Recipes in submodules can be listed with just --list PATH, where PATH is a space- or ::-separated module path:

$ cat justfile
mod foo
$ cat foo.just
mod bar
$ cat bar.just
baz:
$ just foo bar
Available recipes:
    baz
$ just foo::bar
Available recipes:
    baz

just --summary is more concise:

$ just --summary
build test deploy lint

Pass --unsorted to print recipes in the order they appear in the justfile:

test:
  echo 'Testing!'

build:
  echo 'Building!'
$ just --list --unsorted
Available recipes:
    test
    build
$ just --summary --unsorted
test build

If you'd like just to default to listing the recipes in the justfile, you can use this as your default recipe:< D7AE /p>

default:
  @just --list

Note that you may need to add --justfile {{justfile()}} to the line above. Without it, if you executed just -f /some/distant/justfile -d . or just -f ./non-standard-justfile, the plain just --list inside the recipe would not necessarily use the file you provided. It would try to find a justfile in your current path, maybe even resulting in a No justfile found error.

The heading text can be customized with --list-heading:

$ just --list --list-heading $'Cool stuff…\n'
Cool stuff…
    test
    build

And the indentation can be customized with --list-prefix:

$ just --list --list-prefix Β·Β·Β·Β·
Available recipes:
Β·Β·Β·Β·test
Β·Β·Β·Β·build

The argument to --list-heading replaces both the heading and the newline following it, so it should contain a newline if non-empty. It works this way so you can suppress the heading line entirely by passing the empty string:

$ just --list --list-heading ''
    test
    build

Invoking Multiple Recipes

Multiple recipes may be invoked on the command line at once:

build:
  make web

serve:
  python3 -m http.server -d out 8000
$ just build serve
make web
python3 -m http.server -d out 8000

Keep in mind that recipes with parameters will swallow arguments, even if they match the names of other recipes:

build project:
  make {{project}}

serve:
  python3 -m http.server -d out 8000
$ just build serve
make: *** No rule to make target `serve'.  Stop.

The --one flag can be used to restrict command-line invocations to a single recipe:

$ just --one build serve
error: Expected 1 command-line recipe invocation but found 2.

Working Directory

By default, recipes run with the working directory set to the directory that contains the justfile.

The [no-cd] attribute can be used to make recipes run with the working directory set to directory in which just was invoked.

@foo:
  pwd

[no-cd]
@bar:
  pwd
$ cd subdir
$ just foo
/
$ just bar
/subdir

You can override the working directory for all recipes with set working-directory := '…':

set working-directory := 'bar'

@foo:
  pwd
$ pwd
/home/bob
$ just foo
/home/bob/bar

You can override the working directory for a specific recipe with the working-directory attribute1.38.0:

[working-directory: 'bar']
@foo:
  pwd
$ pwd
/home/bob
$ just foo
/home/bob/bar

The argument to the working-directory setting or working-directory attribute may be absolute or relative. If it is relative it is interpreted relative to the default working directory.

Aliases

Aliases allow recipes to be invoked on the command line with alternative names:

alias b := build

build:
  echo 'Building!'
$ just b
echo 'Building!'
Building!

The target of an alias may be a recipe in a submodule:

mod foo

alias baz := foo::bar

Settings

Settings control interpretation and execution. Each setting may be specified at most once, anywhere in the justfile.

For example:

set shell := ["zsh", "-cu"]

foo:
  # this line will be run as `zsh -cu 'ls **/*.txt'`
  ls **/*.txt

Table of Settings

Name Value Default Description
allow-duplicate-recipes boolean false Allow recipes appearing later in a justfile to override earlier recipes with the same name.
allow-duplicate-variables boolean false Allow variables appearing later in a justfile to override earlier variables with the same name.
dotenv-filename string - Load a .env file with a custom name, if present.
dotenv-load boolean false Load a .env file, if present.
dotenv-path string - Load a .env file from a custom path and error if not present. Overrides dotenv-filename.
dotenv-required boolean false Error if a .env file isn't found.
export boolean false Export all variables as environment variables.
fallback boolean false Search justfile in parent directory if the first recipe on the command line is not found.
ignore-comments boolean false Ignore recipe lines beginning with #.
positional-arguments boolean false Pass positional arguments.
quiet boolean false Disable echoing recipe lines before executing.
script-interpreter1.33.0 [COMMAND, ARGS…] ['sh', '-eu'] Set command used to invoke recipes with empty [script] attribute.
shell [COMMAND, ARGS…] - Set command used to invoke recipes and evaluate backticks.
tempdir string - Create temporary directories in tempdir instead of the system default temporary directory.
unstable1.31.0 boolean false Enable unstable features.
windows-powershell boolean false Use PowerShell on Windows as default shell. (Deprecated. Use windows-shell instead.
windows-shell [COMMAND, ARGS…] - Set the command used to invoke recipes and evaluate backticks.
working-directory1.33.0 string - Set the working directory for recipes and backticks, relative to the default working directory.

Boolean settings can be written as:

set NAME

Which is equivalent to:

set NAME := true

Allow Duplicate Recipes

If allow-duplicate-recipes is set to true, defining multiple recipes with the same name is not an error and the last definition is used. Defaults to false.

set allow-duplicate-recipes

@foo:
  echo foo

@foo:
  echo bar
$ just foo
bar

Allow Duplicate Variables

If allow-duplicate-variables is set to true, defining multiple variables with the same name is not an error and the last definition is used. Defaults to false.

set allow-duplicate-variables

a := "foo"
a := "bar"

@foo:
  echo {{a}}
$ just foo
bar

Dotenv Settings

If any of dotenv-load, dotenv-filename, dotenv-path, or dotenv-required are set, just will try to load environment variables from a file.

If dotenv-path is set, just will look for a file at the given path, which may be absolute, or relative to the working directory.

The command-line option --dotenv-path, short form -E, can be used to set or override dotenv-path at runtime.

If dotenv-filename is set just will look for a file at the given path, relative to the working directory and each of its ancestors.

If dotenv-filename is not set, but dotenv-load or dotenv-required are set, just will look for a file named .env, relative to the working directory and each of its ancestors.

dotenv-filename and dotenv-path are similar, but dotenv-path is only checked relative to the working directory, whereas dotenv-filename is checked relative to the working directory and each of its ancestors.

It is not an error if an environment file is not found, unless dotenv-required is set.

The loaded variables are environment variables, not just variables, and so must be accessed using $VARIABLE_NAME in recipes and backticks.

For example, if your .env file contains:

# a comment, will be ignored
DATABASE_ADDRESS=localhost:6379
SERVER_PORT=1337

And your justfile contains:

set dotenv-load

serve:
  @echo "Starting server with database $DATABASE_ADDRESS on port $SERVER_PORT…"
  ./server --database $DATABASE_ADDRESS --port $SERVER_PORT

just serve will output:

$ just serve
Starting server with database localhost:6379 on port 1337…
./server --database $DATABASE_ADDRESS --port $SERVER_PORT

Export

The export setting causes all just variables to be exported as environment variables. Defaults to false.

set export

a := "hello"

@foo b:
  echo $a
  echo $b
$ just foo goodbye
hello
goodbye

Positional Arguments

If positional-arguments is true, recipe arguments will be passed as positional arguments to commands. For linewise recipes, argument $0 will be the name of the recipe.

For example, running this recipe:

set positional-arguments

@foo bar:
  echo $0
  echo $1

Will produce the following output:

$ just foo hello
foo
hello

When using an sh-compatible shell, such as bash or zsh, $@ expands to the positional arguments given to the recipe, starting from one. When used within double quotes as "$@", arguments including whitespace will be passed on as if they were double-quoted. That is, "$@" is equivalent to "$1" "$2"… When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

This example recipe will print arguments one by one on separate lines:

set positional-arguments

@test *args='':
  bash -c 'while (( "$#" )); do echo - $1; shift; done' -- "$@"

Running it with two arguments:

$ just test foo "bar baz"
- foo
- bar baz

Positional arguments may also be turned on on a per-recipe basis with the [positional-arguments] attribute1.29.0:

[positional-arguments]
@foo bar:
  echo $0
  echo $1

Note that PowerShell does not handle positional arguments in the same way as other shells, so turning on positional arguments will likely break recipes that use PowerShell.

If using PowerShell 7.4 or better, the -CommandWithArgs flag will make positional arguments work as expected:

set shell := ['pwsh.exe', '-CommandWithArgs']
set positional-arguments

print-args a b c:
  Write-Output @($args[1..($args.Count - 1)])

Shell

The shell setting controls the command used to invoke recipe lines and backticks. Shebang recipes are unaffected. The default shell is sh -cu.

# use python3 to execute recipe lines and backticks
set shell := ["python3", "-c"]

# use print to capture result of evaluation
foos := `print("foo" * 4)`

foo:
  print("Snake snake snake snake.")
  print("{{foos}}")

just passes the command to be executed as an argument. Many shells will need an additional flag, often -c, to make them evaluate the first argument.

Windows Shell

just uses sh on Windows by default. To use a different shell on Windows, use windows-shell:

set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]

hello:
  Write-Host "Hello, world!"

See powershell.just for a justfile that uses PowerShell on all platforms.

Windows PowerShell

set windows-powershell uses the legacy powershell.exe binary, and is no longer recommended. See the windows-shell setting above for a more flexible way to control which shell is used on Windows.

just uses sh on Windows by default. To use powershell.exe instead, set windows-powershell to true.

set windows-powershell := true

hello:
  Write-Host "Hello, world!"
Python 3
set shell := ["python3", "-c"]
Bash
set shell := ["bash", "-uc"]
Z Shell
set shell := ["zsh", "-uc"]
Fish
set shell := ["fish", "-c"]
Nushell
set shell := ["nu", "-c"]

If you want to change the default table mode to light:

set shell := ['nu', '-m', 'light', '-c']

Nushell was written in Rust, and has cross-platform support for Windows / macOS and Linux.

Documentation Comments

Comments immediately preceding a recipe will appear in just --list:

# build stuff
build:
  ./bin/build

# test stuff
test:
  ./bin/test
$ just --list
Available recipes:
    build # build stuff
    test # test stuff

The [doc] attribute can be used to set or suppress a recipe's doc comment:

# This comment won't appear
[doc('Build stuff')]
build:
  ./bin/build

# This one won't either
[doc]
test:
  ./bin/test
$ just --list
Available recipes:
    build # Build stuff
    test

Expressions and Substitutions

Various operators and function calls are supported in expressions, which may be used in assignments, default recipe arguments, and inside recipe body {{…}} substitutions.

tmpdir  := `mktemp -d`
version := "0.2.7"
tardir  := tmpdir / "awesomesauce-" + version
tarball := tardir + ".tar.gz"
config  := quote(config_dir() / ".project-config")

publish:
  rm -f {{tarball}}
  mkdir {{tardir}}
  cp README.md *.c {{ config }} {{tardir}}
  tar zcvf {{tarball}} {{tardir}}
  scp {{tarball}} me@server.com:release/
  rm -rf {{tarball}} {{tardir}}

Concatenation