gogreement

module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2025 License: MIT

README

GoGreement

CI codecov Documentation Go Reference Go Report Card

A static analyzer for Go that enforces developer agreements through code annotations.

What is it?

GoGreement lets you document and enforce contracts directly in your code using annotations. Mark types as immutable, enforce constructor usage, restrict code to tests, or verify interface implementations—the linter will catch violations at build time.

// Mark a type as immutable - prevent field modifications
// @immutable
type Config struct {
    Host string
    Port int
}

func main() {
    cfg := Config{Host: "localhost", Port: 8080}
    cfg.Port = 9000  // [IMM01] immutability violation in type "Config": cannot assign to field "Port" of immutable type
}

Installation

go install github.com/a14e/gogreement/cmd/gogreement@v0.0.1
For latest version:
go install github.com/a14e/gogreement/cmd/gogreement@latest

Run on your project:

gogreement ./...

Quick Examples

Prevent mutations with @immutable
// @immutable
type Point struct {
    X, Y int
}

p := Point{X: 1, Y: 2}
p.X = 10  // [IMM01] immutability violation in type "Point": cannot assign to field "X" of immutable type
Enforce constructor usage with @constructor
// @constructor NewUser
type User struct {
    id   string
    name string
}

func NewUser(name string) *User {
    return &User{id: generateID(), name: name}
}

// This won't compile:
u := User{name: "John"}  // [CTOR01] type instantiation must be in constructor (allowed: [NewUser])
Restrict code to tests with @testonly
// @testonly
func CreateTestDatabase() *DB {
    // Only callable from test files
}

// In production code:
db := CreateTestDatabase()  // [TONL02] function CreateTestDatabase is marked @testonly and can only be called in test files
Verify interface implementations with @implements
// @implements io.Reader
type BufferedReader struct {
    buf []byte
}

func (r *BufferedReader) Read(p []byte) (n int, err error) {
    // Implementation
}

// If you remove Read() or change its signature, you get an error:
// [IMPL03] type "BufferedReader" does not implement interface "io.Reader"
// missing methods:
//   Read([]byte) (int, error)

Configuration

Control behavior with environment variables or command flags:

# Skip test files
gogreement --config.scan-tests=false ./...

# Exclude specific paths
export GOGREEMENT_EXCLUDE_PATHS="vendor,generated"
gogreement ./...

# Disable specific checks
gogreement --config.exclude-checks=IMM,CTOR ./...

Why use it?

  • Documentation that's enforced: Annotations serve as both documentation and contracts
  • Catch bugs early: Violations are caught at build time, not in production
  • Team coordination: Formalize agreements about how code should be used
  • No runtime overhead: Pure static analysis

Documentation

Full documentation is available at a14e.github.io/gogreement

Contributing

Contributions are welcome. See the contributing guide for details on:

  • Setting up the development environment
  • Running tests
  • Adding new checkers
  • Code style guidelines

Disclaimer

This tool is provided as-is. While it aims to catch common mistakes and enforce agreements, it's a static analyzer and may have limitations. Always review its output and use it as part of your development workflow, not as a replacement for testing and code review.

License

MIT License - see LICENSE-MIT file for details

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL