Maven build
The Maven build in the project directory: the root pom.xml coordinates, its modules, its properties and every dependency it and its modules declare, with the versions its imported BOMs supply.
| Facts key | maven |
| Version | v1 |
| Script | maven.py |
| Timeout | 30 seconds |
Inputs
| Input | Description | Default | Environment |
|---|---|---|---|
projectDir | Directory 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:
{
"collect": ["maven"]
}maven = guardrail.facts("maven")Facts
The document maven collects. A path carrying [] is an entry of the list before it, and one carrying [path] is a key of the object before it.
| Fact | Meaning |
|---|---|
directory | The projectDir input, as the guardrail configured it. |
exists | Whether that directory is there. Nothing else is collected when it is not, and the collector collects nothing at all when the directory holds no pom.xml. |
pom | pom.xml when there is one, null when there is not. |
sources | The build files that were there to read. |
malformed | Whether the POM could not be parsed. The coordinates, properties and modules keep their defaults when it is true, and the fact is absent when there is no POM at all. |
coordinates.groupId | Group id, inherited from the parent when the POM declares none. |
coordinates.artifactId | Artifact id. |
coordinates.version | Version, inherited from the parent when the POM declares none. |
coordinates.packaging | Packaging, jar when the POM declares none. |
properties | Every entry under <properties>, by name. |
modules | Every module the POM declares. |
modules[].path | Module directory, relative to projectDir. |
modules[].pom | The module's POM path when it is there, null when it is not. |
modules[].coordinates | The module's own coordinates, shaped as above, or null when its POM could not be read. |
dependencies | Every dependency the root POM and every module POM that is checked in takes on, inside a <profile> or out of one, split by whether a POM declares it. A plain <dependencyManagement> entry is a managed version rather than a dependency, so it is not one, and a dependency a module inherits from its parent is listed against the POM declaring it rather than against both. |
dependencies.direct | Every dependency a POM declares, the root POM first, together with every BOM they import. |
dependencies.direct[].path | group:name of the dependency. |
dependencies.direct[].version | Version, filled in from <dependencyManagement> when the dependency declares none, taken from an imported BOM when nothing manages it, and resolved through the properties in scope. null when nothing resolves one. |
dependencies.direct[].scopes | The scope declared, compile when the POM declares none and import for a BOM. One entry, because a POM declares a dependency once. |
dependencies.direct[].source | POM declaring it, relative to projectDir. |
dependencies.direct[].profile | Present only when a <profile> declares it, and then that profile's id. Whether the profile activates is not something the POM alone says. |
dependencies.direct[].platform | Present and true only when it is a <dependencyManagement> entry imported with <scope>import</scope>, meaning it is a BOM supplying versions rather than code. |
dependencies.direct[].managedBy | Present only when the version came from an imported BOM, and then that BOM's group:name:version. A version <dependencyManagement> supplies in the same build carries no managedBy, because the POM states it. The BOM is not in the repository, so it is never read: it is matched to a dependency by group, most specific first, and the version taken is the BOM'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 it. A BOM the root POM imports supplies versions to every module, one a module imports only to that module. |
dependencies.transitive | Always empty. A Maven build checks in no resolved dependency graph, so nothing but the declared dependencies is visible without running Maven. |
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 maven collector:
{
"directory": ".",
"exists": true,
"pom": "pom.xml",
"sources": [
"pom.xml"
],
"modules": [
{
"path": "service",
"pom": "service/pom.xml",
"coordinates": {
"groupId": "com.acme",
"artifactId": "widget-service",
"version": "1.1.0",
"packaging": "jar"
}
}
],
"properties": {
"kotlin.version": "2.1.0",
"maven.compiler.release": "21"
},
"coordinates": {
"groupId": "com.acme",
"artifactId": "widget",
"version": "1.1.0",
"packaging": "pom"
},
"dependencies": {
"direct": [
{
"path": "org.junit:junit-bom",
"version": "6.0.3",
"scopes": [
"import"
],
"source": "pom.xml",
"platform": true
},
{
"path": "com.google.guava:guava",
"version": "33.2.0-jre",
"scopes": [
"compile"
],
"source": "service/pom.xml"
},
{
"path": "org.jetbrains.kotlin:kotlin-stdlib",
"version": "2.1.0",
"scopes": [
"compile"
],
"source": "service/pom.xml"
},
{
"path": "org.junit.jupiter:junit-jupiter",
"version": "6.0.3",
"scopes": [
"test"
],
"source": "service/pom.xml",
"managedBy": "org.junit:junit-bom:6.0.3"
}
],
"transitive": []
},
"malformed": false
}Collected for
| Guardrail | Category | Inputs |
|---|---|---|
kotlin/build-manifest | kotlin | projectDir |
maven/coordinates-declared | maven | projectDir |
maven/dependencies-versioned | maven | projectDir |
maven/no-snapshot-dependencies | maven | projectDir |
maven/pom-parses | maven | projectDir |