Command Line Interface
This document describes the command-line interface of Deply.
Available Commands
Analyze Command
The main command for analyzing your project:
deply analyze
Analysis validates the configuration first and exits with status 1 without scanning project files when validation fails. It also exits with status 1 when files cannot be read or parsed, no Python files are found, or no code elements map to configured layers. Completed reports include analysis completeness metrics. Incomplete analysis writes the available metrics to standard error. JSON also generates a report on invalid configuration or incomplete analysis; other formats do not generate a report in these cases.
Validate Command
Validate your configuration without analyzing project files:
deply validate
Help Command
Display help information:
deply --help
Command Line Arguments
Analyze Command Options
--config: Path to the configuration YAML file (default:deply.yaml)--report-format: Format of the output report (choices:text,json,github-actions,sarif, default:text)--output: Output file for the report (if not specified, prints to console)--mermaid: Generates a Mermaid diagram of layer dependencies--max-violations: Maximum number of allowed violations before failing (default: 0)--parallel: Enable parallel processing of code elements
Validate Command Options
--config: Path to the configuration YAML file (default:deply.yaml)
Examples
Basic Analysis
deply analyze
Custom Configuration File
deply analyze --config=custom_config.yaml
Validate Configuration
deply validate --config=custom_config.yaml
Generate GitHub Actions Report
deply analyze --report-format=github-actions
Generate Mermaid Diagram
deply analyze --mermaid
Allow Some Violations
deply analyze --max-violations=5
Enable Parallel Processing
deply analyze --parallel
Output Formats
Text Format
The default output format shows violations and a separate completeness section:
/path/to/your_project/your_project/app1/views_api.py:74:4 - Layer 'views' is not allowed to depend on layer 'models'. Dependency type: function_call.
Analysis completeness
files_discovered: 12
files_excluded: 2
files_included: 10
JSON Format
JSON schema v1 preserves the existing total_violations, by_type, violations, and optional metrics fields and adds machine-readable context:
deply analyze --report-format=json --output=deply-report.json
{
"schema_version": 1,
"status": "complete",
"errors": [],
"total_violations": 1,
"by_type": {
"disallowed_dependency": 1
},
"violations": [
{
"file": "/path/to/your_project/your_project/app1/views_api.py",
"element_name": "list_users",
"element_type": "function",
"line": 74,
"column": 4,
"message": "Layer 'views' is not allowed to depend on layer 'models'. Dependency type: function_call.",
"violation_type": "disallowed_dependency",
"rule_id": "views:disallow_layer_dependencies:bf4644a7ec41e8bcaf3dbdc1d0e47b5ee5bb0183c5c44fa4edcdc02ed31cd252",
"source": {
"file": "your_project/app1/views_api.py",
"name": "list_users",
"type": "function"
},
"target": {
"file": "your_project/app2/models.py",
"name": "User",
"type": "class"
},
"source_layer": "views",
"target_layer": "models",
"dependency_type": "function_call",
"fingerprint": "122cf66fef3a27215b032b6181347ddb9643c8b43c41d29f9a161531b396e117"
}
],
"metrics": {
"files_discovered": 12,
"files_excluded": 2,
"files_included": 10,
"files_parsed": 10,
"files_parse_failed": 0,
"files_mapped": 8,
"files_unmapped": 2,
"elements_mapped": 31,
"elements_overlapping": 3,
"dependencies_detected": 47
}
}
Analysis status and errors
schema_version: integer1. Consumers should check it and tolerate unknown additive fields.status:complete,incomplete, orinvalid_configuration.completemeans the supported analysis passes finished; it does not mean no violations or complete understanding of dynamic Python behavior.errors: an array of{ "code": string, "message": string }. Codes areincomplete_analysisorinvalid_configuration; messages are diagnostics, not identifiers to parse. A complete report has an empty array.metrics: existing counters, including partial counters for incomplete analysis. Invalid configuration has no metrics because scanning never started.
All three statuses produce JSON on stdout or overwrite --output. Errors still print to stderr. Invalid configuration and incomplete analysis exit 1, even with a permissive --max-violations. Complete analysis retains the existing threshold exit behavior. Partial violations in an incomplete report are not an exhaustive result. With JSON and --mermaid, the diagram goes to stderr, keeping stdout parseable. deply validate retains its text-only behavior.
Deduplication now preserves different source/target relationships and configured rules even when their location and message match. This applies to every report format: counts may increase for previously collapsed violations. Re-evaluate existing --max-violations thresholds against the corrected totals.
Violation identity
- Legacy
file,element_name,element_type,line,column,message, andviolation_typefields retain their meanings. Columns are zero-based UTF-8 byte offsets from Python AST, not character offsets. sourceand internaltargetcontainfile,name, andtype. Names preserve collected qualified names, including enclosing scopes where available. Paths use forward slashes and are relative to the configuration directory; files outside it use../segments. On Windows, files on a different drive use absolutefile:URIs, whose fingerprints depend on that drive/path. Run with a configuration in the same relative location across checkouts to retain identity.source_layerandtarget_layeridentify the particular checked membership pair. Overlapping memberships remain separate violations.dependency_typeidentifies an internal dependency, such asfunction_call. Element checks have a nulltarget,target_layer, anddependency_type.- External import checks identify the source as the file’s
<module>with typemodule; the target is{ "module": "requests.sessions", "type": "external_module" }. Theirtarget_layeranddependency_typeare null. The legacy element fields still identify the collected representative element. rule_idislayer:configuration_key:sha256, where the digest covers compact, sorted-key, ASCII-escaped JSON of the effective configured rule (type, supported parameters, and defaults). Ignored metadata does not affect identity. Dependency target lists and external import roots are normalized as sorted sets; other rule configurations retain list order. Identical configured constraints share an ID. Changed constraints change the ID. Bool rules identify the full configured expression, including when a subrule produces the diagnostic.fingerprintis the SHA-256 of compact, sorted-key, ASCII-escaped JSON containingrule_id,source,target,source_layer,target_layer, anddependency_type. JSON usesseparators=(",", ":")and UTF-8 encoding for both digests. It excludes locations and messages; same-drive paths exclude the absolute checkout root. Different call sites for the same relationship share a fingerprint but keep separate locations. Renaming or moving a symbol/file, changing a rule, or changing a membership pair changes the fingerprint. It is not an occurrence ID or proof of semantic equivalence.
Direct JsonReport/ReportGenerator callers default the identity root to the working directory; pass root=Path(...) for a different root. Manually constructed violations without configured context use violation_type as their rule_id and null layers; use the analysis CLI for full configured identities.
Fingerprints prepare exact baseline support; this release does not add baseline suppression. Existing wildcard-import, dynamic-type, and control-flow limitations remain. A complete report is not a complete call graph.
File metrics count unique Python paths. files_parsed means the collection pass parsed the file successfully. files_mapped and files_unmapped partition parsed files. dependencies_detected counts raw dependency events before layer-pair expansion, suppression, and violation checks. GitHub Actions reports expose the same metrics as comment lines without changing annotations.
SARIF Report
deply analyze --report-format=sarif --output=deply.sarif
SARIF 2.1.0 output contains rule IDs, messages, file locations, and metrics in runs[0].properties.metrics. Results use warning severity and line-level locations. Columns are omitted because Python AST offsets count UTF-8 bytes. Files inside the analysis working directory use relative URIs with an explicit source root; files outside it use absolute file URIs. Run from the repository root for GitHub uploads. Existing dependency-inference limitations still apply.
An empty successful report has no results. Violations above --max-violations still produce a report and exit with status 1. Invalid configuration or incomplete analysis exits 1 without writing a new report; an existing output file is not deleted. With --mermaid, use --output to keep diagram text out of the SARIF document.
For an existing GitHub Actions job that checks out the sources and installs Deply, add these steps. The job needs security-events: write permission; private repositories also need actions: read and contents: read.
- name: Analyze architecture
run: |
rm -f deply.sarif
deply analyze --report-format=sarif --output=deply.sarif
- name: Upload architecture findings
if: ${{ !cancelled() && hashFiles('deply.sarif') != '' }}
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: deply.sarif
category: deply
The upload runs even when findings fail the analysis step; the job retains that failure. Removing the previous file prevents stale uploads after an incomplete analysis. See GitHub’s upload documentation for repository availability and permissions. Deply does not emit baseline fingerprints; the upload action can derive fingerprints from checked-out source.
For more information about:
- Mermaid diagrams, see the Mermaid Diagrams documentation
- Rules and violations, see the Rules documentation
- Configuration and usage, see the Configuration Guide and Getting Started guide