Declare features and resolve a set¶
Declare at init¶
A package that owns a feature declares it on the default registry from init, so a blank
import is all a consumer needs:
Registry.Declare returns an error for a nil or incomplete descriptor (no ID, no kind) or a
duplicate ID; MustDeclare panics on it, which at init is the right thing. Any further
rule (go-tool-base refuses a plugin that defaults on) is the consumer's, applied before
Declare.
Contribute under a slot¶
const SlotCheck features.Slot = "check"
features.Default().Contribute("reports", SlotCheck, checkReportsStorage)
features.Default().Contribute(features.Global, SlotMiddleware, logging)
A contribution is a value under a feature ID and a slot name. features.Global is the ID
for a contribution that applies to every feature. A contribution for an ID nobody has
declared is kept, since declaration and contribution may come from different packages in
either init order; a Set only hands out the contributions of enabled (hence declared)
features.
Order¶
A snapshot's order is derived from data, never from init sequencing (Go orders init by
dependency then filename, which moves with the import graph): descriptors that implement
Ranked first, by rank, then the rest by kind and ID. Implement Rank() (int, bool) on
your descriptor to pin an order for your own features and return false for the rest.
Resolve¶
The default Resolver applies every descriptor's DefaultOn, then the states in order.
Enabling an ID the snapshot does not hold is ErrUnknownFeature; disabling one is ignored
and listed by set.Ignored(). Supply your own Resolver for another precedence (an
environment overlay, say): Resolve is DefaultResolver().Resolve.
Read¶
set.Enabled(id)for a gate.set.Descriptors()andset.EnabledDescriptors()for an inventory, in snapshot order.set.Contributions(id, slot)for what an enabled feature brings;features.ContributionsOf[T](set, id, slot)for the typed read, which returns the well-typed values and an error naming the feature and slot for any that are not.
A snapshot is the same surface without the enabled gate: snapshot.Contributions hands out
everything declared, and snapshot.Contributed() lists every ID carrying a contribution.