Skip to content

Guardrails / Collectors

Go build ​

The Go build in the project directory: the module it declares, the Go version it asks for, every module of a workspace, the modules it requires directly and indirectly, and the replacements and lock file beside them.

Facts keygolang
Versionv1
Scriptgolang.py
Timeout30 seconds

Inputs ​

InputDescriptionDefaultEnvironment
projectDirDirectory holding the project, relative to the directory the CLI runs in..GUARDRAIL_INPUT_PROJECTDIR

When a guardrail declares an input with the same name, it passes its value through. That means you set these values in the guardrail's configuration in buildnote.json.

A guardrail asks for these facts by name and reads them back by the same name:

json
{
  "collect": ["golang"]
}
python
golang = guardrail.facts("golang")

Facts ​

These are the fields of the document golang collects. In a path, [] means each entry of the list before it, and [path] means a key of the object before it.

FactMeaning
directoryThe project directory set by the guardrail's projectDir input, relative to the directory the CLI runs in. Every other path this collector reports is also relative to the directory the CLI runs in, so it resolves from where you invoked the CLI, not from wherever the collector happened to run.
existsWhether that directory exists. When it doesn't, nothing else is collected.
manifestPath of the primary manifest, from the directory the CLI runs in: go.work when the checkout is a workspace, go.mod otherwise.
sourcesEvery manifest that was read and understood, in the order they were read. A manifest the reader could not handle is in unparsed instead.
declaredThe Go version the build declares, or null when it declares none.
declared.versionVersion as the go directive writes it, such as 1.22.
declared.sourceManifest declaring it, from the directory the CLI runs in.
declared.pinnedWhether the constraint names one exact version rather than a floor or a range. Always false for Go, because the go directive is the lowest version the module builds with rather than the one the toolchain uses.
toolchainVersion the toolchain directive selects, such as go1.22.3, or null when the module names none and the go directive decides.
projectsEvery module in the build: the workspace's use entries, or the one module the checkout is.
projects[].pathDirectory of the module, from the directory the CLI runs in; directory itself for the project directory.
projects[].manifestThat module's go.mod, from the directory the CLI runs in, or null when the workspace names a directory carrying none.
projects[].nameModule path the module directive declares, such as github.com/company/widget, or null when it declares none.
dependenciesWhat the manifests require, split by whether the module asks for it itself.
dependencies.directEvery module required without an // indirect marker, which is what this build imports itself.
dependencies.direct[].nameModule path required, such as github.com/spf13/cobra.
dependencies.direct[].versionVersion required, as written.
dependencies.direct[].scopesAlways ["default"]. Go modules carry no scope, so a dependency used only by tests is indistinguishable from one the binary links.
dependencies.direct[].sourceManifest that requires it, from the directory the CLI runs in.
dependencies.transitiveEvery module required with an // indirect marker, which exists to pin what a dependency of a dependency resolves to. Shaped as direct.
replacedEvery module a replace directive redirects, meaning a dependency whose source is not the one its path names.
replaced[].nameModule path being replaced.
replaced[].withWhat it is replaced by, as written, a module path or a directory.
replaced[].sourceManifest declaring the replacement, from the directory the CLI runs in.
lockfilesEvery lock file committed beside a manifest, from the directory the CLI runs in. go.sum records the checksum of every module in the graph.
unparsedEvery manifest the reader could not handle, so a guardrail can tell a build that declares nothing apart from one that could not be read.
unparsed[].pathPath of that manifest, from the directory the CLI runs in.
unparsed[].reasonWhy the reader could not handle it.

If a collector can't finish, it prints what it gathered so far along with an incomplete key that says why. Facts after the point where it stopped are missing, so a check that depends on them should read incomplete first.

Example facts ​

Here are the facts the golang collector gathers from an example project:

json
{
  "directory": ".",
  "exists": true,
  "manifest": "go.mod",
  "sources": [
    "go.mod"
  ],
  "declared": {
    "version": "1.22",
    "source": "go.mod",
    "pinned": false
  },
  "toolchain": "go1.22.3",
  "projects": [
    {
      "path": ".",
      "manifest": "go.mod",
      "name": "github.com/company/widget"
    }
  ],
  "dependencies": {
    "direct": [
      {
        "name": "github.com/spf13/cobra",
        "version": "v1.8.1",
        "scopes": [
          "default"
        ],
        "source": "go.mod"
      },
      {
        "name": "golang.org/x/sync",
        "version": "v0.7.0",
        "scopes": [
          "default"
        ],
        "source": "go.mod"
      }
    ],
    "transitive": [
      {
        "name": "github.com/inconshreveable/mousetrap",
        "version": "v1.1.0",
        "scopes": [
          "default"
        ],
        "source": "go.mod"
      },
      {
        "name": "github.com/spf13/pflag",
        "version": "v1.0.5",
        "scopes": [
          "default"
        ],
        "source": "go.mod"
      }
    ]
  },
  "replaced": [
    {
      "name": "github.com/company/queue",
      "with": "./internal/queue",
      "source": "go.mod"
    }
  ],
  "lockfiles": [
    "go.sum"
  ],
  "unparsed": []
}

Collected for ​

GuardrailCategoryInputs
golang/checksums-committedgolangprojectDir
golang/no-local-replacementsgolangprojectDir
golang/toolchain-pinnedgolangprojectDir
golang/version-declaredgolangprojectDir

All collectors

Buildnote Limited
Registered in England and Wales, Reg: 16140412