The Applied Go Weekly Newsletter logo

The Applied Go Weekly Newsletter

Subscribe
Archives
December 15, 2024

Time is skipping • The Applied Go Weekly Newsletter 2024-12-15

AppliedGoNewsletterHeader640.png

Your weekly source of Go news, tips, and projects

Time is flying skipping

Hi ,

"Time flies like an arrow, but fruit flies like a banana." Unit tests should fly like arrows, but tests of timeouts fly like a grindstone. Go 1.24's synctest experiment shall change this, as the first featured article explains.

Speaking of flying bananas time: The year is coming to an end, at least in countries using the Gregorian calendar. The Applied Go Weekly Newsletter goes into "winter break" mode from the following issue on until Jan 12th. This doesn't mean the issues stop coming; I'll be sending "Spotlight-only" versions during the winter break.

So no reason to go bananas. Enjoy the Holiday season!

Featured articles

Coming in Go 1.24: testing/synctest experiment for time and concurrency testing · Dan Peterson

So you want to test timings in the range of seconds but don't want to have your tests run for seconds? A remedy is on the way: Go 1.24 (due February '25) includes the testing/synctest experiment that simulates the time that the tested code observes. Specifically, if all goroutines are asleep for, say, 5 seconds, synctest advances the observed time by the sleep duration immediately.

Go 1.24 Release Candidate 1 is released

Related to the article above: Go 1.24 RC 1 is available for testing!

GitHub - cvilsmeier/go-sqlite-bench: Benchmarks for Golang SQLite Drivers

SQLite has a natural speed advantage over RDBMSs by requiring no network connection—it's an in-app library. But some use cases require squeezing the most out of the DB operations. A fast DB driver helps a lot. Spoiler: The fastest ones (for most of the tests) are two libs that aren't database/sql compatible.

What's Missing From Golang Generics?

Did someone say, "This code looks like Java"?

Podcast corner

Cup o' Go: Update your crypto! And Go 1.24 preview

On crypto security, Go 1.24, weak pointers, compile-time auto-instrumentation, and rethinking DDD in Go.

Go Time: Pitching Go in 2025

Changelog have announced to drop Go Time, so this is probably the last episode, at least on this platform. I'm sure the Go Time team finds another home!

Spotlight: Spread the words: distributing a man page with Goreleaser and Homebrew

In the previous issue's Spotlight, I discussed a few options for writing or generating a man page for a CLI app. That's fine for having one locally, but how to distribute this man page to your app's users?

If you plan to distribute your CLI tool via go install, you can have your binary install the man page on demand:

  1. Use a //go:embed directive to embed the man page in the binary
  2. Add a flag to the tool that copies the man page to /usr/local/share/man/man1/ and ensures that the file mode is 0644.

A nobler way of distributing an app is through package managers. There is a plethora of them, but luckily, there is also goreleaser, a tool that builds releases of your CLI app and manages various package managers for you.

I wrote an introduction to goreleaser on my blog, and a second part where I add Homebrew to my goreleaser config. In these articles, I used the tool goman that I wrote to fake man pages by grabbing the command's README instead. Now I am going to make goman obsolete by telling everyone how to package real man pages alongside their tools! 😉

I won't go through all the steps of the articles again; please read the articles if you're new to either of goreleaser, Homebrew, or goreleaser's Homebrew integration.

In a nutshell, the goreleaser config I built in the second article creates a new Homebrew tap called appliedgo/tools, so that Homebrew users can install goman as brew install appliedgo/tools/goman.

Adding a man page to the Hombrew formula

The goal for today is to modify the goreleaser config file to build the man page and have Homebrew install the man page along with the binary.

This turned out to be surprisingly easy.

Step 1: Build the man page

I decided to write the man page for goman in Markdown and have pandoc turn this into a man page.

goreleaser has a pre-build hook that I utilized for running pandoc. The original pre-build hook looked like this:

before:
  hooks:
    - go mod tidy
    - go mod download

The before.hooks property runs commands before the build, and I use this to tidy the dependency file and download missing ones.

For generating the man page, I only had to add this line to the list in order to invoke pandoc:

    - pandoc -s -t man goman.1.md -o goman.1

Step 2: Add the generated man page to the archive files

goreleaser builds binaries for several OS/architecture combinations (based on what I told it). In the archives.files property, I tell goreleaser which files to zip up with the binary for getting released on GitHub:

archives:
    files:
      - README.md
      - LICENSE*

Here, I added the generated man page:

      - goman.1

Step 3: Ask Homebrew to install the man page

Finally, Homebrew must know that there is a man page to install. Homebrew makes installing man pages dead easy by providing a man1.install directive that I added to goreleaser's brews.extra_install property. (The extra_install property lets me add installation steps without overriding the whole installation procedure.)

brews:
  - repository:
      owner: appliedgo
      name: homebrew-tools
# ...omitted for brevity...
    extra_install: |
        man1.install "goman.1"

(Fun fact: Homebrew formulas are Ruby code, and if you don't put the man page file in quotes, Ruby thinks goman.1 is a floating-point number and complains loudly.)

Wrapping all up

Now I only had to create a new Git tag, push the changes to the remote repo, and run goreleaser release.

The goman.1 file is now included in all .gz files of the release, and the Homebrew formula will install it to the appropriate man1 directory.

Now goman behaves a bit more like a well-mannered Linux/macOS CLI tool. What's your next tool to equip with a man page?

Quote of the Week: Less documentation

The better the software, the less documentation it needs.

–John Arundel

(Ideally, it needs just a man page, right?)

More articles, videos, talks

Go (Golang) Performance Benchmark (gnet vs fiber vs fasthttp vs net/http) - YouTube

HTTP routers aren't usually a performance bottleneck in Web apps. But for high-traffic web apps, you'd better pick a high-performance router. This video compares net/http, gofiber, fasthttp, and gnet.

Errors, Errors Everywhere: How We Centralized and Structured Error Handling | Oliver Nguyen

Go treats errors as values. And just like values, if you have too many of them, you'd want to organize them somehow. Oliver Nguyen presents a centralized error handling system that works with categories, tags, and error trees to avoid growing a hodgepodge of error handling approaches within a single app.

Nuage | Articles/Templ vs Gomponents

Which templating library should you pick? A shoot-out between Templ, Gomponents, or plain html/template.

5 Mocking Techniques for Go | Golang Mocking for Unit Testing

Whatever your stance on mocking external dependencies in unit tests is, you should at least know the mocking techniques used in Go.

Enhancing Go performance: Profiling applications with flamegraphs | Costa on Software

There is NOT only one way to turn a performance profile into a flame graph.

Data structures as jigs for programmers (Go edition)

The author creates an interesting analogy between programming and woodworking to demonstrate how simple data structures like slices and maps can go a long way.

(Double points if you dance to an Irish or Scottish jig while reading the article.)

How to use migrations with Golang | ️Albert Colom

Program code and version control go well together, but what about database schemas? While a schema has a "code" representation, you need a way of up- or downgrading a database to a given schema version. This is where tools like golang-migrate or goose come in handy. Here is a hands-on tutorial.

Gist of Go: Pipelines

Anton Zhiyanov's interactive Go book is growing. Latest chapter: pipelines.

Organizing Your Go Code: Tips for Beginners

Remember: There is no single Go project file layout. Choose the layout that fits your use case. Start minimal; the layout will grow with your project.

Demystifying OTPs: the logic behind the offline generation of tokens

How does a One-Time Pad (OTP) work? Find it out by writing one in Go.

Things You Never Wanted To Know About Go Interfaces

Or maybe you want but you didn't know that you wanted?

Projects

Libraries

GitHub - xybor-x/enum: Elegant and powerful Go enums with zero code generation

Goals of this enum library are compatibility with iota-style "enums", no code generation, and type safety (when giving up iota compatibility).

GitHub - ymz-ncnk/go-client-server-communication-benchmarks: Compares the performance of several client-server communication libraries/frameworks for Golang

Which is faster, gRPC, Kitex, or cmd-stream-go?

GitHub - crazywolf132/conduit: Because life's too short for complicated socket programming!

Communication pipelines without the plumbing.

Tools and applications

GitHub - essentialkaos/aligo: Utility for checking and viewing Golang struct alignment info

For some apps, every byte of memory counts. aligo helps optimize structs by visualizing their memory layout.

GitHub - Abathargh/stropt: C struct optimizer

This must be the week of struct optimizers. This issue lists a visual optimizer for Go structs elsewhere in the "Tools and apps" subsection, and here is a memory layout optimizer for C structs.

fontseca.dev — fontseca.dev's RPC-like API

Wow. A personal website built upon 70 API endpoints. Overkill? You decide. In any case, it's a great project for studying the GoTH stack (Go, Templ, HTMX) in real life.

GitHub - go-dockly/garm: Advanced ARM64 Compiler for High-Performance on the GO

The author wrote this ARM64 compiler because he was "unhappy with go's current state of Plan9 assembly mess and the many arm64 capabilities that remain untapped."

GitHub - armand-sauzay/note: ✍️ take notes in your terminal ✍️

Create and organize Markdown notes in your terminal. With Vim-style keybindings.

GitHub - MegaGrindStone/doconvo: A Terminal User Interface (TUI) application that enables interactive conversations with your documents using Large Language Models (LLM) and Retrieval-Augmented Generation (RAG) techniques.

Not every chatbot requires a web page.

Antonio Pitasi

A personal website built with GoTH... not! It's all standard library. (Source code here)

Completely unrelated to Go

"Rules" that terminal programs follow

While there is no strict rule set that CLI tools follow, a canon of rules or patterns emerged over time. If you plan to write an app, make sure to follow these patterns to delight your users.

Can Postgres cover your NoSQL needs? · Blog · Liip

For many backend devs, PostgreSQL is their go-to database in every situation. But can PostgreSQL even replace NoSQL databases?

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.