Introduction #

In this tutorial we will learn how to use just by example to manage project specific commands. just is like make, but it is written in Rust, and it works with cargo.

Before we get started, please take a look at the just project README.

Let’s say you have a justfile that looks like this, and it has a single recipe called list:

list:
  ls -l

And you run it by typing just list. It just turns around and runs this sh -c "ls -l". That’s it. So on Windows, this doesn’t work, because sh isn’t installed by default. So you have to install cygwin. And then you have to install just and then you have to install sh.

Alternatively, you can specify that you want to use powershell instead by adding this to the top of the justfile: set shell := ["powershell.exe", "-c"]. Or you can just run this just --shell powershell.exe --shell-arg -c list to run just itself at the command prompt.

You can also supply different shell interpreters like python or node. And you can even provide shebang lines like #!/usr/bin/env python or #!/usr/bin/env node at the top of each recipe.

Prerequisites #

🌠 In order for our just file to work, we must first install the Rust toolchain and just and cargo-watch:

  1. Install the Rust toolchain using rustup by following the instructions here.
  2. Install cargo-watch using cargo install cargo-watch.
  3. Install just on your system using cargo install just. It is available for Linux, macOS, and Windows.
    • If you want shell completions for just you can follow these instructions.
    • If you install just using cargo install just or brew install just you will not get shell completions without doing one extra configuration step. So on Linux it is best to use sudo apt install -y just if you want them.

Basic usage #

For Rust projects, typically we will have a build, run, test project specific commands. Let’s start with these simple ones first. The benefit of just is that we can use it to run these commands on any platform (Linux, Mac, Windows). And we don’t need to create OS or shell specific scripts to do this 🎉.

Let’s start by creating a justfile in the root of our project. The justfile is where we will define our project specific commands. Here is what it looks like for the r3bl_ansi_color repo:

build:
  cargo build

clean:
  cargo clean

run:
  cargo run --example main

These are pretty simple commands. The syntax is pretty simple. The first line is the command name. And the second line is the command to run. The command can be a single command or a series of commands.

Now in order to run this, we can just run just --list in the root of our project. And it will show us the list of commands that we can run.

$ just --list
Available recipes:
    build
    clean
    run

Then to run a command, we can just run just <command_name>. For example, to run the build command, we can run just build.

$ just build

Advanced usage #

Running many different commands #

This is pretty straightforward. You can just list all other other just commands inline. Here’s an example.

all: clean build test clippy docs rustfmt

The all command will run the other commands in the order they’re written.

Run on Windows #

Currently our justfile will run on Linux and macOS. To make it run on Windows, we can run just itself using powershell.exe. Here is what it looks like:

just --shell powershell.exe --shell-arg -c build

Or we can add the line set shell := ["powershell.exe", "-c"] to the top of the justfile.

Alternatively, we can use nu shell instead of powershell.exe since it is written in Rust and available via cargo install nu.

Run in CI / CD environments (Github Actions) #

Let’s add a new command called all to our justfile. This will just turn around and run the build and clean commands. Here is what it looks like:

all: build clean

Now, we can also use just in CI / CD environments. For example, here is the rust.yml file for this repo’s Github Actions. It runs just all in the build step.

The one thing to note is that we are installing just in the docker container before we run the just command. We do this by pulling in the prebuilt binary for Ubuntu as shown here: curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to DEST

jobs:
  build:

    runs-on: ubuntu-latest

    steps:

    - uses: actions/checkout@v3

    # Install just before running it below.
    - name: Install just
      run: curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin

    # Simply run the `just all` command.
    - name: all
      run: just all

Using just all is relatively straightforward way to run all our build steps (that would run in a CI / CD environment) on our local computer w/out installing docker. While ensuring that these same steps are carried out in the CI / CD environment.

Pass arguments into commands #

We can also pass arguments into our commands. Let’s say that we have a command that we can use to run a single test. We can pass the name of the test into the command. Here is what it looks like:

watch-one-test test_name:
  # More info on cargo test: https://doc.rust-lang.org/cargo/commands/cargo-test.html
  # More info on cargo watch: https://github.com/watchexec/cargo-watch
  cargo watch -x check -x 'test -- --test-threads=1 --nocapture {{test_name}}' -c -q

There are a few things to note here:

  1. The syntax to name the command is still the same as before.
  2. However, we have added another string after the command name, which is the argument name test_name. If an argument is not passed in then just will display an error and print a message stating that an argument is required.

  3. This argument is used just like a variable would in a justfile. The {{ and }} enclose a variable name.

Now we can run this command by passing in the name of the test that we want to run. For example, if we want to run the test_ansi_color test, we can run just watch-one-test test_ansi_color.

$ just watch-one-test bold

Here’s an example of a justfile that has a lot more commands for you to look at: r3bl_ansi_color justfile.

Next steps #

The just project README has lots of information on how to use just. It is best to have a specific thing you are looking for before you visit this page. Here are some interesting links inside the README:

  1. Command line arguments.
  2. Support for .env files.
  3. Conditional expressions.
  4. Setting variables.

Build with Naz video series on developerlife.com YouTube channel #

If you have comments and feedback on this content, or would like to request new content (articles & videos) on developerlife.com, please join our discord server.

You can watch a video series on building this crate with Naz on the developerlife.com YouTube channel.

👀 Watch Rust 🦀 live coding videos on our YouTube Channel.



📦 Install our useful Rust command line apps using cargo install r3bl-cmdr (they are from the r3bl-open-core project):
  • 🐱giti: run interactive git commands with confidence in your terminal
  • 🦜edi: edit Markdown with style in your terminal

giti in action

edi in action

Related Posts