From 086190b455715a13a09723d7337121d9582a4392 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Mon, 11 Mar 2019 18:51:58 +0900 Subject: [PATCH 1/6] ref #7 update add subcommand for adding a repository to the multiple groups. --- add/add.go | 17 ++++++++++++----- add/add_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/add/add.go b/add/add.go index f746dd1..3ecf5b9 100644 --- a/add/add.go +++ b/add/add.go @@ -38,6 +38,14 @@ func (add *AddCommand) createGroupIfNeeded(db *common.Database, groupName string return fmt.Errorf("%s: group not found", groupName) } +func checkDuplication(db *common.Database, repoID string, path string) error { + var repo = db.FindRepository(repoID) + if repo != nil && repo.Path != path { + return fmt.Errorf("%s: duplicate repository id", repoID) + } + return nil +} + func (add *AddCommand) addRepositoriesToGroup(db *common.Database, args []string, groupName string) []error { var err = add.createGroupIfNeeded(db, groupName) if err != nil { @@ -78,15 +86,14 @@ func (add *AddCommand) addRepositoryToGroup(db *common.Database, groupName strin return append(list, err1) } var repoPath = common.NormalizePath(absPath) - if !db.HasRepository(id) { + if err1 := checkDuplication(db, id, absPath); err1 != nil { + return append(list, err1) + } else { var remotes, err2 = FindRemotes(absPath) if err2 != nil { return append(list, err2) } - var _, err = db.CreateRepository(id, repoPath, remotes) - if err != nil { - return append(list, err) - } + db.CreateRepository(id, repoPath, remotes) } var err = db.Relate(groupName, id) if err != nil { diff --git a/add/add_test.go b/add/add_test.go index 4726d2b..f233e8d 100644 --- a/add/add_test.go +++ b/add/add_test.go @@ -70,3 +70,28 @@ func TestAddCommand_Run(t *testing.T) { } }) } + +func TestAddToDifferentGroup(t *testing.T) { + os.Setenv(common.RrhConfigPath, "../testdata/config.json") + os.Setenv(common.RrhDatabasePath, "../testdata/tmp.json") + rollback(func() { + var command, _ = AddCommandFactory() + command.Run([]string{"../testdata/fibonacci"}) + command.Run([]string{"-g", "group1", "../testdata/fibonacci"}) + + var config = common.OpenConfig() + var db, _ = common.Open(config) + if !db.HasGroup("no-group") { + t.Error("no-group: group not found") + } + if !db.HasRepository("fibonacci") { + t.Error("fibonacci: repository not found") + } + if !db.HasRelation("no-group", "fibonacci") { + t.Error("no-group, and fibonacci: the relation not found") + } + if !db.HasRelation("group1", "fibonacci") { + t.Error("group1 and fibonacci: the relation not found") + } + }) +} From c4d2a83d8fdf51fc602edcc749b9bdb79202b6b4 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Mon, 11 Mar 2019 22:01:10 +0900 Subject: [PATCH 2/6] Supplement the unit test of add command. --- add/add.go | 50 ++++++++++++++++++++++++------------------------- add/add_cmd.go | 12 +++++------- add/add_test.go | 35 ++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 32 deletions(-) diff --git a/add/add.go b/add/add.go index 3ecf5b9..e918898 100644 --- a/add/add.go +++ b/add/add.go @@ -46,7 +46,30 @@ func checkDuplication(db *common.Database, repoID string, path string) error { return nil } -func (add *AddCommand) addRepositoriesToGroup(db *common.Database, args []string, groupName string) []error { +func (add *AddCommand) addRepositoryToGroup(db *common.Database, groupName string, path string, list []error) []error { + var absPath, _ = filepath.Abs(path) + var id = filepath.Base(absPath) + if err1 := add.isExistAndGitRepository(absPath, path); err1 != nil { + return append(list, err1) + } + var repoPath = common.NormalizePath(absPath) + if err1 := checkDuplication(db, id, absPath); err1 != nil { + return append(list, err1) + } else { + var remotes, err2 = findRemotes(absPath) + if err2 != nil { + return append(list, err2) + } + db.CreateRepository(id, repoPath, remotes) + } + var err = db.Relate(groupName, id) + if err != nil { + return append(list, fmt.Errorf("%s: cannot create relation to group %s", id, groupName)) + } + return list +} + +func (add *AddCommand) AddRepositoriesToGroup(db *common.Database, args []string, groupName string) []error { var err = add.createGroupIfNeeded(db, groupName) if err != nil { return []error{err} @@ -62,7 +85,7 @@ func (add *AddCommand) addRepositoriesToGroup(db *common.Database, args []string /* FindRemotes function returns the remote of the given git repository. */ -func FindRemotes(path string) ([]common.Remote, error) { +func findRemotes(path string) ([]common.Remote, error) { r, err := git.PlainOpen(path) if err != nil { return nil, err @@ -78,26 +101,3 @@ func FindRemotes(path string) ([]common.Remote, error) { } return crs, nil } - -func (add *AddCommand) addRepositoryToGroup(db *common.Database, groupName string, path string, list []error) []error { - var absPath, _ = filepath.Abs(path) - var id = filepath.Base(absPath) - if err1 := add.isExistAndGitRepository(absPath, path); err1 != nil { - return append(list, err1) - } - var repoPath = common.NormalizePath(absPath) - if err1 := checkDuplication(db, id, absPath); err1 != nil { - return append(list, err1) - } else { - var remotes, err2 = FindRemotes(absPath) - if err2 != nil { - return append(list, err2) - } - db.CreateRepository(id, repoPath, remotes) - } - var err = db.Relate(groupName, id) - if err != nil { - return append(list, fmt.Errorf("%s: cannot create relation to group %s", id, groupName)) - } - return list -} diff --git a/add/add_cmd.go b/add/add_cmd.go index 758e336..1f0a7d4 100644 --- a/add/add_cmd.go +++ b/add/add_cmd.go @@ -44,7 +44,7 @@ func (add *AddCommand) showError(errorlist []error, onError string) { func (add *AddCommand) perform(db *common.Database, args []string, groupName string) int { var onError = db.Config.GetValue(common.RrhOnError) - var errorlist = add.addRepositoriesToGroup(db, args, groupName) + var errorlist = add.AddRepositoriesToGroup(db, args, groupName) add.showError(errorlist, onError) @@ -73,7 +73,7 @@ func (add *AddCommand) Run(args []string) int { var db, err2 = common.Open(config) if err2 != nil { fmt.Println(err2.Error()) - return 1 + return 2 } return add.perform(db, opt.args, opt.group) } @@ -85,17 +85,15 @@ type addOptions struct { func (add *AddCommand) parse(args []string, config *common.Config) (*addOptions, error) { var opt = addOptions{} + var defaultGroup = config.GetValue(common.RrhDefaultGroupName) flags := flag.NewFlagSet("add", flag.ContinueOnError) flags.Usage = func() { fmt.Println(add.Help()) } - flags.StringVar(&opt.group, "g", config.GetValue(common.RrhDefaultGroupName), "target group") - flags.StringVar(&opt.group, "group", config.GetValue(common.RrhDefaultGroupName), "target group") + flags.StringVar(&opt.group, "g", defaultGroup, "target group") + flags.StringVar(&opt.group, "group", defaultGroup, "target group") if err := flags.Parse(args); err != nil { return nil, err } opt.args = flags.Args() - if opt.group == "" { - opt.group = config.GetValue(common.RrhDefaultGroupName) - } return &opt, nil } diff --git a/add/add_test.go b/add/add_test.go index f233e8d..73cd953 100644 --- a/add/add_test.go +++ b/add/add_test.go @@ -15,6 +15,16 @@ func rollback(f func()) { f() } +func TestInvalidOptions(t *testing.T) { + common.CaptureStdout(func() { + var command, _ = AddCommandFactory() + var flag = command.Run([]string{"--invalid-option"}) + if flag != 1 { + t.Errorf("parse option failed.") + } + }) +} + func TestHelpAndSynopsis(t *testing.T) { var command, _ = AddCommandFactory() if command.Synopsis() != "add repositories on the local path to RRH" { @@ -95,3 +105,28 @@ func TestAddToDifferentGroup(t *testing.T) { } }) } + +func TestAddFailed(t *testing.T) { + os.Setenv(common.RrhConfigPath, "../testdata/nulldb.json") + os.Setenv(common.RrhDatabasePath, "../testdata/tmp.json") + os.Setenv(common.RrhAutoCreateGroup, "false") + + var add = AddCommand{} + var config = common.OpenConfig() + var db, _ = common.Open(config) + + var data = []struct { + args []string + groupName string + }{ + {[]string{"../not-exist-dir"}, "no-group"}, + {[]string{"../testdata/fibonacci"}, "not-exist-group"}, + } + + for _, datum := range data { + var list = add.AddRepositoriesToGroup(db, datum.args, datum.groupName) + if len(list) == 0 { + t.Errorf("successfully add in invalid data: %v", datum) + } + } +} From 520fbf2a8722535d47229cd5139ad8744c0e5c99 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Mon, 11 Mar 2019 22:20:06 +0900 Subject: [PATCH 3/6] fixed test fail of clone command. --- add/add.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/add/add.go b/add/add.go index e918898..ee841bd 100644 --- a/add/add.go +++ b/add/add.go @@ -56,7 +56,7 @@ func (add *AddCommand) addRepositoryToGroup(db *common.Database, groupName strin if err1 := checkDuplication(db, id, absPath); err1 != nil { return append(list, err1) } else { - var remotes, err2 = findRemotes(absPath) + var remotes, err2 = FindRemotes(absPath) if err2 != nil { return append(list, err2) } @@ -85,7 +85,7 @@ func (add *AddCommand) AddRepositoriesToGroup(db *common.Database, args []string /* FindRemotes function returns the remote of the given git repository. */ -func findRemotes(path string) ([]common.Remote, error) { +func FindRemotes(path string) ([]common.Remote, error) { r, err := git.PlainOpen(path) if err != nil { return nil, err From 02ade0df7df684da5eb144a7a8dbd82028d8d568 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Fri, 15 Mar 2019 10:42:39 +0900 Subject: [PATCH 4/6] update unit tests in clone command. --- clone/clone.go | 3 +-- clone/clone_cmd.go | 6 ++++-- clone/clone_test.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/clone/clone.go b/clone/clone.go index a5a9261..41fa44d 100644 --- a/clone/clone.go +++ b/clone/clone.go @@ -17,8 +17,7 @@ func (clone *CloneCommand) toDir(db *common.Database, url string, dest string, r var cmd = exec.Command("git", "clone", url, dest) var err = cmd.Run() if err != nil { - fmt.Printf("clone error: %s\n", err.Error()) - return nil, err + return nil, fmt.Errorf("%s: clone error (%s)", url, err.Error()) } path, err := filepath.Abs(dest) diff --git a/clone/clone_cmd.go b/clone/clone_cmd.go index 36fe2f6..2e8fd20 100644 --- a/clone/clone_cmd.go +++ b/clone/clone_cmd.go @@ -64,7 +64,7 @@ func (clone *CloneCommand) Run(args []string) int { db, err := common.Open(config) if err != nil { fmt.Println(err.Error()) - return 1 + return 2 } return clone.perform(db, arguments) } @@ -81,8 +81,10 @@ func (clone *CloneCommand) perform(db *common.Database, arguments []string) int db.StoreAndClose() if count == 1 { fmt.Printf("a repository cloned into %s and registered to group %s\n", clone.Options.dest, clone.Options.group) - } else { + } else if count > 1 { fmt.Printf("%d repositories cloned into %s and registered to group %s\n", count, clone.Options.dest, clone.Options.group) + } else if count == 0 { + fmt.Println("no repositories cloned") } return 0 diff --git a/clone/clone_test.go b/clone/clone_test.go index 0441017..6d9add6 100644 --- a/clone/clone_test.go +++ b/clone/clone_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "testing" "github.com/tamada/rrh/common" @@ -122,6 +123,34 @@ func TestCloneCommand_SpecifyingId(t *testing.T) { }) } +func TestUnknownOption(t *testing.T) { + os.Setenv(common.RrhConfigPath, "../testdata/config.json") + os.Setenv(common.RrhDatabasePath, "../testdata/tmp.json") + var output, _ = common.CaptureStdout(func() { + var clone, _ = CloneCommandFactory() + clone.Run([]string{}) + }) + var cm = CloneCommand{} + if output != cm.Help() { + t.Error("no arguments were allowed") + } +} + +func TestCloneNotGitRepository(t *testing.T) { + os.Setenv(common.RrhConfigPath, "../testdata/config.json") + os.Setenv(common.RrhDatabasePath, "../testdata/tmp.json") + os.Setenv(common.RrhOnError, "FAIL") + var output, _ = common.CaptureStdout(func() { + var clone, _ = CloneCommandFactory() + clone.Run([]string{"../testdata"}) + }) + output = strings.TrimSpace(output) + var message = "../testdata: clone error (exit status 128)" + if output != message { + t.Errorf("wont: %s, got: %s", message, output) + } +} + func TestHelpAndSynopsis(t *testing.T) { var helpMessage = `rrh clone [OPTIONS] OPTIONS From dc2058158e3f19f12d07bb361c845fb6bc1b5eba Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Fri, 15 Mar 2019 16:37:07 +0900 Subject: [PATCH 5/6] separate complex function. --- clone/clone_cmd.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/clone/clone_cmd.go b/clone/clone_cmd.go index 2e8fd20..04ad692 100644 --- a/clone/clone_cmd.go +++ b/clone/clone_cmd.go @@ -79,15 +79,18 @@ func (clone *CloneCommand) perform(db *common.Database, arguments []string) int } } db.StoreAndClose() + printResult(count, clone.Options.dest, clone.Options.group) + return 0 +} + +func printResult(count int, dest string, group string) { if count == 1 { - fmt.Printf("a repository cloned into %s and registered to group %s\n", clone.Options.dest, clone.Options.group) + fmt.Printf("a repository cloned into %s and registered to group %s\n", dest, group) } else if count > 1 { - fmt.Printf("%d repositories cloned into %s and registered to group %s\n", count, clone.Options.dest, clone.Options.group) + fmt.Printf("%d repositories cloned into %s and registered to group %s\n", count, dest, group) } else if count == 0 { fmt.Println("no repositories cloned") } - - return 0 } func (clone *CloneCommand) parse(args []string, config *common.Config) ([]string, error) { From f57f923a62ecab65f41bca6748d5548334eb0b6b Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Fri, 15 Mar 2019 16:46:06 +0900 Subject: [PATCH 6/6] use switch instead of if-else statements for fixing the warning from Codebeat. --- clone/clone_cmd.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clone/clone_cmd.go b/clone/clone_cmd.go index 04ad692..7cdb500 100644 --- a/clone/clone_cmd.go +++ b/clone/clone_cmd.go @@ -84,12 +84,13 @@ func (clone *CloneCommand) perform(db *common.Database, arguments []string) int } func printResult(count int, dest string, group string) { - if count == 1 { + switch count { + case 0: + fmt.Println("no repositories cloned") + case 1: fmt.Printf("a repository cloned into %s and registered to group %s\n", dest, group) - } else if count > 1 { + default: fmt.Printf("%d repositories cloned into %s and registered to group %s\n", count, dest, group) - } else if count == 0 { - fmt.Println("no repositories cloned") } }