Skip to content

Commit

Permalink
util: Add flagConfig function
Browse files Browse the repository at this point in the history
flagConfig() compares the command flags and the settings in the config
files.  The command defaults to using any value specified on the command
line regardless of the value in the config files.

The function must be called by all commands, and the code only
needs to verify the flag values and not the config values. For example, in
the current code it is necessary to check both the config and the flag
values:

	showComments, _ := cmd.Flags().GetBool("comments")
	if showComments == false {
		showComments = getMainConfig().GetBool(CommandPrefix + "comments")
	}

After a command calls this function, only the flags need to be checked

	showComments, _ := cmd.Flags().GetBool("comments")

Add flagConfig function to compare command line flags and the values
in the config files.

Signed-off-by: Prarit Bhargava <[email protected]>
  • Loading branch information
prarit committed Sep 24, 2020
1 parent fea5044 commit 47de8c5
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 17 deletions.
2 changes: 0 additions & 2 deletions cmd/issue_show.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ var issueShowCmd = &cobra.Command{
Long: ``,
Run: func(cmd *cobra.Command, args []string) {

setCommandPrefix()

rn, issueNum, err := parseArgs(args)
if err != nil {
log.Fatal(err)
Expand Down
2 changes: 0 additions & 2 deletions cmd/mr_show.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ var mrShowCmd = &cobra.Command{
Long: ``,
Run: func(cmd *cobra.Command, args []string) {

setCommandPrefix()

rn, mrNum, err := parseArgs(args)
if err != nil {
log.Fatal(err)
Expand Down
27 changes: 27 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,29 @@ func parseArgsRemoteRef(args []string) (string, string, error) {
return rn, name, nil
}

// setCommandPrefix returns a concatenated value of some of the commandline.
// For example, 'lab mr show' would return 'mr_show.', and 'lab issue list'
// would return 'issue_list.'
func setCommandPrefix(scmd *cobra.Command) {
for _, command := range RootCmd.Commands() {
if CommandPrefix != "" {
break
}
commandName := strings.Split(command.Use, " ")[0]
if scmd == command {
CommandPrefix = commandName + "."
break
}
for _, subcommand := range command.Commands() {
subCommandName := commandName + "_" + strings.Split(subcommand.Use, " ")[0]
if scmd == subcommand {
CommandPrefix = subCommandName + "."
break
}
}
}
}

var (
// Will be updated to upstream in Execute() if "upstream" remote exists
forkedFromRemote = "origin"
Expand Down Expand Up @@ -315,6 +338,10 @@ func Execute() {
}
}

// Set CommandPrefix
scmd, _, _ := cmd.Find(os.Args)
setCommandPrefix(scmd)

if err := RootCmd.Execute(); err != nil {
// Execute has already logged the error
os.Exit(1)
Expand Down
58 changes: 45 additions & 13 deletions cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
package cmd

import (
"path"
"runtime"
"log"
"strconv"
"strings"

flag "github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/zaquestion/lab/internal/config"
)
Expand All @@ -14,23 +15,54 @@ var (
CommandPrefix string
)

// flagConfig compares command line flags and the flags set in the config
// files. The command line value will always override any value set in the
// config files.
func flagConfig(fs *flag.FlagSet) {
fs.VisitAll(func(f *flag.Flag) {
var (
configValue interface{}
configString string
)

switch f.Value.Type() {
case "bool":
configValue = getMainConfig().GetBool(CommandPrefix + f.Name)
configString = strconv.FormatBool(configValue.(bool))
case "string":
configValue = getMainConfig().GetString(CommandPrefix + f.Name)
configString = configValue.(string)
case "stringSlice":
configValue = getMainConfig().GetStringSlice(CommandPrefix + f.Name)
configString = strings.Join(configValue.([]string), " ")

case "int":
configValue = getMainConfig().GetInt64(CommandPrefix + f.Name)
configString = strconv.FormatInt(configValue.(int64), 10)
case "stringArray":
// viper does not have support for stringArray
configString = ""
default:
log.Fatal("ERROR: found unidentified flag: ", f.Value.Type(), f)
}

// if set, always use the command line option (flag) value
if f.Value.String() != f.DefValue {
return
}
// o/w use the value in the configfile
if configString != "" && configString != f.DefValue {
f.Value.Set(configString)
}
})
}

// getMainConfig returns the merged config of ~/.config/lab/lab.toml and
// .git/lab/lab.toml
func getMainConfig() *viper.Viper {
return config.MainConfig
}

// setCommandPrefix sets command name that is used in the config
// files to set per-command options. For example, the "lab issue show"
// command has a prefix of "issue_show.", and "lab mr list" as a
// prefix of "mr_list."
func setCommandPrefix() {
_, file, _, _ := runtime.Caller(1)
_, filename := path.Split(file)
s := strings.Split(filename, ".")
CommandPrefix = s[0] + "."
}

// textToMarkdown converts text with markdown friendly line breaks
// See https://gist.github.com/shaunlebron/746476e6e7a4d698b373 for more info.
func textToMarkdown(text string) string {
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -346,4 +346,6 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

0 comments on commit 47de8c5

Please sign in to comment.