Result files
Overview
A CAST Profiler CLI run writes up to three files, and they are not variations of one another - each holds a different representation of the scan for a different purpose. This page describes what is in each and which one to consume from a pipeline.
All examples use -n my-app, which prefixes every file name.
The files
| File | Purpose |
|---|---|
my-app.json.zs |
The compact scan store. |
my-app-to-upload.json |
The derived evaluation. This is what gets uploaded and what the results page renders. |
my-app-insight-report.html |
A self-contained HTML report. |
my-app-inventory.json |
A flat file inventory, produced only by -fc. |
my-app.json.zs
Despite the extension, this is a Zstandard -compressed JSON document. Any zstd implementation reads it:
$ zstd -d -c my-app.json.zs | jq .version
Compression is effective on this shape of data - a small sample compressed 29 times over - so this is the file to archive if you want to keep a scan around.
The structure is normalized rather than readable. A nodes array holds the file and directory tree, and parallel arrays key off it:
version, fileTypeProfilerVersion, os, name, origin, detailsEnabled
roots, nodes, excludedNodes, projects, alerts
nodeComposition, nodeLanguages, nodeImports, nodeNamespaces,
nodeAnnotations, nodeClasses, nodePrograms, nodeProgramCalls
Use this file as the archive format. Do not parse it for reporting - use the derived evaluation instead.
my-app-to-upload.json
The derived evaluation, produced by running the evaluation engine over the scan. This is what -ci uploads, and what you upload by hand on the website after an offline run.
| Key | Contents |
|---|---|
profilerVersion, d3Version, date |
Provenance of the evaluation |
dataIntegrity |
Dated SHA-256 hashes of each reference knowledge base used |
applicationSize |
Total size figure |
composition |
Per-language totals with density, supportLevel and isBinary |
projects |
Detected projects with type, icon and declared dependencies |
technologies |
Detected technologies with parent, roles, supportLevel, density and the architecture layer under function |
alerts |
Alert counts, boolean flags and affected paths |
conclusion |
nonSupportedLangPercentage and nonSupportedLanguages |
analysis |
architecture - pattern scores, summary and complexity - and indicators |
telemetry |
The extracted identifiers: imports, annotations, dependency coordinates, project names, per language |
This is the file to consume from a pipeline. It carries the support levels, the roles and the alerts already resolved, so you do not have to reimplement any of the evaluation.
telemetry is where the identifiers extracted from your code live - import statements, annotation names, dependency coordinates and project names. If you need to review what an upload would disclose, this is the key to inspect. See what leaves your machine.
my-app-inventory.json
Produced only by -fc, and when -fc is passed nothing else is produced. It is a flat list, cheap to generate and cheap to diff:
{
"files": [
{ "id": 1, "path": "/source/README.md", "root": "/source", "kind": "prose" },
{ "id": 2, "path": "/source/pom.xml", "root": "/source", "kind": "project" }
]
}
kind carries the file’s classification, drawn from the codes listed under file classification - though 2.0.3 emits unclassified and unknown in place of some of them. The file also holds directories, file per language, languages per type and extensions_list, which give the extension-to-language mapping the scan applied.
Use it to answer “which files were actually collected”, which is the question that matters when a count does not match your expectation - remember that files inside automatically excluded folders never appear here at all.
Gating a pipeline on alerts
The alerts object in my-app-to-upload.json gives you counts, booleans and paths, so a pipeline can fail or warn without any parsing of the HTML report:
$ jq '.alerts | {
duplicates: .nbDuplicateFiles,
longPaths: .nbLongPath,
generated: .nbAutoGeneratedFiles,
missingSql: .hasMissingSQL,
noJcl: .noJclFile,
complex: .isComplex
}' profiler-out/my-app-to-upload.json
The unsupported share is in conclusion, which is usually the more useful gate:
$ jq '.conclusion.nonSupportedLangPercentage' profiler-out/my-app-to-upload.json
Each alert and what to do about it is described in the Alerts reference.