Skip to content
BETAGuardrails are in beta. The library, the configuration format and the CLI command can still change.

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

A guardrail that declares an input of the same name passes it through, so the guardrail's configuration in buildnote.json is what decides these values.

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

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

Facts

The document clojure collects. A path carrying [] is an entry of the list before it, and one carrying [path] is a key of the object before it.

FactMeaning
directoryThe projectDir input, as the guardrail configured it.
existsWhether that directory is there. Nothing else is collected when it is not.
manifestPath of the primary manifest, relative to projectDir: 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, relative to projectDir.
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, relative to projectDir, always ..
projects[].manifestIts manifest, relative to projectDir.
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.acme/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, relative to projectDir.
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 from one nobody could read.
unparsed[].pathPath of that manifest, relative to projectDir.
unparsed[].reasonWhat stopped the reader.

A collector that cannot finish prints what it had along with an incomplete key saying why, so the facts below the point it stopped are absent. A check that cares reads incomplete before the rest.

Example facts

The example facts collected by clojure collector:

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.acme/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