wangjohn/levenshtein: A comprehensive batch of lint rules for Go, shared across all your repos. - wangjohn/levenshtein

github.com · 2026-10-02 · by Long Nguyen ·github
A comprehensive batch of lint rules for Go, shared across all your repos. - wangjohn/levenshtein

wangjohn/levenshtein

A comprehensive batch of lint rules for Go, shared across all your repos. - wangjohn/levenshtein

0 stars · 0 forks

README

Levenshtein

A curated set of Go lint rules and verification checks, easy to hook up to any Go repo. Coding agents are writing more and more of our code, and I want as much of that code as possible to be verifiable. Good lint rules and automated checks give agents feedback they can act on while they work, and give us more than the agent's word that a change is ready. I built Levenshtein while setting up a bunch of new Go repos. I wanted one place to keep a high-quality set of rules I could rely on for all of my repos, without researching analyzers and copying lint configs every time. Each repo pins a Levenshtein revision and runs ./verify, so that all my repos use the same rules and tool versions (and updates are easy to roll out everywhere). You can easily add your own lint rules or commands alongside the built-in checks in your repo’s configuration. What it checks Levenshtein combines Staticcheck, established Go analyzers, and a few rules of its own. The rules catch bugs and encourage readable code; most naming and comment-style preferences are left out. Default checks ./verify and pre-merge run these checks. Go vulnerability scanning runs only in main, which also reruns checks without using cached results.

Check Example finding

Staticcheck Close before error check: deferring f.Close() before checking whether os.Open succeeded

Bug-finding analyzers Unchecked error: calling file.Write(data) without checking whether the write failed

Modernize Manual map copy: copying entries in a loop when maps.Copy does the same job

Levenshtein's rules Untyped status: comparing a plain string to "done" and "failed" instead of typed constants

go vet (go-vet) Format mismatch: passing "hello" to fmt.Printf("%d", ...), which expects an integer

Module checks (go-mod) Missing dependency: importing a package whose module is missing from go.mod

Go vulnerabilities (go-vuln, main only) Vulnerable function: your code can reach a dependency function with a known security flaw

Optional checks Add these checks to your repo's configuration.

Check Example finding

Race detector (go-test) Concurrent writes: two goroutines updating a shared map without synchronization

HTTP resources (go-http) Unclosed response body: returning from an HTTP request without closing resp.Body

SQL resources (go-sql) Unclosed query results: reading database rows without closing them afterward

GitHub Actions lint (workflow-lint) Unknown property: a workflow expression referencing a property that doesn't exist

Workflow security (workflow-security) Shell injection: inserting a PR title directly into a workflow's shell command

ShellCheck (shell-lint) Unchecked directory change: running cd "$dir" without stopping or handling failure

Secret scanning (secrets) Committed API key: a credential left in a tracked configuration file

Other dependency vulnerabilities (deps-vuln) Vulnerable package: a version with a known security flaw pinned in package-lock.json

Import boundaries (go-imports) Forbidden import: a domain package importing a database package against your layering rules

Generated files (go-generate) Stale generated code: a committed file that changes when go generate runs

API compatibility (go-apidiff) Removed exported function: a public API change that breaks existing callers

Mutation testing (go-mutation) Missed boundary bug: changing > to >= without any test failing

Semantic lint (semantic-lint) Vague error message: an added error gives the caller no clue how to fix the problem; advisory review through Jev

Custom commands (command) Failed integration test: your repo's test script exits with an error

self-test tests Levenshtein's own fixtures when developing the shared checks. The lint and CI/CD rules index links to all the rules, checks, and CI policies, with explanations of why each rule is enabled or left out. To understand a Go lint warning, start with Go lint rules. Quickstart To try the Go lint rules, run this from your module's root with Go 1.21 or later: go run github.com/wangjohn/levenshtein/runner/lint/cmd/levenshtein-lint@latest ./... For the default checks, use Go and a Docker-compatible runtime on macOS or Linux: git clone --depth 1 --branch v0.2.0 https://github.com/wangjohn/levenshtein ./levenshtein/verify --source ./myapp --format text A single Go module needs no config. The first run downloads and builds the tools; verify reports problems without changing your files. See setup for prerequisites and named runs.

CI setup: GitHub Actions and other providers. Coding agents: instructions and hooks for running checks while an agent works. Configuration: multiple modules, extra checks, and custom commands. Baselines and community rules: adopt checks gradually or add your own analyzers.

Documentation Setup · Rules index · Configuration · CLI reference · Coding agents · Troubleshooting · All docs See the changelog and versioning policy before updating the version your repo uses. If you're happy with a single repo's golangci-lint setup, you may not need this; the FAQ compares the two. Contributing and security Maintained by John Wang (@wangjohn). For questions or bugs, open an issue. See CONTRIBUTING.md. Report vulnerabilities privately as SECURITY.md describes. Released under the Apache License 2.0; see NOTICE.

source

github.com · 3 images · 155 links

Comments (0)

No comments yet