v0.1.0 79118a8

README.md RawHistoryFolder

hexcheck

hexcheck is a Go architecture linter for hexagonal and clean architecture boundaries.

It is built on golang.org/x/tools/go/analysis, runs as a standalone CLI, and can be embedded in a custom golangci-lint binary through the Module Plugin System.

Goals

  • map project packages to configurable architecture components
  • catch deterministic boundary violations in CI
  • warn about suspicious business logic in adapters and entrypoints
  • warn when tests bypass generated interface mocks with local fakes or real adapters
  • smoke test the analyzer against real Go repositories through opt-in local paths

Quick example

version: 1
components:
  core:
    role: core
    paths:
      - internal/domain/**
  usecase:
    role: usecase
    paths:
      - internal/application/usecase/**
  ports:
    role: ports
    paths:
      - internal/application/port/**
  adapters:
    role: adapter
    paths:
      - internal/infrastructure/**
      - internal/ui/**
      - internal/cli/**
  entrypoints:
    role: entrypoint
    paths:
      - cmd/**

rules:
  no-adapter-imports-in-core: error
  no-infra-imports-in-usecase: error
  no-framework-types-in-core: error
  no-infra-types-in-ports: error
  no-adapter-to-adapter-imports: warn
  suspicious-business-logic-in-adapter: warn
  no-local-fakes-for-ports: warn
  prefer-generated-mocks: warn

Standalone CLI

hexcheck --config .hexcheck.yaml ./...

golangci-lint module plugin

Build a custom golangci-lint binary using the module plugin system:

golangci-lint custom -c examples/custom-gcl.yml

Example builder config:

# examples/custom-gcl.yml
version: v2.12.2
name: hex-golangci-lint
destination: ./bin
plugins:
  - module: github.com/bnema/hexcheck
    import: github.com/bnema/hexcheck/golangci
    version: v0.1.0

Enable it in a project:

# examples/golangci.yml
version: "2"
linters:
  enable:
    - hexcheck
  settings:
    custom:
      hexcheck:
        type: module
        description: Checks hexagonal architecture boundaries.
        settings:
          config: .hexcheck.yaml

Local development

make test
make check
HEXCHECK_SMOKE_REPO=/path/to/local/go/repo make smoke-local
source
1# hexcheck
2
3`hexcheck` is a Go architecture linter for hexagonal and clean architecture boundaries.
4
5It is built on `golang.org/x/tools/go/analysis`, runs as a standalone CLI, and can be embedded in a custom `golangci-lint` binary through the Module Plugin System.
6
7## Goals
8
9- map project packages to configurable architecture components
10- catch deterministic boundary violations in CI
11- warn about suspicious business logic in adapters and entrypoints
12- warn when tests bypass generated interface mocks with local fakes or real adapters
13- smoke test the analyzer against real Go repositories through opt-in local paths
14
15## Quick example
16
17```yaml
18version: 1
19components:
20  core:
21    role: core
22    paths:
23      - internal/domain/**
24  usecase:
25    role: usecase
26    paths:
27      - internal/application/usecase/**
28  ports:
29    role: ports
30    paths:
31      - internal/application/port/**
32  adapters:
33    role: adapter
34    paths:
35      - internal/infrastructure/**
36      - internal/ui/**
37      - internal/cli/**
38  entrypoints:
39    role: entrypoint
40    paths:
41      - cmd/**
42
43rules:
44  no-adapter-imports-in-core: error
45  no-infra-imports-in-usecase: error
46  no-framework-types-in-core: error
47  no-infra-types-in-ports: error
48  no-adapter-to-adapter-imports: warn
49  suspicious-business-logic-in-adapter: warn
50  no-local-fakes-for-ports: warn
51  prefer-generated-mocks: warn
52```
53
54## Standalone CLI
55
56```bash
57hexcheck --config .hexcheck.yaml ./...
58```
59
60## golangci-lint module plugin
61
62Build a custom golangci-lint binary using the module plugin system:
63
64```bash
65golangci-lint custom -c examples/custom-gcl.yml
66```
67
68Example builder config:
69
70```yaml
71# examples/custom-gcl.yml
72version: v2.12.2
73name: hex-golangci-lint
74destination: ./bin
75plugins:
76  - module: github.com/bnema/hexcheck
77    import: github.com/bnema/hexcheck/golangci
78    version: v0.1.0
79```
80
81Enable it in a project:
82
83```yaml
84# examples/golangci.yml
85version: "2"
86linters:
87  enable:
88    - hexcheck
89  settings:
90    custom:
91      hexcheck:
92        type: module
93        description: Checks hexagonal architecture boundaries.
94        settings:
95          config: .hexcheck.yaml
96```
97
98## Local development
99
100```bash
101make test
102make check
103HEXCHECK_SMOKE_REPO=/path/to/local/go/repo make smoke-local
104```

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 5

↑↓ moveenter openesc close