Supercharge Your Automation Workflows with Taskfile: Say Goodbye to Makefile
Episode #20: Why is Taskfile an attractive alternative to Makefile for beginners and more advanced users alike?
This article is my second piece on Taskfile.
My first article Taskfile: a modern alternative to Makefile went viral (at least for my standards).
Here you have some stats:
95 points and 212 comments on HackerNews
10k views and 31 new subscribers on Substack (this newsletter).
3.6k views and 2k reads on Medium where I cross-posted the article.
Makefile is a fascinating and controversial topic that sparks passionate debates.
Individuals have diverse and firm opinions on the matter.
The debate on HackerNews became quite intense very quickly. Both sides presented their hot takes—the supporters of Makefile and those who dislike it but have yet to discover a better alternative.
This article is directed towards the latter group.
If you strongly favour Makefile and are unwilling to consider counterarguments, please refrain from reading further.
However, this article may interest you if you dislike Makefile and have been searching for a suitable alternative for years.
Want to connect?
👉 Follow me on LinkedIn and Twitter.
If you need 1-1 mentoring sessions, feel free to check my Mentorcruise profile.
What is Taskfile?
Task (the name says already) is a task runner written in Golang that adopts a YAML-like syntax called Taskfile for writing tasks and their dependencies.
I understand that Task is the name of the tool and Taskfile is the format, but I use the terms interchangeably as people do with Make and Makefile. So keep that in mind when reading the rest of this article.
I already know what people are going to say about Taskfile.
YAML again! YAML is everywhere and... I hate it!
I am not a huge fan of YAML either, but in this case, YAML doesn't get in the way.
Some stats about Task's adoption
9.8k stars. When I wrote my first article, there were 8k stars. As you can see from the graph below, they are increasing exponentially in time.
159 contributors (including me). I have created some GitHub issues in the past and started discussions.
Taskfile vs Makefile
I have to say that comparing Taskfile and Makefile is somehow unfair.
Makefile has been around for almost 50 years and is widely used by a vast community. Taskfile has only been around for about 6 years and has a much smaller user group.
What is terrible about Makefile?
Hard to write and read.
Not user-friendly for beginners.
Documentation is extensive but very hard to search.
Cannot easily list targets.
It doesn't support attaching a help description to a target. You need to look into the Makefile source to understand what the target is meant to be doing.
Hard to break a Makefile into multiple files.
If a target is not a filename, you need to label that target as
PHONY
.Targets (hence filenames of the source code to build) have some legacy limitations. No spaces, no colons, etc.
Makefile was initially conceived to be a build system and is very good at it, but when used as a task runner, it is not a very ergonomic tool.
When compared to more modern building tools like Grunt, Cargo, or Maven, respectively, for Javascript, Rust, and Java, Makefile feels like ancient history and should be replaced with something better.
What do Makefile and Taskfile have in common?
Single binary. Any other solution based on interpreted languages (like Python) is more challenging to use.
Runs everywhere on all Operating Systems thanks to its single binary nature.
Small wrapper around command line tools.
Why is Taskfile better than Makefile?
Some reasons in no particular order:
Simple to read/write and friendly to newcomers.
Great documentation. Not extensive, but good enough.
Simple to break a Taskfile into multiple files and import other Taskfiles as dependencies
You can list the available tasks or see a short description of a task or a more extended summary.
Easy templating with Go templates.
Dry-run mode allows printing the shell commands that make a task and easily reproducing the results elsewhere without a Task.
Cross-platform shell interpreter (it works for Windows, too).
Public vs private (aka internal) tasks.
You can defer a command to run after the end of the task.
Watch feature. It can rerun a task when it detects that a list of files has changed. More on this later.
Feedback from my first article
As stated already, my article Taskfile: a modern alternative to Makefile raised quite a few comments on HackerNews.
I'm sorry if I upset some people in the process.
The passage highlighted below caused most of the discontent.
As anyone that writes or interacts with software these days, I need to run automation scripts every day but I am still stuck with a tool that (according to Wikipedia) has been written 47 years ago. Don't get me wrong, Makefile was really useful 20 years ago but I think we can do better than that in 2023.
Someone commented:
[Makefile is...] ...Proof tested because it has been used for 47y.
I agree with that point, but that is not motivation enough to not develop a more modern alternative that better serves the needs of the 21st century.
I realise now that almost 50 years of use have created pockets of fanatic users that are hard to convince.
Even though, I got some positive feedback from HackerNews as follows:
Make is much the same way. It gets the job done, that doesn’t mean it’s good at getting the job done when better alternatives exist.
The attitude of “well it should be hard, the shouldn’t even learn C if they can’t handle make” is explains why my students love Rust so much. Rust has a sane and standardised build system they prefer to use. Make is the Stone Age to them.
I’m just saying Make is an issue for a lot of reasons like accessibility and portability to multiple toolchains and systems
I won't mention the more negative comments here since some are not very productive, but I suggest you have a look if you're interested.
Here is my strong opinion about the topic of hardcore fanatics about Makefile. I believe people who are unhappy about Makefile but still use it somehow suffer from Stockholm syndrome.
Stockholm syndrome is a proposed condition or theory that tries to explain why hostages sometimes develop a psychological bond with their captors
My article on Taskfile inspired my friend Edoardo Tenani to write a piece on the same topic titled To make or not to make.
I share most of the opinions in that article, and I think Edo made some excellent points.
[Makefile...] ...may also be ... affected by “we always do it like that” or “no one has ever been fired for buying IBM” and this is a culture I’m more than happy to abandon.
Make is far from perfect when used as a task runner, something it has not been designed for.
More recently, I watched a video by Viktor Farcic on the benefits of Taskfile vs Makefile called Say Goodbye to Makefile - Use Taskfile to Manage Tasks in CI/CD Pipelines and Locally
The video highlights the importance of being able to run the same tasks on both your laptop and your CI system.
To achieve consistency, the suggestion is to use Taskfile for all your tasks and wrap it around a GitHub action that sets up Taskfile itself.
This is an alternative to tools like Act that allow you to run GitHub workflows locally. In fact, these tools can only partially replicate GitHub actions on your laptop.
Resources
I have mentioned Taskfile in one of my latest paid articles, Unlock SQLite: Easy Data Analysis for Busy Software Engineers.
You can find the relative taskfiles to install SQLite extensions and analyse some CSV files at the GitHub repository Demos.
In the same original article about Taskfile, I also wrote about other automation tools like DevEnv and Direnv that together with Taskfile are part of all my projects. If you are interested more in those technologies instead, look at Effortless Python Development with Nix.
I have a GitHub repository with some generic taskfiles that I reuse in most projects at Taskfiles.
I have also used Taskfiles to set up a development environment to run Elastic Cloud on Kubernetes. You can find the paid article at Dev environment with Elastic Cloud on Kubernetes (ECK) and the relative taskfiles at ECK taskfiles.