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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
- name: Govulncheck
run: govulncheck ./...
continue-on-error: true
- run: make commentcheck
- run: go test -race -shuffle=on -cover -coverprofile=coverage.out ./...
- run: go build ./...
- run: make cover
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ jobs:
- name: Lint
run: make lint

- name: Comment check
run: make commentcheck

- name: Test (race)
run: make test-race

- name: Cover
run: make cover

- name: Comment check
run: make commentcheck

- name: Vulnerability check (non-blocking)
continue-on-error: true
run: |
Expand Down
15 changes: 9 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ GO ?= go
FMT_PKGS := $(shell $(GO) list $(PKG))
FMT_DIRS := $(shell $(GO) list -f '{{.Dir}}' $(PKG))

.PHONY: all init tidy fmt lint vet vuln test test-race cover cover-html build ci clean
.PHONY: all init tidy fmt lint vet vuln commentcheck test test-race cover cover-html build ci clean

all: build

Expand All @@ -25,11 +25,14 @@ fmt:
$(GO) run mvdan.cc/gofumpt@latest -w $(FMT_DIRS)

lint:
$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run --timeout=5m
$(GO) install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
golangci-lint run --timeout=5m

commentcheck:
$(GO) run ./cmd/commentcheck

vet:
$(GO) vet $(PKG)
$(GO) vet $(PKG)

test:
mkdir -p $(BUILD_DIR)
Expand All @@ -50,9 +53,9 @@ build:
$(GO) build -trimpath -buildvcs=false -ldflags="-s -w" -o $(BUILD_DIR)/$(APP) ./cmd/hclalign

vuln:
$(GO) run golang.org/x/vuln/cmd/govulncheck@latest $(PKG)
$(GO) run golang.org/x/vuln/cmd/govulncheck@latest $(PKG)

ci: tidy fmt lint vuln test cover build
ci: tidy fmt lint vuln commentcheck test cover build

clean:
rm -rf $(BUILD_DIR)
62 changes: 62 additions & 0 deletions cmd/commentcheck/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// cmd/commentcheck/main.go
package main

import (
"fmt"
"go/parser"
"go/token"
"io/fs"
"os"
"path/filepath"
"strings"
)

func check(root string) error {
var bad []string
walk := func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
if d.Name() == "vendor" || strings.HasPrefix(d.Name(), ".") {
return filepath.SkipDir
}
return nil
}
if filepath.Ext(path) != ".go" {
return nil
}
fset := token.NewFileSet()
src, err := os.ReadFile(path)
if err != nil {
return err
}
file, err := parser.ParseFile(fset, path, src, parser.ParseComments)
if err != nil {
return err
}
for _, cg := range file.Comments {
for _, c := range cg.List {
if fset.Position(c.Slash).Line > 1 {
bad = append(bad, path)
return nil
}
}
}
return nil
}
if err := filepath.WalkDir(root, walk); err != nil {
return err
}
if len(bad) > 0 {
return fmt.Errorf("comments beyond first line: %s", strings.Join(bad, ", "))
}
return nil
}

func main() {
if err := check("."); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
33 changes: 33 additions & 0 deletions cmd/commentcheck/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// cmd/commentcheck/main_test.go
package main

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

func TestCheck(t *testing.T) {
t.Run("compliant", func(t *testing.T) {
dir := t.TempDir()
write(t, dir, "ok.go", "// ok.go\npackage main\n")
if err := check(dir); err != nil {
t.Fatalf("unexpected error: %v", err)
}
})
t.Run("noncompliant", func(t *testing.T) {
dir := t.TempDir()
write(t, dir, "bad.go", "// bad.go\npackage main\n// bad\n")
if err := check(dir); err == nil {
t.Fatalf("expected error")
}
})
}

func write(t *testing.T, dir, name, content string) {
t.Helper()
path := filepath.Join(dir, name)
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
t.Fatalf("write %s: %v", name, err)
}
}
Loading