Header banner: Sunset over Nuremberg's Wöhrder Lake in the winter, 2025

Present with Go Modules

There are a few quite interesting utilities in the Go Tools collection, golang.org/x/tools. One of these is the slide presentation software present.

$ go install golang.org/x/tools/cmd/present@latest

If you have watched any Go presentations in the past, there is quite a chance you have already seen present in action. For example, many of Rob Pike’s talks are using present, e.g., his talk on lexical scanning.

present renders Markdown-ish files to either slides or articles - such as for the Go blog - to be displayed in a web browser. Although the feature set is limited, one killer feature is the ability to execute code directly from the slides. The golang.org/x/tools/present package describes the anatomy of a .slide input file and all available commands.

.play Some Code

The mentioned code execution killer feature is named .play and allows not only embedding code, but actually executing this code. For example, the following line in a .slide file would display the content of some demo.go file, make the text box editable, and allow the code to be executed.

.play -edit demo.go

Earlier this year, I have used this for my “Privilege Separation In Go” talk at FOSDEM. At around the 02:00 mark in the linked talk, you can see me altered the code to demonstrate the privileges with which the code usually runs.

Later in the talk, I showed multiple Go libraries that I used directly within present. This, however, was quite a hassle since present - being an older, not so official Go tool - still relies on the $GOPATH. Since time was not on my side, I have ended up filling the $GOPATH manually. And all this over six years after Go 1.11, deep in the age of Go Modules.

Since I was planning to work with external libraries in present again, I settled to patch it in this regard. Just to find out that it can already do this.

.play Me A Go Module

The .play command works not only on Go code, but also on the txtar archive format, which I just learned about today (actually, it was yesterday - I am now finishing this post). In a nutshell, it is a plain text format concatenating multiple text files, each being introduced by a -- FILENAME -- marker, with FILENAME being the actual file name. There may also be a comment before the first file’s marker.

The .played file will be parsed as a txtar archive. If the file is an ordinary Go source code file, there will be no marker and everything is part of the leading comment. A non-empty comment will then be treated as a prog.go file. However, if the input contains txtar entries, each one will be created. Additionally, if a go.mod file is included in the txtar input, the Go code will be built as a Go Module.

In practice, this looks like the following. For example’s sake, I am using the SHA-3 TupleHash library I wrote a while back.

$ go mod init demo
go: creating new go.mod: module demo

$ cat main.go
package main

import (
        "fmt"

        "codeberg.org/oxzi/go-tuplehash"
)

func main() {
        fields := [][]byte{[]byte("foo"), []byte(""), []byte("bar")}
        h := tuplehash.NewTupleHash128(nil, 32)
        for _, field := range fields {
                _, _ = h.Write(field)
        }
        fmt.Printf("%x\n", h.Sum(nil))
}

$ go get codeberg.org/oxzi/go-tuplehash
[ . . . ]
$ go build

$ cp main.go demo.txtar
$ for f in go.{mod,sum}; do echo "-- $f --"; cat "$f"; done >> demo.txtar

This can be demonstrated with a simple .slide file as follows. The /^func main/,/^}/ part behind the .play calls reduces the printed output to the main function for aesthetic reasons.

# External Module Test

## Go File - Fails

.play main.go /^func main/,/^}/

## Go File from txtar - Works

.play demo.txtar /^func main/,/^}/
Screenshot of present failing due to the missing package.

First, present fails due to missing packages - as expected.

Screenshot of present running the code and printing some output.

The second example based on txtar works and produces a hopefully valid output.

.play Me Any Script

While poking through the playground socket code, I made another unexpected discovery: shebang support! If the code starts with a shebang (#!), then it will not be compiled as a Go application, but executed by the shebang interpreter. Therefore, present can be used to run almost any code.

Let’s demonstrate this with an even simpler example of the following .slide:

# Shebang Test

## Python

.play -edit demo.py

And demo.py looking like this:

#!/usr/bin/env python3

import this
Screenshot of present displaying and running the Python script.

present executing a Python script running the PEP 20 easter egg.

Swimming Upstream Is Hard

First and foremost, a random blog post should not be the place to document implementation behavior. Documentation should be, well, in the docs. I have created a pull request, so let’s see how it turns out.

Google’s contribution maze for Go typically guides one through their Gerrit code review tool. Last time I have used it was roughly two years ago and, of course, it requires a Google account. And this was also the last time I have used my Google account, which still has a @googlemail.com address instead of @gmail.com. What’s my age again?

When I tried to log in to this account, Google blocked the login because it thought there was something suspicious about me. As so called “options” to unblock the account, I should either use the same device or a similar location as last time - I have moved roughly 300km. That’s all, no other options.

No Gerrit for me today. This is just another downsides of big tech FOSS projects.

It’s Not A Bug, It’s A Feature

When people ask me what I like about Go, I usually mention its well documented API. As being part of the /x/ namespace, the Go Tools are not so official, but once I became accustomed to the high quality documentation, their lack stood out. And in this case, it misses two very special cases of executing code.

Taking a look at the txtar extraction logic is also a bit scary. Yes sir, I would like you to extract ../../../../../etc/passwd. This has only no further security implications as arbitrary user-supplied code will be executed next.

Thus, do not let present run wild and only execute trusted .slides.

Speaking of undocumented behavior, I tried the same thing in the Go Playground and was quite surprised that the txtar trick worked there as well. Unlike the other code, the Go Playground has some input sanitation in place. Unfortunately, there seems to be no shebang support.

Screenshot of the Go Playground executing the same txtar example from above.

Go Module in the Go Playground as txtar encoded input.

All The Negativity?

The last two sections turned out quite bitter, and I failed to find a way to change that. However, I wanted to end on a positive note and emphasize one more time that I really enjoy working with present. It is a fantastic tool, especially for presentations with code. Use it!