Skip to content

Add errstklint: Linter to enforce defer errstk.Wrap(&err)#2

Merged
tomoemon merged 4 commits into
mainfrom
add-errstklint-linter
Nov 9, 2025
Merged

Add errstklint: Linter to enforce defer errstk.Wrap(&err)#2
tomoemon merged 4 commits into
mainfrom
add-errstklint-linter

Conversation

@tomoemon

@tomoemon tomoemon commented Nov 7, 2025

Copy link
Copy Markdown
Owner

Summary

Add errstklint, a linter tool that ensures all functions returning errors include defer errstk.Wrap(&err) for proper stack trace capture.

Features

Standalone CLI Tool

go install github.com/tomoemon/go-errstk/cmd/errstklint@latest
errstklint ./...
errstklint -exclude="generated/*.go,**/mock_*.go" ./...

golangci-lint Plugin Support

# .custom-gcl.yml
version: v1.62.2
plugins:
  - module: 'github.com/tomoemon/go-errstk/errstklint'
    import: 'github.com/tomoemon/go-errstk/errstklint'
    version: v1.0.0

# .golangci.yml
linters:
  settings:
    errstklint:
      exclude:
        - "generated/*.go"
        - "**/mock_*.go"
        - "**/*_test.go"

File Exclusion Patterns

  • Supports glob patterns with ** for directory recursion
  • Examples: generated/*.go, **/mock_*.go, **/*_test.go

Implementation

Single Module Structure

go-errstk/
├── go.mod                    # Single module for entire project
├── errstk.go                 # Main library (no linter dependencies)
├── errstklint/               # Analyzer package
│   ├── analyzer.go           # go/analysis implementation
│   ├── plugin.go             # golangci-lint plugin entry point
│   ├── analyzer_test.go      # Tests
│   └── testdata/             # Test fixtures
└── cmd/errstklint/           # CLI tool
    └── main.go               # Standalone executable

Dependency Isolation: Library users (import "github.com/tomoemon/go-errstk") don't get linter dependencies. Only projects importing errstklint package get golang.org/x/tools dependencies.

Usage

Detects missing defer:

// ❌ Reported by linter
func GetUser(id string) (user *User, err error) {
    // Missing: defer errstk.Wrap(&err)
    return db.Query(id)
}

// ✅ Passes linter
func GetUser(id string) (user *User, err error) {
    defer errstk.Wrap(&err)
    return db.Query(id)
}

Testing

  • ✅ go/analysis analyzer implementation
  • ✅ Test cases with testdata
  • ✅ golangci-lint plugin integration
  • ✅ File exclusion patterns with glob support
  • ✅ Single module structure verified
  • ✅ CI/CD workflow updated

Test plan

  • Create analyzer package with go/analysis
  • Implement AST-based defer detection
  • Add file exclusion pattern support
  • Create standalone CLI tool
  • Implement golangci-lint plugin
  • Add comprehensive tests
  • Update documentation (README, errstklint/README, cmd/errstklint/README)
  • Update CI/CD workflow
  • Verify go install works correctly

🤖 Generated with Claude Code

tomoemon and others added 4 commits November 7, 2025 20:20
This commit adds a comprehensive linter tool to ensure all functions
returning errors include defer errstk.Wrap(&err) for proper stack trace
capture.

Features:
- Standalone CLI tool (cmd/errstklint)
- golangci-lint plugin support (errstklint/)
- File exclusion patterns using glob (e.g., generated/*.go, **/mock_*.go)
- Configurable via CLI flags or .golangci.yml

Implementation:
- errstklint/: Public package with analyzer and plugin support
  - analyzer.go: Core analysis logic using go/analysis framework
  - plugin.go: golangci-lint plugin integration with config parsing
  - Supports exclude patterns via -exclude flag or YAML config

- cmd/errstklint/: Standalone CLI tool
  - Uses errstklint package as library
  - Independent go.mod for separate dependency management
  - Comprehensive test suite with testdata

- Updated CI workflow to test all components

Usage:
  # Standalone
  errstklint -exclude="generated/*.go,**/mock_*.go" ./...

  # golangci-lint plugin
  # .golangci.yml:
  # linters-settings:
  #   errstklint:
  #     exclude:
  #       - "generated/*.go"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Changes:
- Remove cmd/errstklint/go.mod and errstklint/go.mod
- Merge all dependencies into root go.mod
- Move analyzer_test.go and testdata to errstklint/ package
- Keep cmd/errstklint/ as CLI entry point only

Benefits:
- Simpler module structure (single go.mod)
- go install github.com/tomoemon/go-errstk/cmd/errstklint@version works
- Library users don't get linter dependencies (unless they import it)
- Tests are co-located with implementation
Changes:
- Add linter to Design Philosophy in root README
- Simplify cmd/errstklint/README.md (CLI-focused)
- Expand errstklint/README.md with comprehensive docs
- Fix golangci-lint config syntax (linters: settings:)
- Add module structure explanation
@tomoemon
tomoemon merged commit 4bec266 into main Nov 9, 2025
1 check passed
@tomoemon
tomoemon deleted the add-errstklint-linter branch November 9, 2025 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant