Skip to content

Ignoring files

.cofferdamignore is an optional file at the repository root that tells cofferdam which paths to exclude from analysis. It uses the same syntax as .gitignore, so teams that already know gitignore patterns can write it immediately.

The file exists as a separate mechanism from .gitignore because the two questions are different. .gitignore answers "should git track this file?" .cofferdamignore answers "should cofferdam lint this file?" The overlap is common — most generated or vendored files appear in both — but not universal. A generated file may be committed intentionally (reproducible builds, API clients, migration schemas) while still being worth excluding from lint analysis since no human will be acting on those findings.


Syntax

.cofferdamignore follows the full gitignore pattern specification as implemented by the ignore crate (the same walker used by ripgrep). Everything that works in a .gitignore works here.

Literal patterns

A line with no special characters matches that literal path segment anywhere in the tree:

gitignore
# Matches any file or directory named exactly "vendor" at any depth
vendor

Glob patterns

* matches any sequence of characters except /. ** matches across directory separators.

gitignore
# Any .ts file at the top level of the repo
*.ts

# Any .ts file anywhere in the tree
**/*.ts

# Any file inside a nested __generated__ directory, at any depth
**/__generated__/**

Directory-only patterns

A trailing / restricts the pattern to directories. This avoids accidentally matching a file named the same as a directory.

gitignore
# Matches the directory dist/ (and everything inside it) but NOT a file named "dist"
dist/

# Matches any directory named __generated__ at any depth
**/__generated__/

Root-anchored patterns

A leading / anchors the pattern to the root of the ignore file — the directory containing .cofferdamignore. Without a leading /, the pattern matches at any depth.

gitignore
# Only the top-level build/ directory — does NOT match src/build/
/build/

# Any directory named build at any depth
build/

Comments

Lines starting with # are comments and are ignored.

gitignore
# Generated API client — do not lint, maintained by openapi-generator
src/api/__generated__/

Negation

A leading ! un-ignores a path that a previous pattern would have excluded. This is the primary tool for "ignore this whole directory except one file."

The order of patterns matters: a negation must appear after the pattern it overrides. Negating a path inside an already-excluded directory requires un-ignoring the parent directory first (this is a gitignore constraint, not specific to cofferdam).

gitignore
# Ignore all of vendor/
vendor/

# But keep one file that the team does review
!vendor/keep.ts

See Worked examples — cherry-pick from fixtures below for a fuller worked case.


Precedence

.cofferdamignore and .gitignore

Both files are read and their exclusion sets are unioned. A path is excluded from analysis if it matches a pattern in either file. There is no override — .cofferdamignore cannot un-ignore something that .gitignore excluded, and vice versa. If you need to un-ignore a path that .gitignore already excludes, pass --no-ignore (see below).

In practice, the two files are almost always additive: .gitignore excludes node_modules/ and build outputs, while .cofferdamignore may exclude generated TypeScript that is committed but not worth linting.

--no-ignore flag

cofferdam check --no-ignore disables both .gitignore and .cofferdamignore for that run. Every .ts, .tsx, .mts and .cts file under the scanned paths is analysed, whatever the ignore patterns say.

Every subcommand that walks the tree takes the flag — check, context, advise, baseline write, fix, doctor and the rest. It earns its keep in one-off audits, where the point is to see the whole picture including vendored and generated code.

sh
cofferdam check --no-ignore src/    # analyse everything, including ignored paths

The sibling flag --hidden walks dotfiles and dot-directories, which discovery skips by default. The two are independent: --hidden widens what the walker visits, --no-ignore stops it filtering what it found.

There is no exclude key in cofferdam.toml

Exclusion is a discovery-time decision, so it lives in .cofferdamignore and .gitignore alone. cofferdam.toml tunes checks on files that were already discovered: an [[overrides]] block can set disabled = true for a named check over a path glob, but it cannot take a file out of analysis altogether. If you want a file gone, ignore it.


Worked examples

Vendored dependencies

gitignore
# Third-party code vendored directly into the repo.
# These files are not the team's responsibility to fix.
vendor/
node_modules/

Generated code

gitignore
# Code generated by protobuf, openapi-generator, graphql-codegen, etc.
# Findings here are noise — the source of truth is the schema, not the output.
*.gen.ts
**/__generated__/
**/generated/

Cherry-pick from fixtures

Sometimes a directory is mostly third-party but contains one file the team owns and wants to lint:

gitignore
# Ignore the whole fixtures directory …
tests/fixtures/

# … except one file that exercises a real code path the team maintains
!tests/fixtures/important.ts

Note the gitignore constraint: negation cannot reach inside a directory that was excluded with a trailing /. The pattern above works because tests/fixtures/ excludes the directory, and !tests/fixtures/important.ts re-includes the specific file. If tests/fixtures/ were excluded via tests/ (the parent), you would need to un-ignore tests/fixtures/ first before un-ignoring the individual file.

Build artifacts

gitignore
# Build and coverage outputs — committed only in release branches, not worth linting.
dist/
build/
coverage/
.turbo/

Placement and discovery

.cofferdamignore is loaded by the discovery walker when it encounters a directory that contains one. Like .gitignore, the file takes effect in the directory where it lives and all subdirectories. The conventional placement is the repository root so the rules apply to the entire project.

Placing a .cofferdamignore in a subdirectory is valid and scopes rules to that subtree. This follows the same layering behaviour as .gitignore files in nested directories.


.cofferdamignore semantics are stable from v0.2.0 onward; future changes will be additive only.

MIT License