github.com/tooploox/oya@v0.0.21-0.20230524103240-1cda1861aad6/cmd/root.go (about) 1 // Copyright © 2018 Marcin Bilski 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package cmd 22 23 import ( 24 "fmt" 25 "io" 26 "os" 27 28 homedir "github.com/mitchellh/go-homedir" 29 "github.com/spf13/cobra" 30 "github.com/spf13/pflag" 31 "github.com/spf13/viper" 32 "github.com/tooploox/oya/cmd/internal" 33 ) 34 35 var cfgFile string 36 37 // rootCmd represents the base command when called without any subcommands 38 var rootCmd = &cobra.Command{ 39 Use: "oya", 40 Short: "Oya is a task manager and runner", 41 Long: `Oya takes the pain out of bootstrapping new deployable 42 projects with packaged boilerplate & scripts.`, 43 SilenceErrors: true, 44 SilenceUsage: true, 45 } 46 47 // Execute adds all child commands to the root command and sets flags appropriately. 48 // This is called by main.main(). It only needs to happen once to the rootCmd. 49 func Execute() { 50 if exitCode, err := ExecuteE(); err != nil { 51 os.Exit(exitCode) 52 } 53 } 54 55 func SetOyaVersion(ver string) { 56 rootCmd.Version = ver 57 } 58 59 // ExecuteE executes a command same as Execute but returns error. 60 func ExecuteE() (int, error) { 61 _, err := rootCmd.ExecuteC() 62 if err != nil { 63 return internal.HandleError(rootCmd.OutOrStderr(), err), err 64 } 65 return 0, nil 66 } 67 68 // SetOutput overrides cobra output (for testing). 69 func SetOutput(out io.Writer) { 70 rootCmd.SetOutput(out) 71 } 72 73 // Reset all flags for all commands to their default values (testing). 74 func ResetFlags() { 75 resetFlagsRecurse(rootCmd) 76 } 77 78 func resetFlagsRecurse(cmd *cobra.Command) { 79 cmd.Flags().VisitAll( 80 func(flag *pflag.Flag) { 81 if flag.DefValue == "[]" { 82 // BUG(bilus): I don't know how to set default value for StringArray flag type. 83 flag.Value.Set("") 84 85 } else { 86 flag.Value.Set(flag.DefValue) 87 } 88 89 }) 90 for _, child := range cmd.Commands() { 91 resetFlagsRecurse(child) 92 } 93 } 94 95 func init() { 96 cobra.OnInitialize(initConfig) 97 98 // Here you will define your flags and configuration settings. 99 // Cobra supports persistent flags, which, if defined here, 100 // will be global for your application. 101 // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.oya.yaml)") 102 } 103 104 // initConfig reads in config file and ENV variables if set. 105 func initConfig() { 106 if cfgFile != "" { 107 // Use config file from the flag. 108 viper.SetConfigFile(cfgFile) 109 } else { 110 // Find home directory. 111 home, err := homedir.Dir() 112 if err != nil { 113 fmt.Println(err) 114 os.Exit(1) 115 } 116 117 // Search config in home directory with name ".oya" (without extension). 118 viper.AddConfigPath(home) 119 viper.SetConfigName(".oya") 120 } 121 122 viper.AutomaticEnv() // read in environment variables that match 123 124 // If a config file is found, read it in. 125 if err := viper.ReadInConfig(); err == nil { 126 fmt.Println("Using config file:", viper.ConfigFileUsed()) 127 } 128 }