Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#!/bin/sh
# Pre-commit hook to run goimports, gofmt, go vet, staticcheck, and golangci-lint

# Run goimports on all Go files
# Run goimports on all Go files but generated ones: gsx (*.x.go) and templ
# (*_templ.go) output must stay as the generator wrote it, since
# structpages-lint maps a _templ.go to its .templ only when the file is
# exactly what templ generates.
echo "Running goimports..."
find . -name "*.go" -not -name "*.x.go" -not -path "./vendor/*" -not -path "./.git/*" | xargs goimports -w
find . -name "*.go" -not -name "*.x.go" -not -name "*_templ.go" -not -path "./vendor/*" -not -path "./.git/*" | xargs goimports -w
if [ $? -ne 0 ]; then
echo "goimports failed"
exit 1
fi

# Run gofmt on all Go files
# Run gofmt on all Go files but generated ones
echo "Running gofmt..."
find . -name "*.go" -not -name "*.x.go" -not -path "./vendor/*" -not -path "./.git/*" | xargs gofmt -w -s
find . -name "*.go" -not -name "*.x.go" -not -name "*_templ.go" -not -path "./vendor/*" -not -path "./.git/*" | xargs gofmt -w -s
if [ $? -ne 0 ]; then
echo "gofmt failed"
exit 1
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,18 @@ jobs:
working-directory: ./examples/${{ matrix.example }}
run: go test ./...

test-lint-tool:
name: Test tools/lint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26"

- name: Test
working-directory: ./tools/lint
run: go test ./...
8 changes: 5 additions & 3 deletions docs/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,11 @@ The attribute is matched exactly:
only if the result is byte-for-byte the `_templ.go` on disk. The one exception is the
`// templ: version:` comment line, which may differ or be missing (`templ generate -include-version=false`): it
is a comment, so it changes no code. If anything else differs (another
templ version that generates different code, `-include-timestamp`, a hand edit), the file's positions can't be
trusted, and its attributes are skipped by `region` without a finding. To have them checked, regenerate with
the templ version the linter is built with (the `github.com/a-h/templ` version in the linter's `go.mod`).
templ version that generates different code, `-include-timestamp`, a hand edit, or a formatter run over the
generated file: `goimports` regroups its imports), the file's positions can't be trusted, and its attributes are
skipped by `region` and `keyed` without a finding. To have them checked, regenerate with the templ version the
linter is built with (the `github.com/a-h/templ` version in the linter's `go.mod`), and leave `*_templ.go` out of
any `goimports` or `gofmt -s` run, as you would gsx's `*.x.go`.

Limits:

Expand Down
30 changes: 30 additions & 0 deletions tools/lint/templscan/exprattr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package templscan

import (
"errors"
"path/filepath"
"testing"
)

// The linter's templ fixtures are joined to their .templ only when the
// _templ.go is exactly what templ generates, so a formatter run over one
// (goimports regroups its imports) silently drops its findings.
// stale.templ's _templ.go differs on purpose.
func TestExprAttrs_fixturesAreTemplOutput(t *testing.T) {
files, err := filepath.Glob("../testdata/*/tapp/*.templ")
if err != nil || len(files) == 0 {
t.Fatalf("no .templ fixtures: %v", err)
}
for _, f := range files {
_, err := ExprAttrs(f)
switch {
case filepath.Base(f) == "stale.templ":
if !errors.Is(err, ErrStale) {
t.Errorf("%s: err = %v, want ErrStale", f, err)
}
case err != nil:
t.Errorf("%s: %v (commit a _templ.go exactly as `templ generate` writes it: "+
"no goimports, no gofmt -s)", f, err)
}
}
}
9 changes: 4 additions & 5 deletions tools/lint/testdata/keyed/tapp/pages_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions tools/lint/testdata/region/tapp/noversion_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions tools/lint/testdata/region/tapp/pages_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions tools/lint/testdata/region/tapp/requests_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions tools/lint/testdata/region/tapp/stale_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading