Skip to content

Configuration

LucaCappelletti94 edited this page Oct 23, 2026 · 2 revisions

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.

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 = false

Exit 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 scopes

--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.

Searching dependencies

--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.

Keeping a copy on purpose

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)
}

Generated files

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.

Excluded paths

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.

Clone this wiki locally