2 make || ! 2 make • The Applied Go Weekly Newsletter 2024-11-24
Your weekly source of Go news, tips, and projects
2 make || ! 2 make
Hi ,
Few software tools survive for decades almost unchanged. A build tool named make
is one of these. Is it a good fit for Go? In this week's Spotlight, I focus on one particular aspect of make
and make
-like tools: How file changes are detected.
A quick announcement
Black Friday is nearing, and my course Master Go is $60 off until Dec 2nd. If you're still new to Go, or know someone who is, this is a great occasion to level up. More info at AppliedGo.com.
Featured articles
4 Ways of Bumping Major Versions in Your Go Project
A new major version means breaking changes. A project bumping its major version must ensure that users of the previous version won't accidentally upgrade to incompatible code. Jerry Ng presents four options for increasing the major version number. What's your favorite?
Golang + htmx + Tailwind CSS: Create a Responsive Web Application
Javascript haters love this one weird frontend framework. HTMX turns boring static websites into interactive apps without drowning the app in Javascript
GoMLX: ML in Go without Python
Using AI programmatically usually requires reaching out to Python, the most popular language in the machine learning and data science spaces.
GoMLX brings the low-level ML mechanics to Go without the need for routing every action through Python scripts.
Podcast corner
Cup o' Go: 🔏🇺🇸 The FIPS Episode including an interview with Alex Scheel
This episode is particularly secure: Jonathan and Shay talk to Alexander Scheel of GitLab about FIPS 140-3 "Security Requirements for Cryptographic Modules".
Go Time: Unpop roundup! 2023
The Go Time team continues catching up on unpops. After the 2022 roundup, here is the one for 2023.
Spotlight: Make vs. Taskfile vs. Justfile
Go's feature-rich toolchain is all you need to build, test, or benchmark a Go module. This is the end of the Spotlight, have a good day.
Oh, wait, I get that complex build scenarios call for specialized build tools. If a build consists of more than a single, pure-Go module, many developers and teams turn to the good old make
tool.
make
exists for almost half a century. Created in 1976, it was designed for building C apps and libraries on Unix. Its build mechanism is universal enough for use with other languages and even for automating tasks that are not strictly labelled as build tasks.
However, make
has its quirks and limitations that make developers look for alternatives. Two modern, make
-like tools are Taskfile and Justfile.
I could compile a long feature comparison between the three, but this is a Spotlight, hence short, so instead I want to focus on the most important feature and key differentiator: Managing dependencies.
A build tool should avoid unnecessary work by building only those targets whose dependencies were updated since the last build. It turns out that each of the three tools has a unique approach to change detection.
Make
The make
tool detects changes by looking at the timestamp of the files a target depends on.
The following Makefile compiles hello.c
in to a hello
binary if hello.c
is newer than the binary:
hello: hello.c
cc hello.c -o hello
This is a simple and robust approach that works well on local filesystems… usually.
However, file timestamps can be unreliable for various reasons. System inconsistencies, time zone changes, or tools that manipulate timestamps can mislead make
.
Taskfile
Taskfile is a task runner and build tool written in Go, aiming to be more readable than the Makefile syntax. Taskfile has
a different method of detecting dependency updates: Instead of looking at timestamps, Taskfile takes checksums of each dependency and saves them to the local .task directory. On subsequ
ent builds, Taskfile compares current checksums with the saved ones.
This strategy circumvents the unreliable timestamp method, although Taskfile has an option for comparing by timestamp if desired.
Here is a Taskfile that runs go test
only if the sources have changed:
version: '3'
tasks:
test:
desc: Run tests when source files change
sources:
- '**/*.go'
- '**/*_test.go'
cmds:
- go test ./...
The first invocation runs the tests, the second one says that everything is up to date:
> task test
task: [test] go test ./...
ok hello 0.251s
> task test
task: Task "test" is up to date
Taskfile does not get confused by tweaked timestamps:
> touch hello.go
> task test
task: Task "test" is up to date
The test would not run unnecessarily, which is great for long-running unit or integration tests.
Justfile
The third contender is Justfile. It's syntax is closer to the Makefile syntax than Taskfile's syntax; yet, Jusfile advertises itself as a command runner and not a build tool. Consequently, Justfile does not have, nor check, file dependencies. Justfile's recipes can only depend on other recipies, which are executed unconditionally.
This discovery was a bit of a surprise when I evaluated Justfile as a make
alternative; however, as a plain command runner, Justfile does a nice job.
Conclusion
Make is the grande dame of build systems and still the #1 choice for many projects. However, if reliance on timestamps is a problem, Taskfile is a top alternative. Justfile turned out to focus on managing and running scripted commands without dependency checks. I decided to include it here as this aspect may not be apparent until carefully searching through the documentation to determine the absence of dependency checking mechanisms. If this info saves you time, mission accomplished.
The above list is not complete by far. Quite a few make
alternatives, build tools, and task runners have been created over the years, including:
- Mage, a pure-Go build tool
- Earthly—"as if Dockerfile and Makefile had a baby"
- Bazel, a build system using an imperative build language (Starlark)
- And many more.
- And, of course: Nothing. Because you can get quite far with the Go toolchain alone.
Read more
- Home | Task
- Just: A Command Runner
- Why you should be using Taskfile | by Martin Ricken | Medium
- WIP: Taskfile instead of Makefile? | DevCube
- Introduction to Taskfile: a Makefile alternative - DEV Community
More articles, videos, talks
Wakapi: my first contribution to the open source
See also the follow-up post: Self-Host Wakatime Stats with Supabase & Cloud Run
Go’s Pointers & Memory Management: A Deep Dive
Pointers make all the difference in the world. Especially if your previous world was Python.
Developing a Terminal App in Go with Bubble Tea - YouTube
The term "terminal app" sound so... terminal. Have a cup of bubble tea and all's good again.
Lessons learned adding OpenTelemetry to a (Cobra) command-line Go tool · Jamie Tanna | Software Engineer
Half of the learnings are actually positive!
Testing with Go and PostgreSQL: ephemeral DBs - Michael Stapelberg
Ephemeral PostgreSQL databases for integration testing? Sure, why not. An instance starts in less than a second, and creating a database takes even less.
Hyrum's Law in Golang / Abenezer Belachew
Hyrum's Law applies universally to any API and language. Go goes one step further and contains references to Hyrum's Law in its source code.
Projects
Libraries
GitHub - Juanfec4/velocity: A high-performance "Express-like" HTTP router for Go
The author built this Express.js-like HTTP router to explore the different approaches of Go vs Javascript on implementing routers:
JavaScript libraries like Express.js often lean into dynamic typing and heavy use of middleware chaining, while Go demands explicitness, type safety, and simplicity. These differences presented interesting challenges:
- Middleware handling: How could I replicate Express-style middleware stacking in Go while staying idiomatic?
- Dynamic route parameters: Express allows developers to easily define routes with dynamic segments. Could I bring this ease to Go without sacrificing performance?
- Syntax simplicity: Express.js has an intuitive syntax. I wanted my router to maintain a similar level of developer experience while working within Go’s constraints.
GitHub - stroiman/go-dom: DOM implementation for Go (not usable work in progress, but contributors are welcome)
Headless browsers are great for automatic testing of Go web applications. Even better if the headless browser is implemented in Go. (But note it's a WIP in a very early stage.)
GitHub - donseba/go-partial: Go partial is a HTMX companion library to render partial HTML based on a configurable header
Originally written as a companion to go-htmx
, go-partical
provides a way of letting HTMX or alpine-ajax fetch partial templates for rendering.
GitHub - teilomillet/raggo: A lightweight, production-ready RAG (Retrieval Augmented Generation) library in Go.
For those of you who haven't dug into AI's various mechanisms yet: Retrieval-augmented generation (RAG) turns documents into data digestible by large language models. A.k.a. "talk to your documents".
Tools and applications
GitHub - jesusprubio/up: 📶 Troubleshoot problems with your Internet connection
"It started as a bash script, migrated to Ruby, then to Node.js. Some years ago I wrote it in Rust and, finally, I decided to do it properly in my day to day language."
GitHub - HubertBel/lazyorg
A rare occurrence: While almost every interactice TUI app seems to be written with one of Charm's libraries (Bubble Tea, Lipgloss,...), this one was made with a classic TUI package: gocui
.
GitHub - luqmanshaban/movie-streamer-golang
The author got cut off of the internet, and the only two movies on the laptop came with terrible sound quality? What does a developer do in this case? Writing a streaming server, of course! Result: The movies got streamed to the mobile phone like a charm.
GitHub - charmbracelet/sequin: Human-readable ANSI sequences 🪩
Tired of debugging cryptic ANSI sequences? sequin
translates ANSI gibberish to human text.
> printf ' (x1b[38;5;4mCiao, (x1b[1;7mBaby. \x1b[0m\n' | sequin
CSI 38;5;4m: Foreground color: 4
Text Ciao,
CSI 1;7m: Bold, Inverse
Text Baby •
CSI 0m: Reset style
Ctrl \n: Line feed
GitHub - watzon/goshot: 🎨 Create beautiful code screenshots with customizable styles
Similar to Carbon and Silicon, goshot
creates a social-media-ready screenshot of your code. Comes as a CLI and a library.
GitHub - PeterKwesiAnsah/bitty: A bitTorrent client built from scratch using Go.
Peer-to-peer file sharing in Go. Download .torrent
files
GitHub - manjurulhoque/threadly: A real-time discussion platform inspired by Threads, built with Golang and Next.js. Enables users to create, engage with, and manage threaded conversations seamlessly.
Threads without Meta. Even if you don't want to start another social media platform, the project could be great for analyzing how a rather complex full-stack web app can be built with Go.
Completely unrelated to Go
They all use it
What makes a developer unwilling to even try AI products? Have devs lost their natural curiosity that brought them to software development in the first place?—A rant by Thorsten Ball.
Importing a frontend Javascript library without a build system
Why do gophers love server-side rendering so much? Because wrestling with a plethora of frontend build systems only to get some javascript on the page is annoying. Julia Evans found her way around those nasty build systems, but it's not straightforward either, so she decided to write down all the steps and cases.
On Good Software Engineers
What makes a good software engineer? Hint: "10x engineer" isn't it.
IMG_0416
Early iPhones had a "Send to Youtube" feature that uploaded videos with their technical names by default. Try searching for IMG_0001...
Happy coding! ʕ◔ϖ◔ʔ
Questions or feedback? Drop me a line. I'd love to hear from you.
Best from Munich, Christoph
Not a subscriber yet?
If you read this newsletter issue online, or if someone forwarded the newsletter to you, subscribe for regular updates to get every new issue earlier than the online version, and more reliable than an occasional forwarding.
Find the subscription form at the end of this page.
How I can help
If you're looking for more useful content around Go, here are some ways I can help you become a better Gopher (or a Gopher at all):
On AppliedGo.net, I blog about Go projects, algorithms and data structures in Go, and other fun stuff.
Or visit the AppliedGo.com blog and learn about language specifics, Go updates, and programming-related stuff.
My AppliedGo YouTube channel hosts quick tip and crash course videos that help you get more productive and creative with Go.
Enroll in my Go course for developers that stands out for its intense use of animated graphics for explaining abstract concepts in an intuitive way. Numerous short and concise lectures allow you to schedule your learning flow as you like.
Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany