docs+rules: teach httputil.Bind/BindEmpty (web v1.6.0); v1.3.4

Builtins README gains Bind/BindEmpty adapter rows + a path/query binding section
(uuid/time via TextUnmarshaler; default: with min not omitempty,min). New info
rule httputil.prefer-bind flags hand-rolled chi.URLParam / r.URL.Query() reads and
points to Bind. Escape-hatch note rescoped to custom responses only.
This commit is contained in:
2026-08-13 23:19:19 -06:00
parent 766adb2989
commit 0f476fd6de
6 changed files with 185 additions and 12 deletions
+48
View File
@@ -0,0 +1,48 @@
package rules
import "testing"
const urlParamSnippet = `package handler
import "github.com/go-chi/chi/v5"
func (h *Handler) f(r *http.Request) {
id := chi.URLParam(r, "id")
_ = id
}
`
const urlQuerySnippet = `package handler
func (h *Handler) f(r *http.Request) {
page := r.URL.Query().Get("page")
_ = page
}
`
const boundHandlerSnippet = `package handler
import "code.nochebuena.dev/einherjar/web/httputil"
func (h *Handler) f() {
_ = httputil.Bind(h.v, h.logger, h.get)
}
`
func TestPreferBindFiresOnURLParam(t *testing.T) {
if got := findingsFor(Run(urlParamSnippet), "httputil.prefer-bind"); len(got) == 0 {
t.Fatal("httputil.prefer-bind did not fire on chi.URLParam")
}
}
func TestPreferBindFiresOnURLQuery(t *testing.T) {
if got := findingsFor(Run(urlQuerySnippet), "httputil.prefer-bind"); len(got) == 0 {
t.Fatal("httputil.prefer-bind did not fire on r.URL.Query()")
}
}
func TestPreferBindNoFalsePositiveOnBind(t *testing.T) {
if got := findingsFor(Run(boundHandlerSnippet), "httputil.prefer-bind"); len(got) != 0 {
t.Errorf("httputil.prefer-bind false-positived on a Bind handler: %+v", got)
}
}