Five Nice Things for Machine Generated Code

With the introduction of //go:generate, Go made it easier to integrate auto-generation tools into your build. Tools like stringer eliminate writing repetitive code by hand, while programs like yacc and ragel make it possible to generate optimized parsers. There’s an incomplete list of these tools on the Go Wiki at GoGenerateTools

Mark the code as autogenerated. In order for the generated source code to be recognized by the build tooling, there must be a comment that matches this regular expression:

^// Code generated .* DO NOT EDIT\.$

This text must appear as the first line of a properly formatted Go // comment, and that comment must appear before but not be attached to the package clause and before any /* */ comment. This is similar to the rules for build tags. Files with this header will be ignored by Go Lint and collapsed by default by GitHub in PRs and diffs. It’s also nice if you indicate the name of the tool and the arguments that produced the file.

Use _ when needed. Assigning to _ can simplify your code generation step by always importing maybe-needed packages and assigning a method or package-level variable to_, and similarly for variables that may end up not getting used.

gofmt the output. People will be reading the code while debugging issues — it’s nice if it’s formatted. Also, since editors will gofmt on save, this prevents accidental whitespace changes. You should probably run other linters on the generated code, at least for correctness. Lint violations are Ok (but discouraged), as code written by machines is held to a lower standard than code written by people.

Have deterministic output. Multiple runs of the tool without changing the input should generate the same output. Don’t rely on map ordering or add randomness to the output. I have mixed opinions on timestamps. It’s nice to know when the file was generated, but if there no updates to the file, it’s maybe nice not to output anything at all.

Have readable diffs. This ties into the previous point. People commit code to repositories, and if they generate a new file it’s nice to be able to look at the changes when there’s an update and see the effect it had on the code.

These are some things I’ve noticed when working with code generation tools that make me happy (or more likely when using code generation tools that make me sad). What do you like to have in auto-generated code?