Dynamically registering command in Cobra

365 Views Asked by At

is there a way of dynamically registering cobra commands based on a viper configuration file? Basically I want to only register commands that are available within my config file as "modules".

My root.go's init function looks like this

func init() {
    cobra.OnInitialize(initConfig)

    //don't I have access to viper.GetString("foo") here? It returns empty string instead of "bar"
    registerCommandsPalette()

    //disable help command
    rootCmd.SetHelpCommand(&cobra.Command{
        Use:    "no-help",
        Hidden: true,
    })
    //disable completion command
    rootCmd.CompletionOptions.DisableDefaultCmd = true

    rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.toolbox.yaml)")
}

func registerCommandsPalette() {
    //here I want to access the config e.g. viper.GetString("foo")
    //on various conditions I want to add a command to rootCmd.
    
    rootCmd.AddCommand(server.ServerCmd)
    rootCmd.AddCommand(net.NetCmd)
}

func initConfig() {
    if cfgFile != "" {
        // Use config file from the flag.
        viper.SetConfigFile(cfgFile)
    } else {
        // Find home directory.
        home, err := os.UserHomeDir()
        cobra.CheckErr(err)

        // Search config in home directory with name ".toolbox" (without extension).
        viper.AddConfigPath(home)
        viper.SetConfigType("json")
        viper.SetConfigName(".toolbox")
    }

    viper.AutomaticEnv() // read in environment variables that match

    // If a config file is found, read it in.
    if err := viper.ReadInConfig(); err != nil {
        fmt.Println("Could not load configuration file")
        os.Exit(1)
    }
}

My config file looks like this:

{
  "available_modules": [
    "module-1",
    "module-2"
  ],
  "foo": "bar"
  //....
}

Whenever I use viper.GetString("foo") in a command file, I do get the string "bar" back. Do you have any ideas?

Best, Jakob

0

There are 0 best solutions below