Just make use of just

Organize your project-specific commands with just

4 minute read

Nowadays, makefiles are ubiquitous in software. Most C and C++ projects have used them historically, and still use them as a build system. Nowadays, lots of projects written in other languages which have their own build tools also use them, not to make files, but to store and run commands in an organized manner. If this is you, you are doing it wrong. However, there is a tool designed to do just that: just.

What is make

make is a GNU utility mainly used to make files. It automatically determines which parts of a build are outdated and need remaking (recompiling), and runs the commands to make them. make uses a makefile, which is a user-written file that specifies the targets (files) and the rules to make them. Usually, the makefile informs make as to how to compile and link a program written in C or C++, even though it is also extensively used in other well-suited languages like LaTeX.

However, targets in a makefile are by default files. This means that they build other files. Let’s see a very simple example.

foo: bar
    cat bar bar > foo

In this makefile, we have one file target, foo. To make the file foo, we need a file bar. What appears after the colon in the first line are the requirements to make that file. The command appears below, and it just concatenates bar 2 times and outputs the result to foo.

Let’s try it. First, let’s create a file named bar.

echo "this is bar" > bar

Then, make sure you have a file named makefile with the contents shown above. Then, run make foo.

$  make foo
cat bar bar > foo

If you ls, you will see that now you have a new file named foo, with the contents of bar repeated twice. Now, try make foo again.

$  make foo
make: 'foo' is up to date.

Indeed, nothing was made because make determined that foo is already up to date.

This is essentially the main purpose of make. However, make is often used to store and run arbitrary commands that do not really make any file. For example, in a C codebase you often find a clean target which removes all object (*.o) files. In our example, we can add a clean target that removes foo. To do that, you can explicitly tell make that the target is not linked to a file. We do so by annotating the target with .PHONY:

.PHONY clean
clean: 
    rm -rf foo

After that, make clean with run even if you do not have a file with the name clean. However, this target will not work if a file named clean is in the same directory. To overcome this, we need .PHONY. A phony target is, in essence, a target that is always out of date.

This is why, conceptually, make is not very well-suited to only organize and run arbitrary commands. To that purpose, there exists another tool, just.

What is just

just (github) is a command runner written in Rust. It is not a build system. It steps in in those occasions when you have a project and need to keep your commands (that do not build the project!) nicely organized. just stores the commands (called recipes) in a file named justfile, with a syntax very similar to makefiles. For example, the justfile for this website’s project is the following:

minify:
  $WEB/scripts/minify-all.sh theme-bw

deploy: minify
  $WEB/deploy.sh

hugo:
  hugo server

It has three targets and none of them build files. They do random stuff like minifying and the CSS and the JavaScript files, deploying the website to the server by running the deploy.sh script, or starting a local server. See that targets can still have dependencies (deploy depends on minify), so that they are run in order.

just has many more features though.

  • It is a command runner, not a build system, so there’s no need for .PHONY recipes.
  • Multi-platform.
  • Aliases.
  • Can be invoked from any subdirectory.
  • Recipes can be listed with just -l.
  • Specific and informative errors.
  • Errors are resolved statically.
  • Recipes can be written in any arbitrary language.
  • Much more.

The next time you need to store and organize commands for your project, think again before using make. just might just be what you need!

Website design by myself. See the privacy policy.
Content licensed under CC-BY-NC-SA 4.0 .