Repository navigation
Configuration
Analysis settings can be set on the command line or in .echoes.toml at the workspace root. Command-line settings override the file, which overrides defaults, and --exclude globs add to the file's. --config <PATH> reads another file, and blank entries in the table identify command-line-only options.
| Command line | .echoes.toml |
Default | Effect |
|---|---|---|---|
-p, --package <NAME>
|
all members | Scan one workspace member | |
--organization [<ORG>] |
off | Scan every repository of a GitHub organization or user, by default the current repository's owner | |
--all-targets |
off | Scan binary and example doctests too | |
-t, --threshold <N>
|
threshold |
2 |
Report groups with at least this many sites |
--min-tokens <N> |
min-tokens |
0 |
Skip smaller doctests |
--functions |
functions |
off | Run the function check |
--fn-min-tokens <N> |
fn-min-tokens |
30 |
Skip smaller function bodies |
--context-blocks |
context-blocks |
off | Run the context check |
--context-min-tokens <N> |
context-min-tokens |
30 |
Skip smaller contexts |
--context-select <SCOPE> |
context-select |
the -p package or workspace |
Local contexts whose matches are reported |
--context-search <SCOPE> |
context-search |
the -p package or workspace |
Contexts compared against the local selection |
--context-dependency-depth <N> |
context-dependencies.depth |
0, off |
Maximum shortest dependency-edge distance |
--context-dev-dependencies |
context-dependencies.include-dev |
off | Include development dependency edges |
--context-build-dependencies |
context-dependencies.include-build |
off | Include build dependency edges |
--context-all-optional-dependencies |
context-dependencies.all-optional |
off | Explore optional edges outside the selected features |
--context-features <FEATURES> |
context-dependencies.features |
none | Comma-separated Cargo features for discovery |
--context-all-features |
context-dependencies.all-features |
off | Enable every workspace feature for discovery |
--context-no-default-features |
context-dependencies.no-default-features |
off | Disable default workspace features for discovery |
--context-target <TRIPLE> |
context-dependencies.target |
configured build.target, otherwise host |
Target triple used for discovery |
--context-cache-dir <PATH> |
context-dependencies.cache-dir |
user cache directory | Persistent dependency index directory |
--context-check-latest <BOOL> |
context-dependencies.check-latest |
true |
Also inspect newer published dependency versions |
--context-fail-on-reuse |
context-dependencies.fail-on-findings |
off | Include dependency findings in the gate |
scan-generated |
off | Scan generated files too | |
generated-markers |
none | Extra phrases that mark a file as generated | |
--exclude <GLOB> |
exclude |
none | Leave out the files matching these gitignore-style globs |
--json |
off | Print the report as JSON
|
|
-v, --verbose
|
off | Print the code of each doctest and function group | |
--github |
off | Also print GitHub workflow annotations | |
--no-fail |
off | Exit with 0 even when duplicates are found |
# .echoes.toml
functions = true
fn-min-tokens = 40
context-blocks = true
context-select = "workspace"
generated-markers = ["Autogenerated by build.rs"]
exclude = ["benches/", "examples/"]
[context-dependencies]
depth = 2
include-dev = true
check-latest = falseExit status 0 means complete analysis with no gated findings, or with the duplicate gate suppressed by --no-fail. Status 1 means a doctest, function or context group was reported, or reuse findings were included by --context-fail-on-reuse. Status 2 means a scan error or incomplete dependency or organization coverage and takes precedence over --no-fail.
--context-select picks the local contexts whose matches are reported, and --context-search picks the workspace contexts they are compared against. Each takes one scope string, and both also appear in .echoes.toml as context-select and context-search.
| Scope | Selects |
|---|---|
workspace |
Every context in the workspace |
crate:<name> |
One compilation target, by name or by its workspace-relative root source path |
file:<path> |
One physical source file, workspace-relative |
module:<path> |
One module and its descendant modules |
module-exact:<path> |
One module, without its descendant modules |
An unset scope keeps the -p package, or the whole workspace when the other scope is explicit.
--context-dependency-depth <N> looks for reusable code in the dependencies of the selected local contexts. N caps the shortest dependency edge distance from those contexts, where 1 covers direct dependencies and 2 covers their dependencies. The default 0 disables discovery, and a nonzero depth turns on the context scan on its own.
The search follows normal dependency edges by default, and development or build edges when --context-dev-dependencies or --context-build-dependencies is set. --context-all-optional-dependencies also explores optional edges outside the features selected by --context-features, --context-all-features and --context-no-default-features, and --context-target <TRIPLE> resolves the graph for another target.
Latest-version checks default to true. --context-check-latest false omits newer-version comparisons while retaining source acquisition and provenance lookups.
The dependency index is persistent and lives in the user cache directory, $XDG_CACHE_HOME/echoes or $HOME/.cache/echoes, unless --context-cache-dir <PATH> names another directory.
Findings are source-level matches requiring compatibility review. Text output lists candidates under each local context, and --json places them under reuse. Dependency findings join the gate with --context-fail-on-reuse, or fail-on-findings = true inside [context-dependencies].
The Dependency reuse page documents the candidate output, and Performance covers the index and cache.
Some copies are deliberate, such as a doctest that repeats an example on purpose. Mark the doctest fence as rust,echoes, or put // echoes: allow on the line right above a function or its first attribute, with no blank line between. Allowed copies still count in the totals but never form a group.
```rust,echoes
let v = vec![1, 2, 3];
assert_eq!(v.len(), 3);
```// echoes: allow
fn parse_legacy(input: &str) -> u32 {
input.trim().parse().unwrap_or(0)
}A file counts as generated when one of its first five lines contains @generated or a Go-style // Code generated … DO NOT EDIT. line. Generated files are skipped. Add your generator's own phrase to generated-markers, or set scan-generated = true to scan them anyway.
exclude globs drop files from every check, so an excluded file is never reported and never kept as the original copy. They follow .gitignore rules relative to the workspace root, or to every repository's root in an Organization search. A glob without a slash, such as *.rs, matches at any depth, a slash before its end anchors it to the root, a trailing slash matches a directory's contents, and ** spans directories. An owner/repo: prefix, as in diesel-rs/diesel:diesel_bench/, limits a glob to one scanned repository and never matches a local workspace. Negations with ! are refused.