Configuration¶
Every setting is optional. The table below lists each setting and its default value. The YAML block shows all available keys; some values are examples.
defaults:
unexported: private # shared | private
rules:
naming:
qualify: never # always | never | ondemand
exported: false # true | false
vocabulary:
mouse: [wheel]
boundary: on # off | on
surplus: strict # off | loose | strict
unused: strict # off | loose | strict
filter:
only: [] # nothing outside these, when set
omit:
- "**/mock_*.go" # and not these
baseline: .declscope-baseline.yaml
| Key | Values | Default | Effect |
|---|---|---|---|
defaults.unexported |
shared, private |
private |
Scope of a declaration that carries no directive and inherits none |
rules.naming.qualify |
always, never, ondemand |
never |
When a name must carry its namespace. See the naming rule |
rules.naming.exported |
true, false |
false |
Whether the naming rule also reaches exported declarations. The rename is never offered there |
rules.naming.vocabulary |
Namespace to a list of words | None | Extra words that carry a namespace. See what carries a namespace |
rules.boundary |
off, on |
on |
Whether the boundary rule reports. See reach without a boundary |
rules.surplus |
off, loose, strict |
strict |
How much the surplus rule reports. See strict |
rules.unused |
off, loose, strict |
strict |
How much the unused rule reports. See off, loose and strict |
filter.only |
Path globs | None | When set, no file outside them is read. Empty places no restriction |
filter.omit |
Path globs | None | Files taken back out, whether or not only let them through |
baseline |
A path relative to the config file | The nearest .declscope-baseline.yaml |
The baseline to consult |
Tip
For the recommended checks, put this in .declscope.yaml:
ondemand checks names once a package has a second namespace. exported: true includes exported declarations. surplus and unused default to strict.
- The file is
.declscope.yamlor.declscope.yml. An empty one changes nothing. -confignames one file, and reads no other.- An unknown key is an error, and so is a value a key does not accept. The message names what the section does take, so a typo never leaves a rule at its default in silence.
defaults takes only unexported, because an exported declaration has no scope to default.
How two config files compose¶
Every .declscope.yaml between the analyzed package and the module root is read, outermost first. A nearer file does not replace the one above it. Each key composes on its own.
| Key | Down the chain |
|---|---|
defaults.*, rules.* except vocabulary, baseline |
The nearest file that states the key wins. A key no file states takes the built-in default |
rules.naming.vocabulary |
Merged per namespace. The nearer file wins the namespaces it states |
filter.only |
Intersected. A file is read when it matches every stating file's list |
filter.omit |
Unioned. A file matching any level's list is not read |
Important
A config file can only ever shrink what is read. An omit written at the root holds everywhere below it, and no nested file can undo it. filter has no negation, so nothing like .gitignore's ! can put a path back.
The filter rule¶
filter decides which files are read at all. A file matches a list when it matches any pattern in it.
| Written | Read |
|---|---|
| Neither | Every file |
only alone |
Nothing outside the patterns |
omit alone |
Everything except the patterns |
| Both | What only admits, minus what omit names |
An empty only places no restriction, which is why a repository with no config is read whole.
A pattern is read against the directory of the config file that states it. Anchoring follows the rules of .gitignore.
| Pattern | Matches |
|---|---|
gen.go |
A file of that name at any depth |
/gen.go, ./gen.go |
The one beside this config file |
gen/** |
That directory beside this config file, and no other |
**/gen/** |
That directory at any depth |
gen/ |
That directory at any depth, the same as **/gen/** |
/gen/, ./gen/ |
That directory beside this config file, the same as gen/** |
*, ? |
Within one path segment |
A leading ./ anchors the same way as a leading /. A trailing / names a directory and everything in it. Without one, a pattern names a file, so ./vendor matches only a file called vendor. Write ./vendor/ or ./vendor/** for the directory.
One report comes from the configuration rather than from the code. It fires when a file's only matches files, but an only above it removes them all, so the package is read as empty.
sub/a.go:1:1: filter.only stated in /repo/sub matches 1 file(s) here, but an only above it removes them all, so this package is read as empty
The report is that narrow on purpose. A package that reads nothing is usually the point, as with a root only naming one subtree, or an omit naming a directory.
The cause is in the config files, so fix it there: change the nested only, or the only above it, so that the files are read. No directive silences this report, since nothing in the package is read. filter is still a valid rule name for //declscope:ignore, but such an ignore silences nothing, so the unused rule reports it.