Reference: Output and exit codes: The text, JSON, GitHub and SARIF formats, the work counts of --stats, and the exit codes.
# Output and exit codes
> The text, JSON, GitHub and SARIF formats, the work counts of --stats, and the exit codes.
Each example on this page comes from one repository. Its JSON config has one table. The file `src/shared/label.ts` imports a file of the feature `cart`, and the table refuses it:
archangel.config.json
```json
{
"$schema": "./node_modules/@enhance-eng/archangel/archangel.schema.json",
"parts": {
"feature": "src/features/{feature}/**",
"shared": "src/shared/**"
},
"rules": [
{
"kind": "mayImport",
"name": "app",
"rows": { "feature": ["shared"], "shared": [] },
"because": "Shared code never depends on a feature."
}
]
}
```
## `text`
The default format, for people. Each problem shows its code, its message, the line of source code with a mark under the import, what to do, the rule and your reason.
Terminal
```ansi
$ npx archangel check
error[may-import]: shared may not import feature, through "../features/cart/total": shared may import only itself
--> src/shared/label.ts:1:23
|
1 | import { total } from '../features/cart/total';
| ^^^^^^^^^^^^^^^^^^^^^^^^ shared may import only itself
|
= help: remove the import, or move the code to a file whose row permits the import
= note: rule: app.shared
= note: because: Shared code never depends on a feature.
checked 2 files and 1 imports: 1 problem
For what a code means, run `archangel docs may-import`.
```
| Line | What it is |
| ------------------------------ | ------------------------------------------------------------------------------- |
| `error[may-import]: ...` | The diagnostic code and the message. `archangel docs ` explains the code. |
| `--> src/shared/label.ts:1:23` | The file, the line and the column. |
| `= help: ...` | What to do. |
| `= note: rule: ...` | The name of the rule, for `off`, an exception or the baseline. |
| `= note: because: ...` | Your reason, from `because`. |
| `= note: see: ...` | Your link, from `link`. |
There are no warnings. Each problem is an error.
## `json`
One JSON document, for programs. `check`, `test`, `rules`, `explain` and `why` write JSON.
Terminal
```ansi
$ npx archangel check --format json
{
"schemaVersion": 1,
"diagnostics": [
{
"code": "may-import",
"severity": "error",
"rule": "app.shared",
"file": "src/shared/label.ts",
"line": 1,
"column": 23,
"span": [
22,
46
],
"specifier": "../features/cart/total",
"message": "shared may not import feature, through \"../features/cart/total\": shared may import only itself",
"help": "shared may import only itself",
"reason": "Shared code never depends on a feature.",
"link": null,
"id": {
"rule": "app.shared",
"file": "src/shared/label.ts",
"specifier": "../features/cart/total",
"occurrence": 0
},
"cycle": [],
"group": [],
"chain": [],
"fix": null
}
],
"summary": {
"files": 2,
"imports": 1,
"warnings": 0,
"exceptions": {},
"baselined": {},
"permittedUnresolved": 0,
"unfollowed": 0,
"unfollowedImports": [],
"linksNotFollowed": [],
"nestedRepositories": [],
"presetNamesMatchingNothing": [],
"work": {
"filesFound": 2,
"filesRead": 2,
"bytesRead": 113,
"filesParsed": 2,
"importsFound": 1,
"resolutions": 1,
"filesClassified": 4,
"patternPasses": 4,
"ruleEvaluations": 1,
"cycleFilesVisited": 0,
"transitiveFilesVisited": 0,
"structureEvaluations": 0,
"folderEvaluations": 0,
"exportEvaluations": 0,
"examplesChecked": 0,
"filesWritten": 0,
"pluginRecordsSent": 0,
"pluginChecks": 0,
"packageModulesParsed": 0
},
"rowsWithNoFile": []
}
}
```
* `schemaVersion` is the version of the document.
* Each diagnostic has `id`, the identity of the problem: the rule, the file, the specifier and the occurrence. It does not hold the line, so it stays the same when the line moves.
* `cycle`, `group` and `chain` hold the files of a cycle or of a chain of imports.
* `fix` holds a fix that archangel checked, when it has one.
* `severity` is `error`, or `warning` for a rule with `severity: 'warn'`. `summary.warnings` counts the warnings.
* `summary.unfollowedImports` lists each import whose specifier is computed, by `file` and `line`. The text output lists them under the count.
* `summary.work` holds the work counts.
* `test --format json` lists each failed example and each unproven rule under `diagnostics` too.
* When the config stops a command, the JSON document goes to standard output, as each other document does.
`explain` with a line writes each rule and its verdict:
Terminal
```ansi
$ npx archangel explain src/shared/label.ts:1 --format json
{
"schemaVersion": 1,
"file": "src/shared/label.ts",
"line": 1,
"imports": [
{
"specifier": "../features/cart/total",
"line": 1,
"target": {
"file": "src/features/cart/total.ts"
},
"from": {
"part": "shared",
"instance": [],
"kinds": []
},
"to": {
"part": "feature",
"instance": [
"cart"
],
"kinds": []
},
"rules": [
{
"rule": "app.feature",
"verdict": "skips",
"reason": "the file is not in feature",
"permittedBy": null
},
{
"rule": "app.shared",
"verdict": "refuses",
"reason": "feature is not in its row (shared may import only itself)",
"permittedBy": null
},
{
"rule": "app.every-file-has-a-kind",
"verdict": "skips",
"reason": "this rule checks files, not imports",
"permittedBy": null
}
]
}
]
}
```
`why` writes the chain:
Terminal
```ansi
$ npx archangel why src/shared/label.ts src/features/cart/total.ts --format json
{
"schemaVersion": 1,
"from": "src/shared/label.ts",
"to": "src/features/cart/total.ts",
"chain": [
{
"file": "src/shared/label.ts",
"line": 1,
"specifier": "../features/cart/total"
}
]
}
```
`watch --format json` writes one line of JSON for each check. Read [Commands](/archangel/reference/commands/#watch).
## `github`
Writes each problem as a GitHub Actions annotation. GitHub shows it on its line in the pull request.
Terminal
```ansi
$ npx archangel check --format github
::error file=src/shared/label.ts,line=1,col=23,endColumn=47,title=archangel app.shared::shared may not import feature, through "../features/cart/total": shared may import only itself%0Ahelp: shared may import only itself%0Areason: Shared code never depends on a feature.
checked 2 files and 1 imports: 1 problem
```
Use it in a workflow:
```yaml
- run: npx archangel check --format github
- run: npx archangel test --format github
```
Read [Use archangel in CI](/archangel/guides/ci/).
## `sarif`
Writes a SARIF 2.1.0 log, for GitHub code scanning or another tool that reads SARIF. The log lists each diagnostic code as a rule, with the text of `archangel docs`. Each result has the identity of its problem, so an alert stays the same when its line moves.
```sh
npx archangel check --format sarif > archangel.sarif
```
## `--stats`
Adds the work that archangel did, and the time of each stage. The work counts are:
| Count | What it counts |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| files found, files read, bytes read, files parsed | the source files |
| imports found, resolutions | the imports, and the imports that archangel resolved |
| files classified, pattern passes | the work to find the parts and groups of each file |
| rule evaluations | the times that archangel applied a rule |
| cycle files visited, transitive files visited | the files that the search for cycles and chains visited |
| structure evaluations, folder evaluations, export evaluations | the work of structure, folder and export rules |
| examples checked, files written | the examples of `test`. `files written` is always 0. |
| plugin records sent, plugin checks | the work of plugins |
| package modules parsed | the package files that archangel read for the names that a namespace or dynamic import brings in |
The JSON output holds the same counts in `summary.work`. The times are only in `--stats`, because a time changes from run to run.
## Exit codes
| Code | Meaning |
| ---- | ----------------------------------------------------------------------------------- |
| `0` | The command succeeded, and found no problem, or only warnings. |
| `1` | Archangel found a problem, or the answer is no. |
| `2` | Archangel could not run: the config, the baseline or the command line has an error. |
A warning does not change the exit code, unless `check --max-warnings ` is given and there are more warnings than the count: then the check exits with 1.
A config error stops the check before archangel reads the code. It exits with 2:
Terminal
```ansi
$ npx archangel check
error[rule-unknown-element]: rules[0].files: the config declares no part or group "shraed"; did you mean "shared"? the declared names are shared; a kind has a meaning only in its table, and a path pattern has a `/` or a `*`
--> archangel.config.json:6:37
```