Linter used to enforce some good project structure and validate top level architecture (code layers)
You can imagine some simple architecture, for example classic onion part from "clean architecture":
And describe/declare it as semantic yaml linter config:
version: 3
workdir: internal
components:
handler: { in: handlers/* } # wildcard one level
service: { in: services/** } # wildcard many levels
repository: { in: domain/*/repository } # wildcard DDD repositories
model: { in: models } # match exactly one package
commonComponents:
- models
deps:
handler:
mayDependOn:
- service
service:
mayDependOn:
- repository
see config syntax for details.
And now linter will check all project code inside internal
workdir
and show warnings, when code violate this rules.
For best experience you can add linter into CI workflow
Imagine some main.go
, when we provide repository
into handler
and get some bad
flow:
func main() {
// ..
repository := booksRepository.NewRepository()
handler := booksHandler.NewHandler(
service,
repository, // !!!
)
// ..
}
Linter will easily found this issue:
docker run --rm -v ${PWD}:/app fe3dback/go-arch-lint:latest-stable-release check --project-path /app
other docker tags and versions
It require go 1.20+
go install github.com/fe3dback/go-arch-lint@latest
go-arch-lint check --project-path ~/code/my-project
# or
cd ~/code/my-project
go-arch-lint check
https://plugins.jetbrains.com/plugin/15423-goarchlint-file-support
Adding a linter to a project takes several steps:
.go-arch-lint.yml
file describing the ideal project architecturetodo
with the labelUsage:
go-arch-lint check [flags]
Flags:
--arch-file string arch file path (default ".go-arch-lint.yml")
-h, --help help for check
--max-warnings int max number of warnings to output (default 512)
--project-path string absolute path to project directory (where '.go-arch-lint.yml' is located) (default "./")
Global Flags:
--json (alias for --output-type=json)
--output-color use ANSI colors in terminal output (default true)
--output-json-one-line format JSON as single line payload (without line breaks), only for json output type
--output-type string type of command output, variants: [ascii, json] (default "default")
This linter will return:
Status Code | Description |
---|---|
0 | Project has correct architecture |
1 | Found warnings |
Linter will:
Example config of this repository: .go-arch-lint.yml
You can generate dependencies graph with command graph
:
go-arch-lint graph
See full graph documentation for details.
go-arch-lint can also be used as a pre-commit hook, acting before each commit is made.
This is useful to always check that your new code still respects your repo architecture, and to always update your graph SVG.
.pre-commit-config.yaml
file at the root of your repository with the following content:repos:
- repo: https://github.com/fe3dback/go-arch-lint
rev: master
hooks:
- id: go-arch-lint-check
- id: go-arch-lint-graph
args: ['--include-vendors=true', '--out=go-arch-lint-graph.svg']
args
.pre-commit autoupdate
pre-commit install