Skip to content

v0.19 β†’ v0.20: deprecated setup middleware helpers removed

Two // Deprecated: middleware helpers in pkg/setup β€” deprecated since the composed setup.Command type landed in v0.5 β€” are removed:

  • setup.AddCommandWithMiddleware(parent, child, feature)
  • setup.ApplyMiddlewareRecursively(cmd, feature)

Both are superseded by the composed setup.Command wrapper, whose Register method wires global and feature-specific middleware onto each child's RunE exactly once at attach time.

What changed

// Before (removed)
setup.AddCommandWithMiddleware(rootCmd, serve.NewCmdServe(p), props.ServeCmd)

// After
parent := setup.Wrap("", rootCmd)
parent.Register(setup.Wrap(props.ServeCmd, serve.NewCmdServe(p)))

In practice, GTB command constructors already return *setup.Command carrying their own feature key, so a parent simply does:

parent.Register(serve.NewCmdServe(p)) // child is already a *setup.Command

Register attaches each child and wraps it with its own feature. Unlike the removed ApplyMiddlewareRecursively, it does not re-wrap a subtree with the parent's feature β€” each command carries the middleware key it was constructed with, and its descendants are wired when it registers them.

Impact

  • Direct callers (build break): code calling either helper no longer compiles. Replace AddCommandWithMiddleware(parent, child, feature) with parent.Register(setup.Wrap(feature, child)). Code relying on ApplyMiddlewareRecursively should instead wrap each command with its own feature at construction (via setup.Wrap) and attach it through parent.Register.
  • Generated tools: none. The generator stopped emitting AddCommandWithMiddleware when the composed setup.Command type landed; it has emitted parent.Register(...) (and the variadic NewCmdRoot(p, subs…) form) ever since, and never emitted ApplyMiddlewareRecursively. Regenerating an older project moves any residual call to Register.
  • regenerate manifest / remove command: the scanner and removal passes no longer recognise the legacy AddCommandWithMiddleware call form. Projects whose cmd.go still contains it should run gtb regenerate project (or migrate the call by hand) so registrations are expressed via Register before relying on manifest round-tripping.

How to migrate

  1. Replace every setup.AddCommandWithMiddleware(parent, child, feature) with setup.Wrap("", parent).Register(setup.Wrap(feature, child)) β€” or, preferably, make the child constructor return *setup.Command and call parent.Register(child).
  2. Replace any setup.ApplyMiddlewareRecursively(cmd, feature) usage by wrapping each command with its own feature at construction and registering subcommands via parent.Register.
  3. Regenerate scaffolded projects with gtb regenerate project so any remaining legacy registrations are rewritten to Register.