gitlink-cli/shortcuts/common/runner.go

95 lines
2.1 KiB
Go

package common
import (
"fmt"
"os"
"strconv"
"github.com/spf13/cobra"
)
// MountShortcut converts a Shortcut into a cobra.Command and adds it as a subcommand.
func MountShortcut(parent *cobra.Command, s *Shortcut) {
cmd := &cobra.Command{
Use: "+" + s.Name,
Short: s.Description,
RunE: func(cmd *cobra.Command, args []string) error {
// Collect flag values
flagValues := make(map[string]string)
for _, f := range s.Flags {
if f.Bool {
val, _ := cmd.Flags().GetBool(f.Name)
flagValues[f.Name] = strconv.FormatBool(val)
continue
}
val, _ := cmd.Flags().GetString(f.Name)
if val != "" {
flagValues[f.Name] = val
}
}
commandName := parent.Use + " +" + s.Name
ctx, err := NewRuntimeContext(flagValues, commandName)
if err != nil {
return err
}
// Dry-run interception
if s.DryRun {
if dryRunVal, _ := cmd.Flags().GetBool("dry-run"); dryRunVal {
flagValues["dry-run"] = "true"
if s.DryRunHint != nil {
hint, err := s.DryRunHint(ctx)
if err != nil {
return err
}
fmt.Fprintf(os.Stderr, "[dry-run] %s\n", hint)
}
proceed, err := ConfirmAction(ctx)
if err != nil {
return err
}
if !proceed {
return nil
}
}
}
return s.Run(ctx)
},
}
for _, f := range s.Flags {
usage := f.Usage
if f.Required {
usage = usage + " [required]"
}
if f.Bool {
defaultValue, _ := strconv.ParseBool(f.Default)
if f.Short != "" {
cmd.Flags().BoolP(f.Name, f.Short, defaultValue, usage)
} else {
cmd.Flags().Bool(f.Name, defaultValue, usage)
}
} else if f.Short != "" {
cmd.Flags().StringP(f.Name, f.Short, f.Default, usage)
} else {
cmd.Flags().String(f.Name, f.Default, usage)
}
}
// Auto-register --dry-run flag for shortcuts that support it
if s.DryRun {
cmd.Flags().Bool("dry-run", false, "Preview the operation without executing")
}
parent.AddCommand(cmd)
}
// MountShortcuts mounts multiple shortcuts under a parent command.
func MountShortcuts(parent *cobra.Command, shortcuts []*Shortcut) {
for _, s := range shortcuts {
MountShortcut(parent, s)
}
}