Skip to content

Guardrails / Collectors

Clojure build ​

The Clojure build in the project directory: which tool it uses, the Clojure version it depends on, the source paths and aliases it declares, the repositories it resolves from, and every dependency with its alias, origin and whether it is pinned.

Facts keyclojure
Versionv1
Scriptclojure.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": ["clojure"]
}
python
clojure = guardrail.facts("clojure")

Facts ​

These are the fields of the document clojure 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: deps.edn when there is one, otherwise project.clj.
sourcesEvery manifest that was read and understood, in the order they were read. One the reader could not handle is in unparsed instead.
scannedEvery manifest that is Clojure rather than data and was read by pattern. project.clj is a defproject form, so what it builds with a function or a reader conditional is not seen; deps.edn is EDN and is read whole, so it never appears here.
toolWhich build tool the checkout uses: clojure-cli for deps.edn, leiningen for project.clj, or both when it carries each.
declaredThe Clojure version the project depends on, or null when it names none and the tool's own default decides.
declared.versionVersion exactly as written, such as 1.11.3.
declared.sourceManifest declaring it, from the directory the CLI runs in.
declared.pinnedWhether it names one exact version. Both tools take a literal version rather than a range, so this is false only for a RELEASE, a LATEST or a SNAPSHOT.
pathsSource paths the manifest declares, such as src and resources.
aliasesNames of the aliases deps.edn declares, such as test and build. An alias carries its own dependencies and its own JVM options.
repositoriesEvery Maven repository the manifest adds beyond the defaults, by name. A repository nobody vetted is what a dependency confusion attack needs.
repositories[].nameName the manifest keys it by, such as clojars.
repositories[].urlURL it resolves from, or null when the entry names none.
projectsThe one project the manifest declares. Neither tool has workspaces.
projects[].pathDirectory of the project, from the directory the CLI runs in, always directory itself.
projects[].manifestIts manifest, from the directory the CLI runs in.
projects[].nameName the defproject form declares, or null when there is none to read it from.
dependenciesWhat the manifests declare, split by whether the project asks for it itself.
dependencies.directEvery dependency the reader saw, the root's first and each alias's after it.
dependencies.direct[].nameCoordinates as the manifest writes them, such as org.clojure/clojure or io.github.company/queue.
dependencies.direct[].versionVersion exactly as written, or null when the dependency comes from a git URL or a local root.
dependencies.direct[].scopesdefault for a dependency at the top level, otherwise the alias or Leiningen profile that adds it, such as test.
dependencies.direct[].sourceManifest declaring it, from the directory the CLI runs in.
dependencies.direct[].pinnedWhether the version names one exact release. A RELEASE, a LATEST or a -SNAPSHOT is not pinned, and neither is a git dependency without a :git/sha.
dependencies.direct[].originWhere it comes from: maven, git for a :git/url coordinate, or local for a :local/root.
dependencies.transitiveAlways empty. Neither tool commits a resolved graph, so there is none to read.
unparsedEvery manifest the reader could not handle, so a guardrail can tell a project 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 clojure collector gathers from an example project:

json
{
  "directory": ".",
  "exists": true,
  "manifest": "deps.edn",
  "sources": [
    "deps.edn"
  ],
  "scanned": [],
  "tool": "clojure-cli",
  "declared": {
    "version": "1.11.3",
    "source": "deps.edn",
    "pinned": true
  },
  "paths": [
    "src",
    "resources"
  ],
  "aliases": [
    "build",
    "test"
  ],
  "repositories": [
    {
      "name": "clojars",
      "url": "https://repo.clojars.org/"
    }
  ],
  "projects": [
    {
      "path": ".",
      "manifest": "deps.edn",
      "name": null
    }
  ],
  "dependencies": {
    "direct": [
      {
        "name": "org.clojure/clojure",
        "version": "1.11.3",
        "scopes": [
          "default"
        ],
        "source": "deps.edn",
        "pinned": true,
        "origin": "maven"
      },
      {
        "name": "ring/ring-core",
        "version": "1.12.1",
        "scopes": [
          "default"
        ],
        "source": "deps.edn",
        "pinned": true,
        "origin": "maven"
      },
      {
        "name": "io.github.company/queue",
        "version": null,
        "scopes": [
          "default"
        ],
        "source": "deps.edn",
        "pinned": true,
        "origin": "git"
      },
      {
        "name": "io.github.clojure/tools.build",
        "version": "0.10.3",
        "scopes": [
          "build"
        ],
        "source": "deps.edn",
        "pinned": true,
        "origin": "maven"
      },
      {
        "name": "lambdaisland/kaocha",
        "version": "1.91.1392",
        "scopes": [
          "test"
        ],
        "source": "deps.edn",
        "pinned": true,
        "origin": "maven"
      }
    ],
    "transitive": []
  },
  "unparsed": []
}

Collected for ​

GuardrailCategoryInputs
clojure/dependencies-pinnedclojureprojectDir
clojure/no-local-dependenciesclojureprojectDir
clojure/repositories-allowedclojureprojectDir
clojure/version-declaredclojureprojectDir

All collectors

Buildnote Limited
Registered in England and Wales, Reg: 16140412