Allow and block list linter for direct Go module dependencies. This is useful for organizations where they want to standardize on the modules used and be able to recommend alternative modules.
Allowed and blocked modules are defined in a ./.gomodguard.yaml or ~/.gomodguard.yaml file.
Modules can be allowed by module or prefix name. When allowed modules are specified any modules not in the allowed configuration are blocked.
If no allowed modules or module prefixes are specified then all modules are allowed except for blocked ones.
The linter looks for blocked modules in go.mod and searches for imported packages where the imported packages module is blocked. Indirect modules are not considered.
Alternative modules can be optionally recommended in the blocked modules list.
If the linted module imports a blocked module but the linted module is in the recommended modules list the blocked module is ignored. Usually, this means the linted module wraps that blocked module for use by other modules, therefore the import of the blocked module should not be blocked.
Version constraints can be specified for modules as well which lets you block new or old versions of modules or specific versions.
Results are printed to stdout.
Logging statements are printed to stderr.
Results can be exported to different report formats. Which can be imported into CI tools. See the help section for more information.
# allowed defines the modules that are permitted as direct dependencies.
# When this section is non-empty, any module not matched by an entry is blocked.
# When omitted entirely, all modules are allowed except those in the blocked list.
allowed:
# Exact match (default when match-type is omitted).
- module: go.yaml.in/yaml/v4
- module: github.com/go-xmlfmt/xmlfmt
# version constrains which versions of the module are allowed.
# Uses semver constraint syntax (e.g. ">= 1.0.0", "~1.2", "== 2.5.0").
- module: github.com/confluentinc/confluent-kafka-go/v2
version: "== 2.5.0"
# match-type controls how the module is matched against module paths.
# Options: exact (default), prefix, regex
- module: github.com/kubernetes
match-type: prefix
- module: github.com/apache/arrow-go
match-type: prefix
- module: "github.com/somecompany/.*"
match-type: regex
# blocked defines modules that are not permitted as direct dependencies.
blocked:
- module: github.com/uudashr/go-module
# match-type controls how the module is matched against module paths.
# Options: exact (default), prefix, regex
match-type: exact
# recommendations lists alternative modules to suggest in the lint error.
recommendations:
- golang.org/x/mod
# reason is a human-readable explanation appended to the lint error.
reason: "`mod` is the official go.mod parser library."
- module: github.com/mitchellh/go-homedir
# version constrains which versions of the module are blocked.
# Uses semver constraint syntax. When omitted, all versions are blocked.
version: "<= 1.1.0"
reason: "old versions have a known bug."
- module: "github.com/badcompany/.*"
match-type: regex
reason: "No badcompany packages are permitted."
# Blocks 'replace' directives using local filesystem paths to prevent
# accidental commits of dev overrides. Sibling modules in multi-module
# repos are automatically detected and permitted.
local_replace_directives: true| Field | Type | Default | Description |
|---|---|---|---|
allowed |
list | (none) | Modules that are permitted. When non-empty, anything not matched is blocked. |
blocked |
list | (none) | Modules that are explicitly blocked. |
local_replace_directives |
bool | false |
Block any module whose replace directive points to a local filesystem path. Multi-module repo aware: sibling modules whose replacement path contains a matching go.mod are not blocked. |
| Field | Type | Description |
|---|---|---|
module |
string | The module path to match against. |
match-type |
exact | prefix | regex |
How module is matched against dependency paths. Defaults to exact. |
version |
semver constraint string | Restricts the rule to specific versions (e.g. <= 1.2.0, >= 2.0.0). When omitted, all versions match. |
recommendations |
list of module paths | (blocked only) Alternative modules to suggest in the lint error. If the module being linted is itself in this list, the block is skipped. |
reason |
string | (blocked only) Human-readable explanation appended to the lint error. |
When multiple rules can match the same module the following precedence applies:
- Exact match — highest priority; wins over prefix and regex.
- Prefix match — next priority; longest matching prefix wins.
- Regex match — lowest priority; evaluated in alphabetical key order; first match wins.
The following example configuration files are available:
- examples/alloptions/.gomodguard.yaml
- examples/allowedversion/.gomodguard.yaml
- examples/emptyallowlist/.gomodguard.yaml
- examples/indirectdep/.gomodguard.yaml
- examples/majorversion/.gomodguard.yaml
- examples/regexversion/.gomodguard.yaml
- examples/regextest/.gomodguard.yaml
If you have a v1 .gomodguard.yaml file, you can automatically migrate it to the new v2 schema by running:
gomodguard migrate > .gomodguard-v2.yaml
mv .gomodguard-v2.yaml .gomodguard.yaml
╰─ gomodguard -help
Usage: gomodguard <file> [files...]
Also supports package syntax but will use it in relative path, i.e. ./pkg/...
Commands:
(default) Lint Go module dependencies using the configuration file
migrate Convert a v1 .gomodguard.yaml config file to v2 format and print to stdout
Flags:
-f string
Report results to the specified file. A report type must also be specified
-file string
-h Show this help text
-help
-i int
Exit code when issues were found (default 2)
-issues-exit-code int
(default 2)
-n Don't lint test files
-no-test
-r string
Report results to one of the following formats: checkstyle. A report file destination must also be specified
-report string
-version
Print the version
╰─ cd examples/alloptions
╰─ gomodguard -r checkstyle -f gomodguard-checkstyle.xml ./...
info: allowed modules, [github.com/Masterminds/semver/v3 github.com/go-xmlfmt/xmlfmt golang.org gopkg.in/yaml.v3]
info: blocked modules, [github.com/gofrs/uuid github.com/mitchellh/go-homedir github.com/uudashr/go-module]
blocked_example.go:6:1 import of package `github.com/gofrs/uuid` is blocked because the module is in the blocked modules list. `github.com/ryancurrah/gomodguard` is a recommended module. testing if module is not blocked when it is recommended.
blocked_example.go:7:1 import of package `github.com/mitchellh/go-homedir` is blocked because the module is in the blocked modules list. version `v1.1.0` is blocked because it does not meet the version constraint `<=1.1.0`. testing if blocked version constraint works.
blocked_example.go:8:1 import of package `github.com/uudashr/go-module` is blocked because the module is in the blocked modules list. `golang.org/x/mod` is a recommended module. `mod` is the official go.mod parser library.
Resulting checkstyle file
╰─ cat gomodguard-checkstyle.xml
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="1.0.0">
<file name="blocked_example.go">
<error line="6" column="1" severity="error" message="import of package `github.com/gofrs/uuid` is blocked because the module is in the blocked modules list. `github.com/ryancurrah/gomodguard` is a recommended module. testing if module is not blocked when it is recommended." source="gomodguard"></error>
<error line="7" column="1" severity="error" message="import of package `github.com/mitchellh/go-homedir` is blocked because the module is in the blocked modules list. version `v1.1.0` is blocked because it does not meet the version constraint `<=1.1.0`. testing if blocked version constraint works." source="gomodguard"></error>
<error line="8" column="1" severity="error" message="import of package `github.com/uudashr/go-module` is blocked because the module is in the blocked modules list. `golang.org/x/mod` is a recommended module. `mod` is the official go.mod parser library." source="gomodguard"></error>
</file>
</checkstyle>
go install github.com/ryancurrah/gomodguard/v2/cmd/gomodguard@latest
git clone https://github.com/ryancurrah/gomodguard.git && cd gomodguard/cmd/gomodguard
go build -o gomodguard main.go
MIT
