justl: Driving recipes within Emacs
Sibi Prabakaran (he/him, psibi2000@gmail.com)
In this talk, Sibi Prabakaran shares how to use justl to run justfile tasks from inside Emacs, including a comparison with Makefiles. Afterwards, he will handle questions over IRC.
00:00.000 Introduction 00:39.320 Justfiles 01:48.520 Executing recipes 02:27.680 Other features 02:56.440 Comparison with Makefiles 04:19.280 justl.el 04:52.400 Executing recipes in Emacs 06:17.280 Options 06:36.600 Eshell 06:57.320 Going to the recipe line 07:15.520 Re-executing recipes 07:39.560 Example 08:56.600 justl-exec-recipe-in-dir 09:34.680 End
Description
justl.el is a major mode for driving justfiles.
Justfiles are a way to save and run project specific commands. Think of it like Makefile, but purely focused as a command runner.
The purpose of the talk is to give a brief introduction about justfile and then followed by how to use the justl.el extension to drive justfiles from within Emacs.
Bio: https://psibi.in/about.html
Resources
Discussion
- thanks for the great talk sibi
- Seems like a pretty focused and useful tool!
- will try out Just after that talk
- Great talk. I'll definitively give it a try.
Transcript
[00:00:00.000] Hi everyone, I am Sibi Prabakaran and welcome to my session on Justl Emacs Mode. A bit about me, I have been working as a Haskell Engineer at FPComplete for the last 4 years. I am based out of India. I occasionally blog at my website psibi.in where you can find more information about me. I have been using Emacs for more than a decade now. I help in the maintenance of the Terraform client for LSP mode. I have also authored dhall-mode and rego-mode which are the major modes for the respective languages.
[00:00:39.320] Before jumping into the demo of the Emacs package, I would like to give a brief introduction about justfiles and what it is. I will also try to compare it with Makefiles as it takes a lot of inspiration from it. What you see currently in the buffer is a sample justfile. If you have previously used Makefiles, you would be able to see that there is quite a bit of similarity between them. Anything that starts with hash is a documentation comment. You can see that I have the first recipe which is named as default. So if you run the just executable without any arguments, by default it is going to run the first recipe. This recipe's definition calls the just command in turn, with the two arguments, namely --list and --unsorted, which basically asks just to list down all the recipes in an unsorted order. Each line of each recipe is executed by a fresh shell. That pretty much is the high level overview of getting started to use this tool. This tool assumes the presence of a shell which is bash in most GNU/Linux systems, but you can configure it to explicitly use any specific shell you have in mind.
[00:01:48.520] Let me in fact go and try executing the first recipe. I will first execute it without any arguments, which will force it to run the first recipe. As you can see, it listed all the recipes. Now I can actually execute a particular recipe by passing an explicit recipe name. Let me execute the hello recipe now which will basically print "hello world". It works as expected. As you can see, that's all that's required to get started with this tool. You create a file named justfile in a directory, define some recipes and then run them via the just executable.
[00:02:27.680] Note that there are various other features in justfile. You can define variables, mark some variables to be exported as environment variables, have optional parameters that can be passed to a recipe. You can also set up dependency between recipes and also write scripts within a recipe in a language of your choice. I won't be going into the details, but I encourage you to go through the very helpful manual page to learn more about it.
[00:02:56.440] Also, let me compare it with Makefiles. I do think it's kind of unfair to compare both the tools since make is a build automation tool whereas just's goal is a task runner, and since just doesn't try to be a build system, it can avoid the associated complexity that comes with the tool like make. There is one nice historical fact about just. The initial version of just relied on make command being available, so it was basically a glorified wrapper around it. But it was removed, and justfile doesn't have that dependency anymore. If you are using make as a task runner then you would have to use something called phony targets. I don't want to go into the details, but makefiles have good reason for why they need something like that. Since justfile is not a build system, it doesn't have to deal with them. The error message and user experience of this tool, in my opinion, is better. To show you a concrete example, justfile errors out by default if you have duplicate recipes. This is in contrast with make where I believe it prints out a warning about it, but still executes the target action. Justfile also gives you the ability to easily create scripts written in any language within a recipe. My personal opinion is that if you are using makefile as a task runner, you might want to check out justfile to see if it will suit your workflow.
[00:04:19.280] With that, I'll move on to justl.el, which is basically an Emacs package for driving justfiles. I started writing this tool around a year ago when my usage of justfile increased. The objective of the tool is to reduce the usage of the CLI and drive the execution of the recipes natively within the editor. Let me take you back to the justfile which we saw previously. This time we will drive it within the editor itself, instead of executing commands via vterm as done previously.
[00:04:52.400] So the idea is you either open the justfile, or any other file in the directory. That doesn't matter, actually. Once you do that, you call the justl command. Now as you can see, it lists down all the recipes, along with the description if present. You can move on to different recipes by your usual keybinding. And for executing a specific recipe, you have to press the e keybinding, and that will run the recipe and show its output on a special buffer named just which is built on top of the compilation mode available in Emacs. Let me actually try executing the hello recipe which we previously executed in vterm. As you can see, it executed the recipe and the "hello world" output is visible in the just buffer. You can also see that there is other metadata like when it started executing and when did it finish executing. If a recipe execution fails, it will also change the color and print the corresponding exit code. Let me actually show you by modifying the hello recipe and making it exit. As you can see, it clearly indicates the error message now. That is a pretty much a good high level overview of how to execute recipes using this Emacs extension.
[00:06:17.280] If I press the h or the ? key, it will display the various ways to drive it. Now as you can see, you can pass various options to it. I find the dry run option effective whenever I have to print the recipe contents without actually executing the recipe.
[00:06:36.600] There are also various ways to execute it. You can use Emacs's eshell to execute it by pressing the E keybinding. Let me try executing the hello recipe again, but this time via Emacs's eshell. As you can see now I have an eshell instance where it executed the just hello recipe.
[00:06:57.320] You can also directly go to the recipe line by pressing the return key. So let's say if I want to go to the recipe build app all I have to do is press the return key and it will go to the just file with the proper line.
[00:07:15.520] You can also re-execute the same recipe from the output just buffer. I find this very helpful when iterating on certain things. In my day job, I often have to work with a Kubernetes cluster, and I would have to write resource manifest files for applications. Having the ability to run the recipes while iterating on the project is very useful, in my opinion.
[00:07:39.560] Let me actually show you an example of what I am talking about. Let me run the build app recipe now, which will basically build the manifest and print it out. Now let me open one of the application files. I will open the ingress.yaml file. So I have this YAML file which I am working on, and I also have this output buffer which is basically the output of the build app recipe. Now I can basically go through this buffer and see if everything is alright, but I find out that I didn't want the hostname to be emacs2022. I wanted it to be just emacs. I can go and fix it in my YAML file, and then I can go on to the output buffer and basically just re-run the command by pressing the g key binding. As you can see, it executed the same recipe again, and I can see that the hostname is indeed emacs. I find this kind of workflow very convenient while I am working on a project.
[00:08:56.600] Another way of interacting with the justl extension is by using the interactive function justl-exec-recipe-in-dir. The use case of this function is executing a one-off recipe while you are working on something else. Let me show you an example of it. As you can see, it shows me a drop down of various recipes available in the justfile. You can choose any particular one and execute the corresponding recipe. In this case, I will choose the build-app recipe, and we will get the output in the just buffer which should be similar to what we saw previously.
[00:09:34.680] So this was a quick introduction to what justfile is and how to drive them within Emacs. Hopefully it was helpful and it would encourage you to use justfiles in your workflow. Thank you for allowing me to present. I am available in IRC if you have any questions.
Captioner: sachac
Questions or comments? Please e-mail psibi2000@gmail.com