Site icon Golang Libraries, Apps, Golang Jobs and Go Tutorials

A CLI Tool for CI/CD pipelines to prevent Golang spaghetti code

A Golang-based command line tool for CI/CD pipelines (and dev machines) that helps to prevent Go spaghetti code (a.k.a. big ball of mud).

Thankfully, in the Go world, the compiler already prevents circular dependencies between packages. So this tool has to care only about additional undesired dependencies.

I gave a talk that included the motivation for this tool and some (old) usage examples: 

Additionally, this tool documents the structure of a project in its configuration.

Usage of the Golang CLI Tool

You can simply call it with go run github.com/flowdev/spaghetti-cutter from anywhere inside your project.

The possible command line options are:

Usage of spaghetti-cutter:
  -e    don't report errors and don't exit with an error (shorthand)
  -noerror
        don't report errors and don't exit with an error
  -r string
        root directory of the project (shorthand) (default ".")
  -root string
        root directory of the project (default ".")

If no --root option is given the root directory is found by crawling up the directory tree starting at the current working directory. The first directory that contains the configuration file .spaghetti-cutter.hjson will be taken as project root.

The output looks like:

2020/09/10 09:37:08 INFO - configuration 'allowOnlyIn': `github.com/hjson/**`: `x/config` ; `golang.org/x/tools**`: `parse*`, `x/pkgs*`
2020/09/10 09:37:08 INFO - configuration 'allowAdditionally': `*_test`: `parse`
2020/09/10 09:37:08 INFO - configuration 'god': `main`
2020/09/10 09:37:08 INFO - configuration 'tool': `x/*`
2020/09/10 09:37:08 INFO - configuration 'db': ...
2020/09/10 09:37:08 INFO - configuration 'size': 1024
2020/09/10 09:37:08 INFO - configuration 'noGod': false
2020/09/10 09:37:08 INFO - root package: github.com/flowdev/spaghetti-cutter
2020/09/10 09:37:08 INFO - Size of package 'x/config': 699
2020/09/10 09:37:08 INFO - Size of package 'x/pkgs': 134
2020/09/10 09:37:08 INFO - Size of package 'deps': 401
2020/09/10 09:37:08 INFO - Size of package 'parse': 109
2020/09/10 09:37:08 INFO - Size of package 'size': 838
2020/09/10 09:37:08 INFO - Size of package 'x/dirs': 86
2020/09/10 09:37:08 INFO - Size of package '/': 202
2020/09/10 09:37:08 INFO - No errors found.

First, the configuration values and the root package are reported. So you can easily ensure that the correct configuration file is taken.

All package sizes are reported and last but not least, any violations are found. Since no error was found, the return code is 0.

A typical error message would be:

2020/09/10 10:31:14 ERROR - domain package 'pkg/shopping' isn't allowed to import package 'pkg/cart'

The return code is first From the output, you can see that

You can fix that by adding a bit of configuration.

Other non-zero return codes are possible for technical problems (unparsable code: 6, …). If appropriately used in the build pipeline, a non-zero return code will stop the build, and the problem has to be fixed first. So undesired imports (spaghetti relationships) are prevented.

Standard Use Case: Golang Web API

According to my own unscientific research, this tool was created with Web APIs in mind as that is what about 95% of all Gophers do.

So it offers special handling for the following cases:

These cases needn’t be used and can be overridden with explicit configuration.

Configuration

It is mandatory to use a HJSON configuration file .spaghetti-cutter.hjson in the root directory of your project. This serves multiple purposes:

The configuration can have the following elements:

The size configuration key prevents a clever developer from just throwing all of the spaghetti code into a single package. With the spaghetti-cutter such things will become obvious and you can put them as technical dept into your back log.

Exit mobile version