// Package options holds the flags that every command has and reads // them back. package options import ( "fmt" "strconv" "github.com/spf13/cobra" "sneak.berlin/go/keyfunc/internal/mnemonic" ) // Add gives a command the flags that every command has. They are // persistent, so every command below it has them too. func Add(cmd *cobra.Command) { cmd.PersistentFlags().String( "mnemonic-command", "", "shell command whose output is the mnemonic", ) cmd.PersistentFlags().VarP( new(Decimal), "index", "n", "which key to derive", ) } // Index returns the key index the user asked for. func Index(cmd *cobra.Command) (uint32, error) { index, err := cmd.Flags().GetUint32("index") if err != nil { return 0, fmt.Errorf("reading the index: %w", err) } return index, nil } // Mnemonic returns the mnemonic, from the first source that has one. func Mnemonic(cmd *cobra.Command) (string, error) { command, err := cmd.Flags().GetString("mnemonic-command") if err != nil { return "", fmt.Errorf("reading the mnemonic command: %w", err) } return mnemonic.Read(cmd.Context(), command) } // Decimal is a flag value for a number written in decimal digits only. // The flag library's own uint32 flags read 010 as octal 8 and also // take 0x10 or 1_0. type Decimal uint32 // String returns the number in decimal digits. func (d *Decimal) String() string { return strconv.FormatUint(uint64(*d), 10) } // Set reads text as a decimal number that fits in 32 bits: a leading // zero is still decimal, and a base prefix, an underscore or a sign is // refused. func (d *Decimal) Set(text string) error { number, err := strconv.ParseUint(text, 10, 32) if err != nil { return err } *d = Decimal(number) return nil } // Type is what --help shows as the flag's type, and what GetUint32 // checks before it reads the value back. func (d *Decimal) Type() string { return "uint32" }