The Applied Go Weekly Newsletter logo

The Applied Go Weekly Newsletter

Subscribe
Archives
December 8, 2024

RTFM • The Applied Go Weekly Newsletter 2024-12-08

AppliedGoNewsletterHeader640.png

Your weekly source of Go news, tips, and projects

RTFM

Hi ,

Please read the fu... the fri... um, er, the fine manual!

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:

  1. Write them manually
  2. Use Pandoc
  3. Use muesli/mango
  4. Use cpuguy83/go-md2man
  5. 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.

Check it out.


Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany

Don't miss what's next. Subscribe to The Applied Go Weekly Newsletter:
LinkedIn
Powered by Buttondown, the easiest way to start and grow your newsletter.