RTFM • The Applied Go Weekly Newsletter 2024-12-08
Your weekly source of Go news, tips, and projects
RTFM
Hi ,
Please read the fu... the fri... um, er,
Small problem: Many Go-based CLI tools have no manpage. The man
command, however, is the standard Unix way of providing user manuals for CLI apps. I think once a Go CLI tool is getting distributed through OS package managers, it should come with a man page. It's not that hard to write one; this week's Spotlight lists several ways.
Thinking of it, it's intriguing to observe how many Unix tools and standards have survived for decades, despite more modern, more capable, prettier alternatives. The authors of the early Unix tools seem to have been right to focus on simplicity and robustness. Features that also apply to Go, and many gophers take this spirit forward into their own simple, robust apps.
As Leonardo da Vinci, the universal genius from the 15th century, (didn't) say, "Simplicity is the ultimate sophistication."
Featured articles
Union types ('enum types') would be complicated in Go
Sure, the Go maintainers want to keep the language small and the syntax simple. But these are probably not the main reasons why Go has no union types.
Follow-up article: Good union types in Go would probably need types without a zero value
Weak Pointers in Go: Why They Matter Now
The garbage collector won't clean up allocated memory as long as a pointer references that memory. There are scenarios, however, where an existing reference should not prevent memory cleanup. Weak pointers achieve that goal: They go out of the way of the GC's work and get set to nil
automatically if the memory they point to gets freed.
Why Clean Architecture and Over-Engineered Layering Don’t Belong in GoLang
A rant about bringing unidiomatic ideas to Go, such as 7+ architecture layers. TL;DR: Separation of concerns never needs more than 3 layers.
The comments read like love letters to Go:
What I like about Go is you can open a random file in a project and expect to find real code inside. That does something. You can follow along.
For real, after 10 years of professional Java + Spring development I've been working with Go for a year, and it's beautiful: easy, no boilerplate, no nonsense, everything is pure simplicity.
A package in Go has properties that make it class-like, as well as project-like. Whether it behaves more like a Java class or a Java project is completely up to the developer. It’s so freeing.
I love how Go forces you to simplicity, and it's not a trap. Simplicity is grossly underestimated and often undervalued, but it's the greatest asset when you want to create something in an effective and fast manner.
Go 1.23.4 and Go 1.22.10 have been released
Yay! Finally, we're at Go 1-2-3-4.
Podcast corner
Cup o' Go: One and two and three and four and proposals!
Your weekly potpourri of Go news! Noteworthy: Phil Pearl's article about the cost of clearing a map.
Spotlight: Does your CLI tool have a man page?
If you're into writing CLI tools in Go, chances are you implement a help
sub-command or a --help
flag for each one, or have the CLI framework of your choice generate help output for you.
Awesome, but what about man pages? Unless your CLI apps are made for Windows only, you'd surely want to make your CLI tools well-behaved inhabitants of the Unix ecosystem. And this means your CLI app should come with a man
page.
Luckily, there are several ways to create man pages for your Go app, including:
- Write them manually
- Use Pandoc
- Use muesli/mango
- Use cpuguy83/go-md2man
- Use Cobra
So you need at least five excuses for not adding a man
page to your CLI project. Better write one!
1. Write them manually
Maybe this comes as a surprise, but manpages are actually plain-text files that use a fairly simple markup language.
A typical manpage is structured like this:
SOMETHING(SECTION) User Manual SOMETHING(SECTION)
NAME
SOMETHING - briefly describe SOMETHING
SYNOPSIS
formal description of invocation
DESCRIPTION
detailed multi-line description
OPTIONS
explain/list parameters and arguments
EXAMPLES
usage examples
SEE ALSO
list related objects
AUTHOR
author(s) + contact information
COPYRIGHT
copyright/license info
VERSION DATE SOMETHING(SECTION)
Other possible sections would be ENVIRONMENT, EXIT STATUS, FILES, BUGS, or HISTORY.
Every man page belongs to a numbered section. CLI tools belong to section #1. The man
command looks for matching man pages in each section in ascending order. If two man pages of the same name exist in different section, use man
to open the page in the desired section.
Let's create a minimal man page for a tool called noop
. To format the page, the example uses "man macros"—short codes at the beginning of a line, starting with a dot. See man 7 man
for more information about the macros syntax.
(Side note: BSD-based Unixes like Darwin prefer the mdoc
markup language. If you run man 7 man
there, the page claims that the man macros are a "legacy" formatting language.)
Our example page uses three marcos:
.TH [name of program] [section number] [center footer] [left footer] [center header]
: This information will be shown in the header and footer of the page, respectively..SH [string]
: A section.TP
: A "hanging tag". The first line below.TP
is indented normally, the following lines get an extra indent. Used for flag descriptions.
There are quite a few more macros available, but these three are enough to get started:
.TH "NOOP" "1" "December 08, 2024" "Noop User Manual"
.SH NAME
noop
.SH SYNOPSIS
noop [\-v] [\-a]
.SH Description
noop does nothing.
.SH OPTIONS
.TP
\-v
Verbose output.
.TP
\-a
Do absolutely nothing at all.
.SH AUTHORS
Christoph Berger.
Save the above text to a file named "noop.1" (the extension represents the section number) and pass it to the man
command:
man ./noop.1
You should then get a page similar to this one:
NOOP(1) General Commands Manual NOOP(1)
NAME
noop
SYNOPSIS
noop [-v] [-a]
Description
noop does nothing.
OPTIONS
-v Verbose output.
-a Do absolutely nothing at all.
AUTHORS
Christoph Berger.
Noop User Manual December 8, 2024 NOOP(1)
That was quite easy, wasn't it?
To "install" a man page,
1. Copy it to /usr/local/share/man/man1/
(or the appropriate section)
2. Ensure the copy has mode 0644
3. gzip
it
Two options (source: linux.org):
cp noop /usr/local/man/man1/noop.1 && chmod 0644 /usr/local/man/man1/noop.1 && gzip /usr/local/man/man1/noop.1
A shorter version, using the install
command:
gzip noop.1 && install -g 0 -o 0 -m 0644 noop.1.gz /usr/local/man/man1/
Add these steps to the installer of your choice (such as goreleaser) or your favorite build tool.
2. Use Pandoc
Pandoc converts almost any open text format to almost any other open text format. You can make use of this to write your manpage in Markdown, with a few "extras" such as the pandoc_title_block or definition_lists extensions, that you can see in action in this sample Markdown manpage:
% NOOP(1) Noop User Manual
% Christoph Berger
% December 08, 2024
# NAME
noop
# SYNOPSIS
noop [-v] [-a]
# Description
noop does nothing.
# OPTIONS
-v
: Verbose output.
-a
: Do absolutely nothing at all.
Run this through pandoc
and man
to get the same man page as before:
pandoc -s -t man noop.md -o noop.1 && man ./noop.1
3. Use muesli/mango
muesli/mango generates man pages from Go flags or pflags, or from CLI frameworks like Cobra, Coral, or Kong.
Mango is a package, not a command, so you can make your CLI tool generate a man page on demand (for example, during the installation process).
4. Use cpuguy83/go-md2man
Similar to Pandoc, the go-md2man
tool converts Markdown files into manpage format. The exact Markdown format is not documented, but a peek into the raw version of go-md2man.1.md gives a few hints.
5. Use Cobra
The Cobra CLI framework features automated man page generation based on the data you would supply to the subcommand definitions anyway.
As of this writing, the exact way of generating a man page with Cobra is not documented.
Summary
CLI tools should follow certain standards, regardless of the language they're built with. Man pages are the Linux standard of documenting CLI tools, and the above list should contain a man page generation option for every taste.
Go build awesome tools!
Quote of the Week: Project completed
Oh completed...lol
–u/imscaredalot
's answer to "What's the proudest Golang project you've completed in Golang?"
More articles, videos, talks
How to break production on Black Friday | Jakub Jarosz
Want to nuke a Kubernetes cluster? Here's a playbook.
Part 2 (of 3) is also out: How to prevent panics in Go
Using CloudEvents in Go
CloudEvents is a specification for events used in event-driven architectures (EDA). This article presents a simple example of working with the CloudEvents Go SDK.
Diving into eBPF: Building a Process Tracer from Scratch!
Or: How to use eBPF in Go without using CGO.
As the author points out, "Some people, when confronted with a problem, think “I know, I’ll use CGO.” Now they have two problems."
Caching in Go | MzunguDev
A little copying coding (109 lines) is better than a little dependency.
– Not a Go proverb (yet)
Things I love about Golang - by Thane Thomson
Yet Another Love Letter To Go™. (Yes, there are many, and yes, there's a reason. Or rather, plenty of reasons.)
Building a distributed log using S3 (under 150 lines of Go) - blag
Your app shall run with zero disk space? That's cool, simply log to S3.
Awful ways to create Pipelines with Go – Poxate
Spoiler: Not all ways of creating pipelines are awful. (Archived version)
Coding/Programming | csgeek0x7bc | Substack
A journey through (the learning of) BubbleTea. More chapters to come.
AOC 2024, Day 1: Missing abs() for integers
The author wondered about a missing abs()
for integers and ended up dissecting abs()
for floats and learning about the evolution of the math
package.
Gist of Go: Channels
Learn Go channels the interactive way, powered by Codapi.
Blockchain-Based Chain of Custody (B-COC): Revolutionizing Evidence Management for Law Enforcement 🚓🔒
One of the most unusual Go projects I heard of: a blockchain implementation in Go for tamper-proof evidence tracking in police investigations.
Projects
Libraries
GitHub - jairad26/go-simd: Golang Assembly and SIMD
SIMD = Single Instruction, Multiple Data. A type of parallel processing that allows a single instruction to operate on multiple data points simultaneously.
If your ARM64 CPU supports Neon SIMD, this package can accelerate your code using just assembly and no CGO.
GitHub - crazywolf132/secretfetch: Your secrets deserve better than hardcoding. SecretFetch makes secret management a breeze!
Fetch AWS secrets right into your Go structs.
GitHub: gobigbang/binder: Http binder
A partial rewrite of https://echo.labstack.com/docs/binding
Tools and applications
GitHub - DataDog/orchestrion: Automatic compile-time instrumentation of Go code
Orchestrion injects instrumentation at compile time. Datadog built this to avoid the disadvantages of common instrumentation injection options like binary patching or eBPF.
GitHub - phillipahereza/omniClip: Decentralised P2P Universal clipboard
Like Apple's Universal Clipboard but without Apple.
Clave - Simple, Secure Authentication
A 2FA app for the desktop.
GitHub - EmBachlitzanakis/GoShell: GoShell is a customizable, lightweight, cross-platform shell built with Go. It allows users to execute commands, navigate directories, and interact with the system in a terminal-like environment. With support for both Windows and Unix-like systems
If you want to know how to write a shell in Go, look at self-learning projects that are still small and clean like this one.
GitHub - vinceanalytics/vince: Self Hosted Alternative To Google Analytics
An open-source, privacy-first analytics server in Go, with no dependencies on other apps (like a database system or redis cache).
GitHub - crazywolf132/ultimate-gomake: The ultimate makefile for any golang project
All build actions you probably ever need for Go projects!
GitHub - glojurelang/glojure: Clojure interpreter hosted on Go, with extensible interop support.
Can't decide between Go and Clojure? Now you can have both. Glojure is a hosted language, which means that all Go values can be used as Glojure values and vice versa.
Completely unrelated to Go
Evolving my ergonomic setup (or, my laptop with extra steps)
What's the advantage of an ergonomic computer setup? The ergonomics, you think? Well, Nicole Tietz-Sokolsaya discovered another advantage: *"Engineers ask me about it, and everyone else ignores me."'
I want one.
The World Wide Web project
Some of you may know the website that (jokingly) claims to be "the last page of the internet".
The first page of the World Wide Web, on the other hand, exists for real—no joke!—, and is still online.
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