From a7585cf909cda353ed14559eed0e2ace38f2f0d7 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Thu, 11 Apr 2019 17:37:58 +0900 Subject: [PATCH] Update for coloring. --- common/colorable_output.go | 3 ++ common/config.go | 82 +++++++++++++++++++++--------------- common/config_test.go | 3 +- group/group_cmd.go | 14 +++--- list/list_cmd.go | 22 +++++----- repository/repository_cmd.go | 26 ++++++------ status/status_cmd.go | 6 +-- 7 files changed, 88 insertions(+), 68 deletions(-) diff --git a/common/colorable_output.go b/common/colorable_output.go index 7369935..f6492af 100644 --- a/common/colorable_output.go +++ b/common/colorable_output.go @@ -9,6 +9,9 @@ import ( type colorSettings map[string]string type colorFuncs map[string](func(r string) string) +/* +Color struct shows the color settings of RRH. +*/ type Color struct { settings colorSettings funcs colorFuncs diff --git a/common/config.go b/common/config.go index 03e3ae4..e981c4e 100644 --- a/common/config.go +++ b/common/config.go @@ -76,7 +76,10 @@ const ( /* Config shows the values of configuration variables. */ -type Config map[string]string +type Config struct { + values map[string]string + Color *Color +} /* ReadFrom shows the value of config load from. @@ -85,18 +88,21 @@ The available values are default, config_file, environment, and not found. type ReadFrom string var defaultValues = Config{ - RrhAutoCreateGroup: "false", - RrhAutoDeleteGroup: "false", - RrhCloneDestination: ".", - RrhColor: "repository:fg=red+group:fg=magenta+label:op=bold+boolTrue:fg=green+boolFalse:fg=blue", - RrhConfigPath: "${RRH_HOME}/config.json", - RrhDatabasePath: "${RRH_HOME}/database.json", - RrhDefaultGroupName: "no-group", - RrhEnableColorized: "true", - RrhHome: "${HOME}/.rrh", - RrhOnError: Warn, - RrhSortOnUpdating: "false", - RrhTimeFormat: Relative, + values: map[string]string{ + RrhAutoCreateGroup: "false", + RrhAutoDeleteGroup: "false", + RrhCloneDestination: ".", + RrhColor: "repository:fg=red+group:fg=magenta+label:op=bold+boolTrue:fg=green+boolFalse:fg=blue", + RrhConfigPath: "${RRH_HOME}/config.json", + RrhDatabasePath: "${RRH_HOME}/database.json", + RrhDefaultGroupName: "no-group", + RrhEnableColorized: "true", + RrhHome: "${HOME}/.rrh", + RrhOnError: Warn, + RrhSortOnUpdating: "false", + RrhTimeFormat: Relative, + }, + Color: &Color{}, } func (config *Config) isOnErrorIgnoreOrWarn() bool { @@ -153,7 +159,7 @@ func (config *Config) Unset(label string) error { if !contains(availableLabels, label) { return fmt.Errorf("%s: unknown variable name", label) } - delete((*config), label) + delete(config.values, label) return nil } @@ -170,7 +176,7 @@ func validateArgumentsOnUpdate(label string, value string) error { func (config *Config) updateBoolValue(label string, value string) error { var flag, err = trueOrFalse(value) if err == nil { - (*config)[label] = string(flag) + config.values[label] = string(flag) } return err } @@ -192,7 +198,7 @@ func (config *Config) Update(label string, value string) error { } value = newValue } - (*config)[label] = value + config.values[label] = value return nil } @@ -202,7 +208,7 @@ If the label is not RrhAutoCreateGroup, RrhAutoDeleteGroup, and RrhSortOnUpdatin */ func (config *Config) IsSet(label string) bool { if contains(boolLabels, label) { - return strings.ToLower((*config)[label]) == trueString + return strings.ToLower(config.values[label]) == trueString } return false } @@ -234,7 +240,7 @@ func (config *Config) GetString(label string) (string, ReadFrom) { if !contains(availableLabels, label) { return "", NotFound } - var value, ok = (*config)[label] + var value, ok = config.values[label] if !ok { return config.getStringFromEnv(label) } @@ -262,17 +268,11 @@ func (config *Config) findDefaultValue(label string) (string, ReadFrom) { if !contains(availableLabels, label) { return "", NotFound } - var value = defaultValues[label] + var value = defaultValues.values[label] value = config.replaceHome(value) return value, Default } -func configPath() string { - var config = new(Config) - var configPath, _ = config.getStringFromEnv(RrhConfigPath) - return configPath -} - /* StoreConfig saves the store. */ @@ -282,31 +282,47 @@ func (config *Config) StoreConfig() error { if err1 != nil { return err1 } - var bytes, err2 = json.Marshal(*config) + var bytes, err2 = json.Marshal(config.values) if err2 == nil { return ioutil.WriteFile(configPath, bytes, 0644) } return err2 } +/* +NewConfig generates the new Config instance. +*/ +func NewConfig() *Config { + return &Config{values: map[string]string{}, Color: &Color{colorSettings{}, colorFuncs{}}} +} + /* OpenConfig reads the config file and returns it. The load path is based on `RrhConfigPath` of the environment variables. */ func OpenConfig() *Config { - bytes, err := ioutil.ReadFile(configPath()) + var config = NewConfig() + var configPath, _ = config.getStringFromEnv(RrhConfigPath) + bytes, err := ioutil.ReadFile(configPath) if err != nil { - return new(Config) + return config } - var config Config - if err := json.Unmarshal(bytes, &config); err != nil { + var values = map[string]string{} + if err := json.Unmarshal(bytes, &values); err != nil { return nil } - InitializeColor(&config) - return &config + config.values = values + config.Color = InitializeColor(config) + return config } func (config *Config) formatVariableAndValue(label string) string { var value, readFrom = config.GetString(label) - return fmt.Sprintf("%s: %s (%s)", label, value, readFrom) + if contains(boolLabels, label) { + return fmt.Sprintf("%s: %s (%s)", + config.Color.ColorizedLabel(label), + config.Color.ColorizedBool(value), readFrom) + } + return fmt.Sprintf("%s: %s (%s)", + config.Color.ColorizedLabel(label), value, readFrom) } diff --git a/common/config_test.go b/common/config_test.go index 012b5e4..b908941 100644 --- a/common/config_test.go +++ b/common/config_test.go @@ -334,7 +334,7 @@ func TestPrintErrors(t *testing.T) { {FailImmediately, []error{errors.New("error")}, 5, true}, } - var config = Config{} + var config = NewConfig() for _, tc := range testcases { config.Update(RrhOnError, tc.onError) var output = CaptureStdout(func() { @@ -351,6 +351,7 @@ func TestPrintErrors(t *testing.T) { } func TestFormatVariableAndValue(t *testing.T) { + os.Setenv(RrhConfigPath, "../testdata/config.json") var config = OpenConfig() assert(t, config.formatVariableAndValue(RrhDefaultGroupName), "RRH_DEFAULT_GROUP_NAME: no-group (default)") } diff --git a/group/group_cmd.go b/group/group_cmd.go index 511f524..4b56bfc 100644 --- a/group/group_cmd.go +++ b/group/group_cmd.go @@ -240,15 +240,15 @@ func printRepositoryCount(count int) { } } -func findGroupName(name string, nameOnlyFlag bool) string { +func findGroupName(name string, nameOnlyFlag bool, config *common.Config) string { if nameOnlyFlag { return name } - return common.ColorizedGroupName(name) + return config.Color.ColorizedGroupName(name) } -func (glc *listCommand) printResult(result Result, options *listOptions) { - fmt.Print(findGroupName(result.Name, options.nameOnly)) +func (glc *listCommand) printResult(result Result, options *listOptions, config *common.Config) { + fmt.Print(findGroupName(result.Name, options.nameOnly, config)) if !options.nameOnly && options.desc { fmt.Printf(",%s", result.Description) } @@ -261,9 +261,9 @@ func (glc *listCommand) printResult(result Result, options *listOptions) { fmt.Println() } -func (glc *listCommand) printAll(results []Result, options *listOptions) { +func (glc *listCommand) printAll(results []Result, options *listOptions, config *common.Config) { for _, result := range results { - glc.printResult(result, options) + glc.printResult(result, options, config) } } @@ -282,7 +282,7 @@ func (glc *listCommand) Run(args []string) int { return 2 } var results = glc.listGroups(db, listOption) - glc.printAll(results, listOption) + glc.printAll(results, listOption, db.Config) return 0 } diff --git a/list/list_cmd.go b/list/list_cmd.go index 84a29a9..202336e 100644 --- a/list/list_cmd.go +++ b/list/list_cmd.go @@ -88,13 +88,13 @@ printColoriezdRepositoryID prints the repository name in color. Coloring escape sequence breaks the printf position arrangement. Therefore, we arranges the positions by spacing behind the colored repository name. */ -func printColoriezdRepositoryID(repoName string, length int) { +func printColoriezdRepositoryID(repoName string, length int, config *common.Config) { var formatter = fmt.Sprintf(" %%s%%%ds", length-len(repoName)) - fmt.Printf(formatter, common.ColorizedRepositoryID(repoName), "") + fmt.Printf(formatter, config.Color.ColorizedRepositoryID(repoName), "") } -func (options *options) printRepo(repo Repo, result Result, maxLength int) { - printColoriezdRepositoryID(repo.Name, maxLength) +func (options *options) printRepo(repo Repo, result Result, maxLength int, config *common.Config) { + printColoriezdRepositoryID(repo.Name, maxLength, config) if options.localPath || options.all { fmt.Printf(" %s", repo.Path) } @@ -111,17 +111,17 @@ func (options *options) isPrintSimple(result Result) bool { return !options.noOmit && result.OmitList && len(options.args) == 0 } -func printGroupName(result Result) int { +func printGroupName(result Result, config *common.Config) int { if len(result.Repos) == 1 { - fmt.Printf("%s (1 repository)\n", common.ColorizedGroupName(result.GroupName)) + fmt.Printf("%s (1 repository)\n", config.Color.ColorizedGroupName(result.GroupName)) } else { - fmt.Printf("%s (%d repositories)\n", common.ColorizedGroupName(result.GroupName), len(result.Repos)) + fmt.Printf("%s (%d repositories)\n", config.Color.ColorizedGroupName(result.GroupName), len(result.Repos)) } return len(result.Repos) } -func (options *options) printResult(result Result) int { - var repoCount = printGroupName(result) +func (options *options) printResult(result Result, config *common.Config) int { + var repoCount = printGroupName(result, config) if !options.isPrintSimple(result) { if options.description || options.all { fmt.Printf(" Description %s", result.Description) @@ -129,7 +129,7 @@ func (options *options) printResult(result Result) int { } var maxLength = findMaxLength(result.Repos) for _, repo := range result.Repos { - options.printRepo(repo, result, maxLength) + options.printRepo(repo, result, maxLength, config) } } return repoCount @@ -172,7 +172,7 @@ func (options *options) printResults(results []Result, config *common.Config) in } var repoCount int for _, result := range results { - repoCount += options.printResult(result) + repoCount += options.printResult(result, config) } printGroupAndRepoCount(len(results), repoCount) return 0 diff --git a/repository/repository_cmd.go b/repository/repository_cmd.go index 77504ac..1528b42 100644 --- a/repository/repository_cmd.go +++ b/repository/repository_cmd.go @@ -98,27 +98,27 @@ func (info *infoCommand) parseOptions(args []string) error { return nil } -func printInfo(result common.Repository, options *infoOptions) { - fmt.Printf("%-12s %s\n", common.ColorizedLabel("ID:"), common.ColorizedRepositoryID(result.ID)) - fmt.Printf("%-12s %s\n", common.ColorizedLabel("Description:"), result.Description) - fmt.Printf("%-12s %s\n", common.ColorizedLabel("Path:"), result.Path) +func (options *infoOptions) printInfo(result common.Repository, config *common.Config) { + fmt.Printf("%-12s %s\n", config.Color.ColorizedLabel("ID:"), config.Color.ColorizedRepositoryID(result.ID)) + fmt.Printf("%-12s %s\n", config.Color.ColorizedLabel("Description:"), result.Description) + fmt.Printf("%-12s %s\n", config.Color.ColorizedLabel("Path:"), result.Path) if len(result.Remotes) > 0 { - printRemoteInfo(result.Remotes) + printRemoteInfo(result.Remotes, config) } } -func printRemoteInfo(remotes []common.Remote) { - fmt.Printf("%-12s\n", common.ColorizedLabel("Remote:")) +func printRemoteInfo(remotes []common.Remote, config *common.Config) { + fmt.Printf("%-12s\n", config.Color.ColorizedLabel("Remote:")) for _, remote := range remotes { - fmt.Printf(" %s: %s\n", common.ColorizedLabel(remote.Name), remote.URL) + fmt.Printf(" %s: %s\n", config.Color.ColorizedLabel(remote.Name), remote.URL) } } -func printInfoResult(result common.Repository, options *infoOptions) { +func (options *infoOptions) printInfoResult(result common.Repository, config *common.Config) { if options.csv { - fmt.Printf("%s,%s,%s\n", common.ColorizedRepositoryID(result.ID), result.Description, result.Path) + fmt.Printf("%s,%s,%s\n", config.Color.ColorizedRepositoryID(result.ID), result.Description, result.Path) } else { - printInfo(result, options) + options.printInfo(result, config) } } @@ -126,7 +126,7 @@ func (info *infoCommand) perform(db *common.Database, args []string) int { var results, errs = findResults(db, args) var onError = db.Config.GetValue(common.RrhOnError) for _, result := range results { - printInfoResult(result, info.options) + info.options.printInfoResult(result, db.Config) } if len(errs) > 0 && onError != common.Ignore { return printErrors(db.Config, errs) @@ -146,7 +146,7 @@ func (info *infoCommand) Run(args []string) int { fmt.Println(err2.Error()) return 2 } - common.SetColorize(info.options.color || !info.options.noColor) + config.Color.SetColorize(info.options.color || !info.options.noColor) return info.perform(db, info.options.args) } diff --git a/status/status_cmd.go b/status/status_cmd.go index 9902157..f424296 100644 --- a/status/status_cmd.go +++ b/status/status_cmd.go @@ -99,15 +99,15 @@ func (status *Command) printResultInCsv(results []result, config *common.Config) func (status *Command) printResult(results []result, config *common.Config) { var groupName = results[0].relation.gname var repositoryName = results[0].relation.rname - fmt.Printf("%s\n %s\n", common.ColorizedGroupName(groupName), common.ColorizedRepositoryID(repositoryName)) + fmt.Printf("%s\n %s\n", config.Color.ColorizedGroupName(groupName), config.Color.ColorizedRepositoryID(repositoryName)) var fmtString = status.parseFmtString(results) for _, result := range results { if groupName != result.relation.gname { - fmt.Println(common.ColorizedGroupName(result.relation.gname)) + fmt.Println(config.Color.ColorizedGroupName(result.relation.gname)) groupName = result.relation.gname } if repositoryName != result.relation.rname { - fmt.Printf(" %s\n", common.ColorizedRepositoryID(result.relation.rname)) + fmt.Printf(" %s\n", config.Color.ColorizedRepositoryID(result.relation.rname)) repositoryName = result.relation.rname } var time = ""