github.com/gfleury/gobbs@v0.0.0-20200831213239-44ca2b94c1a1/cmd/root.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/gfleury/gobbs/common" 8 "github.com/gfleury/gobbs/common/log" 9 "github.com/gfleury/gobbs/pullrequests" 10 "github.com/gfleury/gobbs/repos" 11 "github.com/gfleury/gobbs/search" 12 "github.com/gfleury/gobbs/users" 13 14 homedir "github.com/mitchellh/go-homedir" 15 "github.com/spf13/cobra" 16 "github.com/spf13/viper" 17 ) 18 19 var ( 20 cfgFile string 21 verbosity int 22 stashInfo common.StashInfo 23 storePWDGoPass bool 24 ) 25 var rootCmd = &cobra.Command{Use: common.AppName} 26 27 func init() { 28 cobra.OnInitialize(initConfig) 29 30 rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gobbs.yaml)") 31 rootCmd.PersistentFlags().IntVarP(stashInfo.Timeout(), "timeout", "t", 30, "timeout for api requests") 32 rootCmd.PersistentFlags().IntVarP(&verbosity, "verbose", "v", 1, "Increase verbosity for debugging") 33 34 rootCmd.PersistentFlags().StringVarP(stashInfo.Host(), "host", "H", *stashInfo.Host(), "Stash host (https://stash.example.com)") 35 rootCmd.PersistentFlags().StringVarP(stashInfo.Project(), "project", "P", *stashInfo.Project(), "Stash project slug (PRJ)") 36 rootCmd.PersistentFlags().StringVarP(stashInfo.Repo(), "repository", "r", *stashInfo.Repo(), "Stash repository slug (repo01)") 37 38 rootCmd.PersistentFlags().BoolVarP(&storePWDGoPass, "gopass", "g", false, "Enable password to be stored with gopass (gopass must be installed, https://www.gopass.pw/)") 39 rootCmd.PersistentFlags().StringVarP(stashInfo.Credential().User(), "user", "u", *stashInfo.Credential().User(), "Stash username") 40 rootCmd.PersistentFlags().StringVarP(stashInfo.Credential().Passwd(), "passwd", "p", *stashInfo.Credential().Passwd(), "Stash username password") 41 42 rootCmd.AddCommand(pullrequests.PullRequestRoot) 43 rootCmd.AddCommand(repos.ReposRoot) 44 rootCmd.AddCommand(users.UserRoot) 45 rootCmd.AddCommand(search.Search) 46 } 47 48 func initConfig() { 49 os.Setenv("GOBBS_DEBUG", fmt.Sprintf("%d", verbosity)) 50 log.IncreaseLogLevel(verbosity) 51 52 common.SetConfig(viper.NewWithOptions(viper.KeyDelimiter("::"))) 53 54 common.Config().SetEnvPrefix("GOBBS") 55 common.Config().AutomaticEnv() 56 57 if cfgFile == "" { 58 cfgFile = common.Config().GetString("config") 59 } 60 61 if *stashInfo.Host() == "" { 62 stashInfo.SetHost(common.Config().GetString("host")) 63 } 64 if *stashInfo.Credential().User() == "" { 65 stashInfo.Credential().SetUser(common.Config().GetString("user")) 66 } 67 if *stashInfo.Credential().Passwd() == "" { 68 stashInfo.Credential().SetPasswd(common.Config().GetString("passwd")) 69 } 70 71 if cfgFile != "" { 72 // Use config file from the flag. 73 common.Config().SetConfigFile(cfgFile) 74 } else { 75 // Find home directory. 76 home, err := homedir.Dir() 77 if err != nil { 78 log.Fatal(err.Error()) 79 } 80 81 // Search config in home directory with name ".gobbs" (without extension). 82 common.Config().AddConfigPath(home) 83 common.Config().SetConfigName(fmt.Sprintf(".%s", common.AppName)) 84 cfgFile = fmt.Sprintf("%s/.%s.yaml", home, common.AppName) 85 } 86 87 if err := common.Config().ReadInConfig(); err == nil { 88 log.Debugf("Using config file:", common.Config().ConfigFileUsed()) 89 } else { 90 log.Debugf("Config file not found, creating empty file:", cfgFile) 91 file, err := os.Create(cfgFile) 92 if err != nil { 93 log.Fatal(err.Error()) 94 } 95 file.Close() 96 } 97 } 98 99 func persistConfig() error { 100 // common.Config() is only initialized if rootCmd ran (false if only help mode was shown) 101 if common.Config() != nil { 102 err := common.Config().BindPFlag(fmt.Sprintf(common.UserNameKey, *stashInfo.Host()), rootCmd.PersistentFlags().Lookup("user")) 103 if err != nil { 104 return err 105 } 106 if common.Config().GetString("password_method") == "" && !storePWDGoPass && stashInfo.Credential().IsNew() { 107 err = common.Config().BindPFlag(fmt.Sprintf(common.PasswdKey, *stashInfo.Host()), rootCmd.PersistentFlags().Lookup("passwd")) 108 if err != nil { 109 return err 110 } 111 } else if (storePWDGoPass || common.Config().GetString("password_method") == "gopass") && stashInfo.Credential().IsNew() { 112 err = common.SavePasswdExternal(*stashInfo.Host(), rootCmd.PersistentFlags().Lookup("passwd").Value.String()) 113 if err != nil { 114 return err 115 } 116 } 117 if storePWDGoPass { 118 common.Config().Set("password_method", "gopass") 119 } 120 err = common.Config().WriteConfig() 121 return err 122 } 123 return nil 124 } 125 126 func Execute() error { 127 ctx := common.APIClientContext(&stashInfo) 128 129 err := rootCmd.ExecuteContext(ctx) 130 if err != nil { 131 return err 132 } 133 134 return persistConfig() 135 }