Skip to content

Releases: egoisutolabs/goxlint

v0.1.0

Choose a tag to compare

@gendev1 gendev1 released this 28 Oct 05:53
3db2d09

goxlint is an engine for building your own Go linter: you write the rules only your codebase has, and goxlint provides loading, the AST walk, configuration, fixes, suppressions, output, and a test harness.

v0.1.0 is the first release we consider ready for real projects. The rule API is still v0.x and can change, but from here every release lists what changed and what you must update.

go get github.com/egoisutolabs/goxlint@v0.1.0

To see it on your own code first, with the example rules:

go run github.com/egoisutolabs/goxlint/examples/goxlint@v0.1.0 init
go run github.com/egoisutolabs/goxlint/examples/goxlint@v0.1.0 ./...

New

go/analysis adapter. The new goxlintanalysis package turns goxlint rules into analysis.Analyzer values. The same rules run under go vet -vettool, multichecker, and golangci-lint module plugins, with suppressions, help text, related locations, and safe and suggestion fixes. (#14)

Related locations. A diagnostic can point at supporting code in other files of the same package: goxlint.Diagnostic.Related. Each position is checked against the exact files loaded for the run, so a stale position becomes an internal error instead of a wrong frame. Related locations appear in code frames, JSON (related), SARIF (relatedLocations), and go/analysis (RelatedInformation). (#35)

Package rules in the test harness. goxlinttest.RunPackage type-checks several files as one package and runs both Create and AnalyzePackage. It supports per-file options and disabled files, and RelatedError checks related locations, with line numbers relative to each file as written. (#17, #35)

SARIF 2.1.0 output. --format sarif for GitHub code scanning and other SARIF tools. Columns are converted from Go byte offsets to Unicode code points, as SARIF requires. Validated against the official schema. (#28)

Lint from stdin. --stdin-filename <path> lints an unsaved buffer as if it were at that path, for editors and coding-agent hooks. In typed mode the buffer replaces the file on disk through a go/packages overlay, and package rules see the other files of the package. With a fix flag, the fixed source goes to stdout and nothing is written to disk. (#33)

Rule timing. --timing prints the 10 slowest rules and the load time to stderr. Without the flag, no timers are installed; a benchmark showed no measurable difference. (#29)

rules --format json. Lists every rule with its metadata and its resolved severity. (#11)

Changed

Fixes run until stable. --fix applies fixes in passes, up to ten, so one fix can build on another. An overlapping fix waits for the next pass. If fixes still apply after ten passes, goxlint names the files that did not stabilize. (#18)

Fixes keep formatting. A file that was gofmt-clean before fixing is formatted after the last pass. A file that was not keeps only the rule's edits. Every batch is parsed before it is written; a fix that produces invalid Go is rejected, reported with its rule IDs, and the run exits with 2. (#26)

Suppressions for disabled rules are kept. A //goxlint:ignore for a registered rule that is off in this run (an opt-in rule, an override, or -A) is no longer reported as unused. Unknown names, stale targets for enabled rules, and redundant targets are still reported. (#27)

Forward slashes everywhere. Diagnostic paths use / in every output format on every OS, including Windows. A directory named ..foo inside the root is no longer treated as outside it. (#20, #24)

Upgrading from v0.0.2

  • goxlint.Diagnostic and goxlinttest.Error have a new Related field. Keyed literals need no change. A literal without field names no longer compiles; add the field names.
  • --fix now formats files that were gofmt-clean. If you relied on unformatted fix output, compare your CI formatting step.
  • A fix that produces invalid Go now exits with 2 instead of writing the file.
  • Fewer unused-suppression reports: targets for rules that are off are no longer reported.
  • On Windows, output paths now use /.

Project

  • CI runs gofmt, go vet, race tests, and goxlint on its own code on Linux, macOS, and Windows. (#20)
  • New: CONTRIBUTING.md, AGENTS.md, SECURITY.md, a code of conduct, and Discussions for questions and rules you built.
  • Contributors: comment on an issue to ask for it, and a maintainer assigns it. Issues labeled good first issue are a good start. (#38)
  • A new README and a mascot: an oxpecker that lints itself.

Known limits

No result cache, no editor language server yet (#15), and no data-flow analysis (#34). We have no benchmarks yet (#25), so we make no speed claims.

Thanks to @dannyward630 for rules --format json (#11).

Full changelog: v0.0.2...v0.1.0

v0.0.2: goose-lint is now goxlint

Choose a tag to compare

@gendev1 gendev1 released this 27 Oct 07:10

goose-lint is now goxlint. This release renames the project. There are no changes in behavior.

Upgrade from v0.0.1

v0.0.1 (goose-lint) v0.0.2 (goxlint)
github.com/egoisutolabs/goose-lint/goose github.com/egoisutolabs/goxlint (the rule API is now at the module root)
github.com/egoisutolabs/goose-lint/goosetest github.com/egoisutolabs/goxlint/goxlinttest
github.com/egoisutolabs/goose-lint/cli github.com/egoisutolabs/goxlint/cli
.gooserc.json .goxlintrc.json
//goose:ignore, //goose:ignore-file //goxlint:ignore, //goxlint:ignore-file
goose/unused-suppression goxlint/unused-suppression

Steps:

  1. go get github.com/egoisutolabs/goxlint@v0.0.2
  2. Change the imports in the table. Change goose. to goxlint. and goosetest. to goxlinttest. in your code.
  3. Rename .gooserc.json to .goxlintrc.json.
  4. Change the suppression comments in your code.
  5. Run go mod tidy to remove the old module.

The old repository URL redirects to the new one. The goose-lint module stays in the Go module proxy, but it gets no more updates.

Full changelog: v0.0.1...v0.0.2

v0.0.1: first release (as goose-lint)

Choose a tag to compare

@gendev1 gendev1 released this 27 Oct 07:10

First public release, under the module path github.com/egoisutolabs/goose-lint.

This module path is no longer supported. The project is now goxlint. Use v0.0.2 or later at github.com/egoisutolabs/goxlint.

What is in this release

An engine to build your own Go linter:

  • Visitor rules. A rule registers handlers for AST node types. All rules share one walk of each file.
  • Package rules. AnalyzePackage examines all files of a package together.
  • Type information on demand. Typed mode only when an enabled rule sets NeedsTypes; otherwise syntax-only parsing.
  • Configuration. .gooserc.json with categories, severities, rule options, ignore patterns, and per-file overrides.
  • Fixes with three levels: safe, suggestion, dangerous.
  • Suppressions. //goose:ignore and //goose:ignore-file, with unused-suppression reports.
  • Output formats: code frames, unix, json, github.
  • Rule tests with the goosetest package.
  • An example linter in examples/goose.

Requires Go 1.26 or later. MIT License.