Skip to content

Guardrails / Collectors

Gradle build ​

The Gradle build in the project directory: its settings and manifest, every included project, the wrapper and the distribution it pins, the version catalog, and every dependency the build files declare or the lock files resolve, with the versions its platforms supply.

Facts keygradle
Versionv1
Scriptgradle.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": ["gradle"]
}
python
gradle = guardrail.facts("gradle")

Facts ​

These are the fields of the document gradle 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, and when the directory holds no Gradle build (no settings file, no manifest and no version catalog), the collector collects nothing at all.
rootDirectory holding the settings file of the build this project belongs to, from the directory the CLI runs in, or null when directory is that root or nothing above it is. It is only looked for when directory holds no settings file of its own, and never above the directory the CLI runs in, so a module checked on its own reads the settings, version catalog, wrapper and platforms its root supplies rather than reporting none. A module of a repository checked from that repository's root therefore reads . here, and a project that is its own build root reads null. Nothing else from the root is collected: projects and dependencies remain those of directory.
settingsSettings file found (settings.gradle.kts or settings.gradle), from the directory the CLI runs in, taken from root when the project carries none of its own, or null.
manifestRoot manifest found (build.gradle.kts or build.gradle), from the directory the CLI runs in, or null.
sourcesThe build files that were there to read, from the directory the CLI runs in, in the order they are read, followed by the ones read from root.
versionCatalogEvery entry under [versions] in gradle/libs.versions.toml, by name, taken from root when the project carries no catalog of its own. Empty when there is no catalog.
wrapper.scriptWhether gradlew is committed, in projectDir or in root when the project carries no wrapper of its own.
wrapper.propertiesPath of the wrapper properties file, from the directory the CLI runs in, or null when it is not committed.
wrapper.distributionUrlThe distribution the wrapper pins, or null when it declares none.
wrapper.distributionSha256SumChecksum the wrapper properties pin the distribution to, or null when they pin none, in which case the wrapper trusts whatever the distribution URL serves.
wrapper.versionGradle version named by that URL, or null when it names none.
projectsThe root project followed by every project the settings file includes.
projects[].pathGradle path of the project, : for the root.
projects[].directoryDirectory holding it, from the directory the CLI runs in.
projects[].manifestManifest found in that directory, from the directory the CLI runs in, or null.
dependenciesEvery dependency the root project and every included project takes on, split by whether the build declares it. A commented out line is not one, and neither is a project(":x") dependency, a constraints entry or a catalog alias the catalog does not declare.
dependencies.directEvery dependency a build file declares, in the order the files declare them.
dependencies.direct[].pathgroup:name of the dependency.
dependencies.direct[].versionVersion, taken from the lock file when one resolves it and from a declared platform when the declaration states none. null when nothing in the files resolves one, such as an interpolated variable or a catalog alias declaring no version.
dependencies.direct[].scopesEvery configuration it is declared in, followed by every configuration a lock file resolves it for. The two are different vocabularies: implementation is declarable, runtimeClasspath is resolvable, and a dependency declared and locked carries both.
dependencies.direct[].sourceBuild file declaring it, from the directory the CLI runs in.
dependencies.direct[].platformPresent and true only when it is declared as platform(...) or enforcedPlatform(...), meaning it is a BOM supplying versions rather than code.
dependencies.direct[].managedByPresent only when the version came from a platform, and then the group:name:version of that platform. The BOM is not in the repository, so it is never read: a platform is matched to a dependency by group, most specific first, and the version taken is the platform's own. Treat a version carrying a managedBy as a hint rather than a fact. It is wrong wherever the BOM does not publish one version line for the whole group, and it is set even on a coordinate the BOM never lists but whose group happens to sit under the platform's. A platform declared in the root manifest supplies versions to every included project; one declared anywhere else supplies only the project declaring it; and one declared in the manifest of root supplies projectDir and every project it includes.
dependencies.transitiveEvery dependency a lock file resolves that the project's own build file does not declare, meaning another dependency pulled it in. Empty when the build locks nothing; check lockfiles to tell that apart from a build that pulls nothing in.
dependencies.transitive[].pathgroup:name of the dependency.
dependencies.transitive[].versionVersion the lock file resolves.
dependencies.transitive[].scopesEvery configuration the lock file resolves it for.
dependencies.transitive[].sourceLock file resolving it, from the directory the CLI runs in.
lockfilesEvery dependency lock file that was read, from the directory the CLI runs in.

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 gradle collector gathers from an example project:

json
{
  "directory": ".",
  "exists": true,
  "root": null,
  "settings": "settings.gradle.kts",
  "manifest": "build.gradle.kts",
  "sources": [
    "build.gradle.kts",
    "gradle/libs.versions.toml"
  ],
  "versionCatalog": {
    "kotlin": "2.1.0",
    "junit": "5.11.0"
  },
  "wrapper": {
    "script": true,
    "properties": "gradle/wrapper/gradle-wrapper.properties",
    "distributionUrl": "https://services.gradle.org/distributions/gradle-8.14-bin.zip",
    "distributionSha256Sum": null,
    "version": "8.14"
  },
  "projects": [
    {
      "path": ":",
      "directory": ".",
      "manifest": "build.gradle.kts"
    },
    {
      "path": ":service",
      "directory": "service",
      "manifest": "service/build.gradle.kts"
    }
  ],
  "dependencies": {
    "direct": [
      {
        "path": "org.http4k:http4k-bom",
        "version": "6.57.2.0",
        "scopes": [
          "implementation"
        ],
        "source": "build.gradle.kts",
        "platform": true
      },
      {
        "path": "org.http4k:http4k-core",
        "version": "6.57.2.0",
        "scopes": [
          "implementation"
        ],
        "source": "build.gradle.kts",
        "managedBy": "org.http4k:http4k-bom:6.57.2.0"
      },
      {
        "path": "org.slf4j:slf4j-api",
        "version": "2.0.13",
        "scopes": [
          "implementation",
          "compileClasspath",
          "runtimeClasspath"
        ],
        "source": "build.gradle.kts"
      },
      {
        "path": "org.junit.jupiter:junit-jupiter",
        "version": "5.11.0",
        "scopes": [
          "testImplementation"
        ],
        "source": "build.gradle.kts"
      },
      {
        "path": "com.google.guava:guava",
        "version": "33.2.0-jre",
        "scopes": [
          "implementation"
        ],
        "source": "service/build.gradle.kts"
      }
    ],
    "transitive": [
      {
        "path": "ch.qos.logback:logback-classic",
        "version": "1.5.6",
        "scopes": [
          "runtimeClasspath"
        ],
        "source": "gradle.lockfile"
      }
    ]
  },
  "lockfiles": [
    "gradle.lockfile"
  ]
}

Collected for ​

GuardrailCategoryInputs
build/gradle-version-floorbuildprojectDir
build/wrapper-distribution-verifiedbuildprojectDir
kotlin/build-manifestkotlinprojectDir
kotlin/dependencies-lockedkotlinprojectDir
kotlin/gradle-wrapperkotlinprojectDir

All collectors

Buildnote Limited
Registered in England and Wales, Reg: 16140412