Skip to content

features

Feature gating and feature flags for Go tools, as values rather than process state. features is what a binary offers (declared at init into a Registry), what a tool has chosen (a Set, resolved once from an immutable Snapshot), and how a request asks (an Evaluator, static by default and dynamic over a Backend when a feature opts in).

go get gitlab.com/phpboyscout/go/features
// Declared at init by the package that owns the feature.
features.MustDeclare(features.Default(), reportsFeature{})

// Resolved once, when the tool builds itself.
set, err := features.Resolve(features.Default().Snapshot(), features.Apply(nil, features.Enable("reports")))

// Read everywhere something static is decided.
if set.Enabled("reports") { /* ... */ }

It is a library, not a command: no binary, no configuration file, no environment variable, no vendor SDK. A flag backend is an adapter module implementing Backend.

Start here

  • Getting started: ten minutes from an empty main to a tool that gates a command on a feature and evaluates a dynamic flag with a fallback.

Three questions, three roles

Why it is shaped this way

  • Snapshots, not seals: how a process-wide registry can be read safely by several roots without a seal that panics.
  • Static and dynamic: the rule that keeps --help deterministic offline, and where a dynamic answer is allowed.