Table of Contents

Go and portgen(1)


Here is a diff that adds go support in portgen(1). It's a combination of diffs from my self and afresh1@. There are a few issues, but on the whole this is the direction I think we should take with regard to porting Go application.

The biggest issue with the diff is it's inability to cope with the way Go escapes[1] uppercase letters in URLs. This means that this implementation can't package things like "github.com/gohugoio/hugo" as it has some dependencies like: "github.com/BurntSushi/toml".

As for usage, one needs to get the "module" name from a given program. This is the first line of the "mo.mod" file contained in the program being ported. Once you have that it's simply a call to portgen:

portgen go gthub.com/qbit/gavin

This causes portgen to:

  1. Fetch https://proxy.golang.org/github.com/qbit/gavin/@latest
  2. Grab the latest version.
  3. Fetch the .mod file: https://proxy.golang.org/github.com/qbit/gavin/@v/v0.0.0-20191129154004-5242047b11bb.mod
  4. Call 'go mod graph' to get a list of all dependencies and their versions. We need the .zip files and a handful of .mod files (as described in [1]) to complete the build.
  5. Generate the port.

We are using SUPDISTFILES for the .mod and .zip files as Go doesn't need the zip files to be extracted on disk.

With this diff I can package a number of applications (wireguard, honk and a number of pet projects I have) without issue!

I'd like to get this diff into the tree to make collaboration easier. As it is now, I can build other ports (with portgen) fine, and in-tree go packages build as expected.

[1] https://tip.golang.org/cmd/go/#hdr-Module_proxy_protocol

MMITYWTR (Much More Info Than You Wanted To Read)

Here is an outline of the current methods for creating a Go port and a bit of reasoning as to why I went with the 'go mod' method.

  1. Using GOPATH.


    • Minimal changes to our tree.
    • Easy.


    • Going away in future releases.
    • Prevents Go from using versioned modules (everything basically builds off of 'master' of what ever dependency. This will likely introduce issues that seem like upstream problems, but are actually local to our port.
  2. Using the vendor directory.


    • Easy.
    • Currently in use.
    • Maintains "build integrity" by keeping versioned dependencies in the 'vendor' directory.


    • Requires building / hosting of 'vendor'ed distfiles.
    • Might go away in the future.
  3. Using 'go mod'.


    • The New© Go⑨ Way™. Likely to stay the defacto method for some time.
    • Maintains "build integrity". The binaries we produce in the ports tree are the same as the binaries upstream will produce.


    • More complex to implement.
    • Makes patching an application's dependencies difficult[2]. But one could still fall back to the 'vendor'ed method if patches are absolutely required (this breaks "build integrity" though).

For portgen(1) I have opted to use method 3.

[2] I see this as an advantage, as it will encourage people to upstream diffs first. This raises awareness of OpenBSD and lubes the interactions between program and library developers.

Author: Aaron Bieber

Created: 2022-08-23 Tue 13:14