Skip to content

Releases: mpyw/molint

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 24 Oct 22:53
Immutable release. Only release title and notes can be modified.
5ba8fcd

A pass without the buildssa result now returns the exported molint.ErrNoSSA (#24). It returned an unexported error before. Nothing molint reports changes.

Upgrading

Who Do
golangci-lint plugin Set version: v0.4.1 in .custom-gcl.yml
Everyone else Nothing

Install

mise use "github:mpyw/molint@0.4.1"

Full changelog: v0.4.0...v0.4.1

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 22:04
Immutable release. Only release title and notes can be modified.
b15b3cd

molint adds molint.New, which builds an analyzer from typed settings. Nothing molint reports changes.

molint.New

New builds an analyzer of its own from a molint.Config. It has no flags, so two analyzers share nothing with each other or with molint.Analyzer (#22):

a, err := molint.New(molint.Config{
	Rules: map[string]bool{"return-error": true},
})

Rules turns a rule on or off by its name, as the flags do. A rule left out keeps its default. New fails on an unknown rule. molint.Analyzer keeps the flags, for the command and go vet. The golangci-lint plugin now builds its analyzer with New.

Other changes

Change Effect
The skills move from the root package to github.com/mpyw/molint/skills (#21) The analyzer no longer pulls in go-skill-embed. molint.Skills is removed. Use skills.Set
The analyzer is built without init (#22) None
The README says AI coding agents are used (#22) None
golang.org/x/tools goes from v0.50.0 to v0.52.0 (#16, #18) None
The design notes drop a repeated paragraph (#17), and the icon moves to .github/assets (#15) None

declscope, which checks the repository itself, was updated too (#12, #13, #14, #19, #20). It is a development tool, and not part of the binary.

Upgrading

Who Do
golangci-lint plugin Set version: v0.4.0 in .custom-gcl.yml
Code that read molint.Skills Import github.com/mpyw/molint/skills and read skills.Set
Everyone else Nothing

Install

mise use "github:mpyw/molint@0.4.0"

Full changelog: v0.3.0...v0.4.0

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 05 Oct 00:14
Immutable release. Only release title and notes can be modified.
d9da416

Highlights

field-nil-store is on by default

field-nil-store reports nil stored into a pointer field: S{F: nil}, S{1, nil}, s.F = nil, or a nil that reaches the store on some path. It is now on without a flag.

A nil written into a field says the field is absent there, so each report is right. Without exhaustruct, a field left out of a composite literal is not seen. The rule then misses more, but it reports nothing wrong.

Rule 0.2.0 0.3.0
field-nil-store Off On
field-nil-compare Off Off
return-error Off Off

field-nil-compare stays off. It also reports a field set on first use, and a check made just in case on a field that is never nil. There the fix is to delete the check, not to make the field an mo.Option.

Run inside golangci-lint

molint can be built into golangci-lint as a module plugin. It is not bundled with golangci-lint, so build a binary that holds it.

.custom-gcl.yml:

version: v2.13.1
plugins:
  - module: github.com/mpyw/molint
    import: github.com/mpyw/molint/plugin
    version: v0.3.0

.golangci.yml:

version: "2"
linters:
  enable:
    - molint
  settings:
    custom:
      molint:
        type: module
        description: Enforces samber/mo.
        settings:
          field-nil-compare: true
golangci-lint custom  # writes ./custom-gcl
./custom-gcl run ./...

Each key under settings is a rule's name, as the flags take it. A rule left out keeps its default. An unknown name stops the run.

Breaking change

Upgrading from 0.2.0 reports nil stores into pointer fields that were silent before. To keep the old behavior, pass -field-nil-store=false, or set field-nil-store: false in the plugin's settings.

Pull requests

  • #11 feat: turn field-nil-store on by default, and add a golangci-lint module plugin

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 17:45
Immutable release. Only release title and notes can be modified.
ee0bd7f

Highlights

New rules for pointer fields

Two rules report a pointer field used as optional, so that it becomes mo.Option. Both are off by default.

Rule Reports Turn it on with
field-nil-store nil stored into a pointer field: S{F: nil}, S{1, nil}, s.F = nil, or a nil that reaches the store on some path -field-nil-store
field-nil-compare A pointer field compared with nil: s.F == nil, s.F != nil, or case nil -field-nil-compare

Important

Turn on field-nil-store together with exhaustruct. A field left out of a composite literal is not seen by molint. The exhaustruct linter makes you write it as F: nil. Then molint reports it.

field-nil-compare does not need exhaustruct. It also finds a field that only a decoder such as json.Unmarshal leaves nil.

Only fields declared in the package count. An embedded field and a field in a generated file do not.

An agent skill in the binary

The binary carries molint-authoring, a skill for an AI agent writing code under molint. It says how to fix each rule with samber/mo, which fixes only hide a problem, and when an ignore is right.

molint skill install                                # the agents already set up in this project
molint skill install --agent claude-code --scope user
molint skill list                                   # where it is, and whether it is current

gh skill install mpyw/molint molint-authoring installs the same skill without the binary.

-V=full prints the release

molint -V=full now prints the release, such as 0.2.0. It used to print devel for every binary. go vet -vettool reads the same line to identify the tool.

Breaking change

molint.ErrNoSSA is removed. No driver could return it, since a driver runs the analyzer's Requires first. Only a hand-built analysis.Pass without SSA met it.

Documentation

  • The rule tables in the README say what each row means, in place of "The same".
  • The README and design/rules.md list a gap that every rule already had. No rule analyzes the initializer of a package-level variable, such as var s = S{P: nil}.

Pull requests

  • #9 feat: add field-nil-store and field-nil-compare
  • #10 feat: ship the molint-authoring skill, and answer -V=full with the release

Full Changelog: v0.1.0...v0.2.0

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 17:06
Immutable release. Only release title and notes can be modified.
9817b5f

Changelog

  • 0bd2e2b Add a logo and a social preview
  • f4a1eef Add types that are not pointers to the return-nil table
  • 5546116 Break the unwrap-nil summary and spell the kinds as Go does
  • 33da306 Close the gaps the reviews of the specs found
  • 9817b5f Drop the work-in-progress warning
  • 972feb9 Explain why return-nil and wrap-nil judge a nil slice apart
  • 1c1afb3 Head the README with badges, as declscope does
  • f22a8a9 Implement the molint rules
  • 40b4df9 Implement the return-only rule
  • 876c580 Initial commit
  • 8e3b368 Lay out the install section as declscope does, with mise first
  • f186bf4 Link every mention of samber/mo, samber/lo and nilaway
  • 68034f8 Link the rules that other rules refer to
  • 4a62cb0 Link the types, functions and methods of mo and lo to their docs
  • 13ff295 Make each fix a heading below its rule
  • b76c17c Mark the row that another rule reports with a warning
  • 8d1544d Mark the rule tables of the README valid or not (#4)
  • 5330640 Mark the rules' defaults with green and red
  • 5a5e822 Put each rule's fix under its report in the summary table
  • 5e3e6ff Rename to molint and pin the rules as fixtures
  • 5f19711 Report nil maps, funcs and channels given to mo.Some and mo.Ok
  • be59b5d Report nil slices given to mo.Some and mo.Ok
  • 004299a Revert "Show how to fix return-nil for each shape of results"
  • 8b59c58 Show each fix in the README as code
  • 7a4dc03 Show how to fix return-nil for each shape of results
  • e02be3f Show the code of each rule's table as a Go block
  • 606f7ad Split the README's Valid columns into Valid? and Reason
  • cbeb08e Use a value, not a pointer, in the return-error examples
  • 98066ba Widen unwrap-nil to every type whose nil breaks on use
  • 98d7de3 [Claude] Record how molint and nilaway work together (#3)