Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make subcommand required in Go CLI using cobra

I am using Cobra to make some cli updated to my app. I want to make this command required, meaning the application should fail if it doesn't find the argument it is looking for.

package commands

import (
    "github.com/spf13/cobra"
    "errors"
    "fmt"
)

var (
    Env string
)

var RootCmd = &cobra.Command{
    Use:   "myapp",
    Short: "tool",
    Long:  `tool`,
    Run: func(cmd *cobra.Command, args []string)  {
        // Root command does nothing
    },
}

func init() {
    RootCmd.AddCommand(Environment)
}

var Environment = &cobra.Command{
    Use:   "env",
    Short: "Specify Environment to run against",
    Long: `Can be dev or prod`,
    Args: func(cmd *cobra.Command, args []string) error {
        if len(args) != 1 {
            return errors.New("requires at least one arg")
        }

        if args[0] == "dev" || args[0] == "prod" {
            return nil
        }else {
            return errors.New("input can only be dev or prod")
        }
        return fmt.Errorf("invalid env specified: %s", args[0])
    },
    PreRunE: func(cmd *cobra.Command, args []string) error {
        if len(args) != 1 {
          return fmt.Errorf("env is required")
        }
      return nil
    },
    Run: func(cmd *cobra.Command, args []string) {
        Env = args[0]
    },
}

and main package is

package main

import (
    "fmt"
    "log"
    "os"
    "util"
    "commands"
)

func main() {
    log.Println("Executing")

    if err := commands.RootCmd.Execute(); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    log.Println("Executing")
}

Now if I run this as ./myApp without any env, it doesn't complain about it. However if I use env after myapp then it activates the function and runs all the validations.

like image 331
wayfare Avatar asked Feb 13 '26 08:02

wayfare


1 Answers

Omitting the Run (and RunE) field from the cobra.Command will make it a requirement for a valid subcommand to be given:

var RootCmd = &cobra.Command{
    Use:   "myapp",
    Short: "tool",
    Long:  `tool long help...`,
}

If no subcommand is given on the command line, Cobra will print out the command's Help() text , which will include the root command's Long help text and the autogenerated usage help for all subcommands.

like image 91
hampercm Avatar answered Feb 15 '26 17:02

hampercm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!