Create an internal CLI using Just(blog.chay.dev) |
Create an internal CLI using Just(blog.chay.dev) |
https://docs.fabfile.org/en/latest/getting-started.html#adde...
If you are Python dev, you could specify Python dependencies for script using pep 723 https://iscinumpy.dev/post/pep723/ (nix might be an overkill).
For notebooks, workflows, personal playbooks, notes Org Babel could be used (emacs) Here's example code blocks in Haskell (but many other languages can be used such as shell, jupyter, plantuml) https://youtu.be/1qOFYluebBg?si=muGfsaC1kI7Cgpyw
One of my favorite features are subtree specific settings that enable remote shell commands by configuring :dir to /ssh:host:
Though commits on both projects are several months old
- two ways of producing the same file
- a command with no side effects
- not having to draw up a state machine
just can enumerate its own commands, which is minor but helpful
just can execute in multiple directories, and can descend directories
just treats spaces and tabs identically for indention, rather than space-indented for shell scripts and tab-indented for make commands
Make targets can be whatever you want, and don't have to produce files.
Make -n TARGET will list everything that Make thinks it needs to do to achieve TARGET, including anything that has to happen for any expressed dependencies (which can be tasks, and don't have to produce files).
Make recipes are arbitrary shell scripts that can do whatever you want, including changing directory. Make can also include other Makefiles, or call other Makefiles.
At its core, Make is a way to express "snippets of shell scripts, with a dependency graph between them". It can track files as dependency input and output -if you want-, but Make does not care if you don't. Call your targets whatever, and don't have them produce files. Boom, command runner. Make also has a powerful design, with a lot that you can do at parse-time.
And as it turns out, most tasks -do- have some amount of file dependencies. Maybe they need to consume a key file. Maybe they download a tarball. Maybe they produce a logfile that another task uploads. Being able to express as much (or as little) of that dependency graph as I want is a feature, not a bug.
Here are some of the differences I can recollect. Remember, you won't appreciate it until you try it.
- All tasks in just are phony. No file timestamp checks
- Just recipes can be in any scripting language within the same file. For example, you can write one recipe in bash, another in python and a third in perl, etc.
- Each line in a recipe in Make is executed in a different shell. You can't share variables between lines without using shell tricks. The same is the default for just as well. However, Just also allows you to write an entire recipe as a single script using shebang.
- Shell execution during variable assignment is done using backticks in just (just like bash). Make uses special function 'shell' for this.
- Recipe targets in Just can have parameters like bash functions do.
- Help strings for targets is easy in Just. You just place the string above the recipe. It's shown when you list the targets. Something similar can be done with Make, but using an additional hacky script.
- Just has a CLI to view and select targets. An emacs package also exists for the same.
- Some recipes can be private and wont show up in the listing.
- Just gives you the option to execute a recipe in the same directory as the Justfile, or in the current directory. It's a bit more complicated to do that in Makefile without the shell tricks.
* a way to list all available commands
* generate completions
* run shebang commands
.. and many more quality-of-life things.
It is probably possible to achieve these using `make`, but not without some hacking.
You can do all of this with make and make includes.
But it's simply not true that Make does all of that.
I moved from make about 5 years ago, never been happier.
By the logic that since make exists, and can do everything, then we really shouldn't build any new command runners. Since C exists and can do everything we really shouldn't use rust, zig, java, python.
Make is great, I've used it for nearly 30 years now, and it's really good at certain things, but it's not particularly good as a generic command runner. It's difficult to debug, it requires a lot of extra boilerplate text to be an ok command runner.
Just is a more ergonomic tool than make to use as a command runner, zsh is a more ergonomic tool to use as a shell than sh.
Yes make, when combined with some other tools like sed/awk can do everything that just can do, just not as easily, and it definitely requires a lot more depth of understanding to write a well formed Makefile than it does a well formed justfile.
But we get it, you don't want to try anything new.
Dismissing it as being for olds is short-sighted.
1. Someone wants to do it. Most open source is developed because someone just wants to. 2. You aren't happy with the language it's written in C vs Rust. 3. The tool is lacking some set of features that you want. 4. The tool isn't as easy to use as you would like. 5. The tool doesn't support some platform you care about. 6. Using the tool requires more knowledge or cognitive load than you would like. 7. The tool you are replacing has multiple variants that have different feature sets slightly different supported syntax (gnu make vs bsd make).
Same issue with bash. Having something that really cares about windows support is useful.