Attach the commands to a CLI¶
This guide shows how a host binary wires the sign and keys command builders
onto its root command — first for a plain Cobra
CLI, then for a go-tool-base tool.
Both paths are real and compilable.
Every constructor returns a plain *cobra.Command and takes one
signingcli.Logger. You do not need an adapter:
a *slog.Logger and go-tool-base's logger.Logger both satisfy the interface
structurally.
Attaching the commands does not compile in any signing backend — that is a separate, deliberate step. See Compile in signing backends.
Plain Cobra root (e.g. sigillum)¶
Add the module and attach the two top-level builders directly. NewCmdKeys
returns the keys parent with mint, generate, and wkd already attached, so
one AddCommand brings the whole group.
package main
import (
"log/slog"
"os"
"github.com/spf13/cobra"
signingcli "gitlab.com/phpboyscout/go/signing-cli"
// Compile in the backends this binary should offer (see the
// companion how-to). Without at least one, `--backend` has no
// valid value.
_ "gitlab.com/phpboyscout/go/signing-aws-kms" // registers "aws-kms"
_ "gitlab.com/phpboyscout/go/signing/local" // registers "local"
)
func main() {
log := slog.New(slog.NewTextHandler(os.Stderr, nil))
root := &cobra.Command{Use: "sigillum"}
root.AddCommand(
signingcli.NewCmdSign(log), // sign <input-file>
signingcli.NewCmdKeys(log), // keys (mint | generate | wkd)
)
if err := root.Execute(); err != nil {
os.Exit(1)
}
}
That is the entire integration. sigillum sign …, sigillum keys mint …,
sigillum keys generate …, and sigillum keys wkd … all work.
Attaching a single subcommand¶
If you want only part of the group — say keys mint under your own parent — the
subcommand builders are exported too:
myKeys := &cobra.Command{Use: "keys"}
myKeys.AddCommand(
signingcli.NewCmdKeysMint(log),
signingcli.NewCmdKeysGenerate(log),
signingcli.NewCmdKeysWKD(log),
)
root.AddCommand(myKeys)
NewCmdKeys(log) is just the convenience that does exactly this.
go-tool-base root (gtb and scaffolded tools)¶
go-tool-base registers subcommands through setup.Wrap, which pairs a command
with the GTB feature it belongs to (an empty feature string means "always on,
not gated by a feature flag"). Pass the framework logger straight in via
p.GetLogger():
import (
"gitlab.com/phpboyscout/go-tool-base/pkg/cmd/root"
"gitlab.com/phpboyscout/go-tool-base/pkg/setup"
signingcli "gitlab.com/phpboyscout/go/signing-cli"
)
rootCmd := root.NewCmdRoot(p,
// … other subcommands …
setup.Wrap("", signingcli.NewCmdKeys(p.GetLogger())),
setup.Wrap("", signingcli.NewCmdSign(p.GetLogger())),
)
p is the GTB *props.Props; p.GetLogger() returns a logger.Logger, which
satisfies signingcli.Logger directly. This is exactly how the shipped gtb
binary wires the commands (internal/cmd/root/root.go).
As with the plain-Cobra path, the backends must still be blank-imported in the
binary's main package. In gtb those live in a single on/off file,
cmd/gtb/signing.go — see Compile in signing backends.
Verify the wiring¶
your-tool sign --help # shows --backend, --key-id, --public-key, …
your-tool keys --help # lists mint, generate, wkd
your-tool keys mint --help # --backend's help lists the compiled-in backends
If --backend lists no backends, you have attached the commands but not
compiled any backend in.
See also¶
- Compile in signing backends — make
--backend aws-kms/--backend localactually resolve. - The Logger seam — why
p.GetLogger()andslog.New(...)both just work. signandkeys— the flag reference for each command.