Skip to content

Commit

Permalink
Merge pull request #44 from tamada/issue/colorable_output
Browse files Browse the repository at this point in the history
Issue/colorable output
  • Loading branch information
tamada committed Apr 9, 2019
2 parents 1f572ae + 8e6104d commit ab340d8
Show file tree
Hide file tree
Showing 25 changed files with 472 additions and 244 deletions.
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
name = "github.com/mitchellh/go-homedir"
version = "1.1.0"

[[constraint]]
name = "github.com/gookit/color"
version = "1.1.5"

[prune]
go-tests = true
unused-packages = true
41 changes: 31 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,34 +386,34 @@ We can see those variables by running `rrh config` sub-command.
### `RRH_HOME`
* specifies the location of the RRH database and config file.
* default: `/Users/tamada/.rrh`
* Default: `/Users/tamada/.rrh`
### `RRH_CONFIG_PATH`
* specifies the location of the location path.
* RRH ignores to specify `RRH_CONFIG_PATH` in the config file.
This variable availables only environment variable.
* default: `${RRH_HOME}/config.json`
* Default: `${RRH_HOME}/config.json`
### `RRH_DATABASE_PATH`
* specifies the location of the database path.
* default: `${RRH_HOME}/database.json`
* Default: `${RRH_HOME}/database.json`
### `RRH_DEFAULT_GROUP_NAME`
* specifies the default group name.
* default: `no-group`
* Default: `no-group`
### `RRH_CLONE_DESTINATION`
* specifies the destination by cloning the repository.
* default: `.`
* Default: `.`
### `RRH_ON_ERROR`
* specifies the behaviors of RRH on error.
* default: `WARN`
* Default: `WARN`
* Available values: `FAIL_IMMEDIATELY`, `FAIL`, `WARN`, and `IGNORE`
* `FAIL_IMMEDIATELY`
* reports error immediately and quits RRH with a non-zero status.
Expand All @@ -427,7 +427,7 @@ We can see those variables by running `rrh config` sub-command.
### `RRH_TIME_FORMAT`
* specifies the time format for `status` command.
* default: `relative`
* Default: `relative`
* Available value: `relative` and the time format for Go lang.
* `relative`
* shows times by humanized format (e.g., 2 weeks ago)
Expand All @@ -438,17 +438,38 @@ We can see those variables by running `rrh config` sub-command.
### `RRH_AUTO_CREATE_GROUP`
* specifies to create the group when the not existing group was specified, and it needs to create.
* default: false
* Default: false
### `RRH_AUTO_DELETE_GROUP`
* specifies to delete the group when some group was no more needed.
* default: false
* Default: false
### `RRH_SORT_ON_UPDATING`
* specifies to sort database entries on updating database.
* default: false
* Default: false
### `RRH_COLOR`
* specifies the colors of the output.
* Default: `""` (empty string)
* Format: `"repository:fg=<COLOR>;bg=<COLOR>;op=<STYLE>+GROUP:fg=<COLOR>;bg=<COLOR>;op=<STYLE>"`
* Available `COLOR`s
* red, cyan, gray, blue, black, green, white, yellow, magenta.
* Available `STYLE`s
* bold, underscore.
* Delimiter of repository and group is `+`, delimiter of type and value is `:`, delimiter of each label is `;`, and delimiter of each value is `,`.
* Examples:
* `RRH_COLOR: repository:fg=red+group:fg=cyan;op=bold,underscore`
* Repository: red, Group: cyan in bold with underscore.
* Note
* The colorized output does not support to arrange the output indentation.
### `RRH_ENABLE_COLORIZED`
* specifies to colorize the output. The colors of output were specified on [`RRH_COLOR`](#rrh_color)
* Default: true
## Database
Expand Down
1 change: 1 addition & 0 deletions clone/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func registerPath(db *common.Database, dest string, repoID string) (*common.Repo
if err2 != nil {
return nil, err2
}
fmt.Printf("createRepository(%s, %s)\n", repoID, path)
var repo, err3 = db.CreateRepository(repoID, path, remotes)
if err3 != nil {
return nil, err3
Expand Down
2 changes: 1 addition & 1 deletion clone/clone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func contains(slice []string, checkItem string) bool {
func TestCommand_MultipleProjects(t *testing.T) {
common.Rollback("../testdata/tmp.json", "../testdata/config.json", func() {
var clone, _ = CommandFactory()
clone.Run([]string{"-d", "../testdata/hoge", "-g", "not-exist-group",
clone.Run([]string{"--verbose", "-d", "../testdata/hoge", "-g", "not-exist-group",
"../testdata/helloworld",
"../testdata/fibonacci"})
defer cleanup([]string{"../testdata/hoge"})
Expand Down
95 changes: 95 additions & 0 deletions common/colorable_output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package common

import (
"strings"

"github.com/gookit/color"
)

var repoColorFunc func(r string) string
var groupColorFunc func(r string) string

var repoColor = ""
var groupColor = ""

/*
ColorizedRepositoryID returns the colorrized repository id string from configuration.
*/
func ColorizedRepositoryID(repoID string) string {
return repoColorFunc(repoID)
}

/*
ColorizedGroupName returns the colorrized group name string from configuration.
*/
func ColorizedGroupName(groupName string) string {
return groupColorFunc(groupName)
}

/*
ClearColorize clears the color settings.
*/
func ClearColorize() {
parse("")
}

func parse(colorSettings string) {
var colors = strings.Split(colorSettings, "+")
repoColor = ""
groupColor = ""
for _, c := range colors {
parseEach(c)
}
updateFuncs()
}

func parseEach(c string) {
if strings.HasPrefix(c, "repository:") {
repoColor = color.ParseCodeFromAttr(strings.Replace(c, "repository:", "", -1))
} else if strings.HasPrefix(c, "group:") {
groupColor = color.ParseCodeFromAttr(strings.Replace(c, "group:", "", -1))
}
}

func updateFuncs() {
updateRepoFunc(repoColor)
updateGroupFunc(groupColor)
}

func updateRepoFunc(repoColor string) {
if repoColor != "" {
var printer = color.NewPrinter(repoColor)
repoColorFunc = func(r string) string {
return printer.Sprint(r)
}
} else {
repoColorFunc = func(r string) string {
return r
}
}
}

func updateGroupFunc(groupColor string) {
if groupColor != "" {
var printer = color.NewPrinter(groupColor)
groupColorFunc = func(r string) string {
return printer.Sprint(r)
}
} else {
groupColorFunc = func(r string) string {
return r
}
}
}

/*
InitializeColor is the initialization function of the colorized output.
The function is automatically called on loading the config file.
*/
func InitializeColor(config *Config) {
var colorSetting = config.GetValue(RrhColor)
if config.IsSet(RrhEnableColorized) && colorSetting != "" {
parse(colorSetting)
}
updateFuncs()
}
38 changes: 38 additions & 0 deletions common/colorable_output_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package common

import (
"testing"

c "github.com/gookit/color"
)

func TestParse(t *testing.T) {
var testcases = []struct {
givenString string
repoColor string
groupColor string
wontRepo string
wontGroup string
}{
{"repository:fg=white;op=bold,underscore", "37;1;4", "", c.Style{c.FgWhite, c.Bold, c.OpUnderscore}.Render("repository"), "groupName"},
{"group: fg=red+repository:fg=white;op=bold,underscore", "37;1;4", "31", c.Style{c.FgWhite, c.Bold, c.OpUnderscore}.Render("repository"), c.FgRed.Render("groupName")},
{"group: fg=red+group: fg=blue", "", "34", "repository", c.FgBlue.Render("groupName")},
}

for _, tc := range testcases {
parse(tc.givenString)
if repoColor != tc.repoColor {
t.Errorf("%v: repo color did not match, wont: %s, got: %s", tc.givenString, tc.repoColor, repoColor)
}
if groupColor != tc.groupColor {
t.Errorf("%v: group color did not match, wont: %s, got: %s", tc.givenString, tc.groupColor, groupColor)
}
if name := ColorizedRepositoryID("repository"); name != tc.wontRepo {
t.Errorf("repository id did not match: wont: %s, got: %s", tc.wontRepo, name)
}
if name := ColorizedGroupName("groupName"); name != tc.wontGroup {
t.Errorf("group name did not match: wont: %s, got: %s", tc.wontGroup, name)
}
ClearColorize()
}
}
14 changes: 10 additions & 4 deletions common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,25 @@ const (
RrhAutoDeleteGroup = "RRH_AUTO_DELETE_GROUP"
RrhAutoCreateGroup = "RRH_AUTO_CREATE_GROUP"
RrhCloneDestination = "RRH_CLONE_DESTINATION"
RrhColor = "RRH_COLOR"
RrhConfigPath = "RRH_CONFIG_PATH"
RrhDatabasePath = "RRH_DATABASE_PATH"
RrhDefaultGroupName = "RRH_DEFAULT_GROUP_NAME"
RrhEnableColorized = "RRH_ENABLE_COLORIZED"
RrhHome = "RRH_HOME"
RrhOnError = "RRH_ON_ERROR"
RrhSortOnUpdating = "RRH_SORT_ON_UPDATING"
RrhTimeFormat = "RRH_TIME_FORMAT"
)

var availableLabels = []string{
RrhAutoCreateGroup, RrhAutoDeleteGroup, RrhCloneDestination, RrhConfigPath,
RrhDatabasePath, RrhDefaultGroupName, RrhHome, RrhOnError, RrhSortOnUpdating,
RrhTimeFormat,
RrhAutoCreateGroup, RrhAutoDeleteGroup, RrhCloneDestination, RrhColor,
RrhConfigPath, RrhDatabasePath, RrhDefaultGroupName, RrhEnableColorized,
RrhHome, RrhOnError, RrhSortOnUpdating, RrhTimeFormat,
}
var boolLabels = []string{
RrhAutoCreateGroup, RrhAutoDeleteGroup, RrhSortOnUpdating,
RrhAutoCreateGroup, RrhAutoDeleteGroup, RrhEnableColorized,
RrhSortOnUpdating,
}

/*
Expand Down Expand Up @@ -85,9 +88,11 @@ var defaultValues = Config{
RrhAutoCreateGroup: "false",
RrhAutoDeleteGroup: "false",
RrhCloneDestination: ".",
RrhColor: "",
RrhConfigPath: "${RRH_HOME}/config.json",
RrhDatabasePath: "${RRH_HOME}/database.json",
RrhDefaultGroupName: "no-group",
RrhEnableColorized: "true",
RrhHome: "${HOME}/.rrh",
RrhOnError: Warn,
RrhSortOnUpdating: "false",
Expand Down Expand Up @@ -297,6 +302,7 @@ func OpenConfig() *Config {
if err := json.Unmarshal(bytes, &config); err != nil {
return nil
}
InitializeColor(&config)
return &config
}

Expand Down
7 changes: 7 additions & 0 deletions common/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ func ExampleCommand() {
// RRH_AUTO_CREATE_GROUP: true (config_file)
// RRH_AUTO_DELETE_GROUP: false (config_file)
// RRH_CLONE_DESTINATION: . (default)
// RRH_COLOR: (default)
// RRH_CONFIG_PATH: ../testdata/config.json (environment)
// RRH_DATABASE_PATH: ../testdata/tmp.json (environment)
// RRH_DEFAULT_GROUP_NAME: no-group (default)
// RRH_ENABLE_COLORIZED: true (default)
// RRH_HOME: ../testdata/ (environment)
// RRH_ON_ERROR: WARN (default)
// RRH_SORT_ON_UPDATING: true (config_file)
Expand All @@ -125,9 +127,11 @@ func ExampleCommand_Run() {
// RRH_AUTO_CREATE_GROUP: true (config_file)
// RRH_AUTO_DELETE_GROUP: false (config_file)
// RRH_CLONE_DESTINATION: . (default)
// RRH_COLOR: (default)
// RRH_CONFIG_PATH: ../testdata/config.json (environment)
// RRH_DATABASE_PATH: ../testdata/database.json (environment)
// RRH_DEFAULT_GROUP_NAME: no-group (default)
// RRH_ENABLE_COLORIZED: true (default)
// RRH_HOME: ../testdata/ (environment)
// RRH_ON_ERROR: WARN (default)
// RRH_SORT_ON_UPDATING: true (config_file)
Expand All @@ -143,9 +147,11 @@ func Example_listCommand_Run() {
// RRH_AUTO_CREATE_GROUP: true (config_file)
// RRH_AUTO_DELETE_GROUP: false (config_file)
// RRH_CLONE_DESTINATION: . (default)
// RRH_COLOR: (default)
// RRH_CONFIG_PATH: ../testdata/config.json (environment)
// RRH_DATABASE_PATH: ../testdata/database.json (default)
// RRH_DEFAULT_GROUP_NAME: no-group (default)
// RRH_ENABLE_COLORIZED: true (default)
// RRH_HOME: ../testdata/ (environment)
// RRH_ON_ERROR: WARN (default)
// RRH_SORT_ON_UPDATING: true (config_file)
Expand Down Expand Up @@ -174,6 +180,7 @@ func TestLoadConfigFile(t *testing.T) {
{RrhConfigPath, "../testdata/config.json", Env},
{RrhTimeFormat, Relative, Default},
{RrhOnError, Warn, Default},
{RrhEnableColorized, "true", Default},
{"unknown", "", NotFound},
}

Expand Down
4 changes: 2 additions & 2 deletions common/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
Remote represents remote of the git repository.
*/
type Remote struct {
Name string
URL string
Name string `json:"name"`
URL string `json:"url"`
}

/*
Expand Down
Loading

0 comments on commit ab340d8

Please sign in to comment.