Skip to content

v0.7.0

Choose a tag to compare

@floatdrop floatdrop released this 05 Sep 15:14
· 28 commits to main since this release
1b91630

The API surface cut down ahead of the graph-validation work of #3, so that it lands on a smaller and more regular API, plus the four defects of the fourth September 2026 review.

This release breaks callers. Nine identifiers are gone and one is renamed; go doc -all diffed against 0.6.0 lists exactly those and one addition, Binding.Group. Every one has a one-line migration:

0.6.0 0.7.0
.Named("x"), s.Lookup(di.Named[T]("x")), Key, di.Named a distinct type: type ReplicaDB struct{ *DB }
Binding.Run(f) Binding.Worker(f)
s.Add(ctor) s.Provide(ctor).Group()
s.Bind[Reader, *Repo]() s.Provide(func(s *di.Scope) Reader { return s.Get[*Repo]() }), .Scoped() too when the target is
.Transient() a factory closure, or call the constructor
.Health(f), HealthCheck, ErrUnhealthy, EventHealth a Group of checkers; the README's Groups section is the recipe
app.Middleware(mux) dihttp.Middleware(app)(mux), from the new dihttp package
di.Signals(...) none; Run exits on os.Interrupt and SIGTERM
di.SlogObserver(l) four lines in user code

Why these: Named was the one stringly-typed corner, and a newtype is checked at every reference where a misspelt name was a missing key at runtime. Bind carried the most machinery per use in the library, and a constructor that returns the implementation is checked by the compiler where Bind checked Implements at registration. Transient had no hooks and no tracking, a lifetime in name only, and every teardown oracle carried an exemption for it; the singleton-stability invariant now has none. Health checks are an application concern that a group expresses in three lines. The core package no longer imports net/http or log/slog, and registers nothing on a caller's behalf.

The rest is correctness, from the fourth review. Scope.Run reports a cause published through Shutdown while a failed Start was rolling back, not only during an ordinary stop. A Stop reports the failure of a drain hook of its own scope even when an ancestor's Stop ran the hook, which is the request-scope-during-shutdown case. And a key can no longer be overridden while a resolution of it is in flight, which closed a path to two live values for one key from a single goroutine.

Testing: drain hooks can fail in the drivers, the machines drive Scope.Run, and two registration shapes have constructors that register. Generator coverage went from 82.5% to 90.2%, and CI now fails below 85%. The coverage-gap script itself turned out to be wrong, merging blocks that shared a line, and CI now checks its arithmetic against go tool cover.

Full notes with the reasoning behind each cut are in CHANGELOG.md.