Add possiblity to limit actions to tagged or named repository
This commit is contained in:
parent
5c98ab6554
commit
23e4547e52
12
README.md
12
README.md
@ -11,9 +11,10 @@ Create a yaml file with the given structure
|
|||||||
workspace: ${HOME}/workspace
|
workspace: ${HOME}/workspace
|
||||||
# List with repositories, that you want to manage with GRM
|
# List with repositories, that you want to manage with GRM
|
||||||
repositories:
|
repositories:
|
||||||
- src: "git@github.com:Revalus/GitRepositoryManager.git"
|
- src: "git@github.com:Revalus/GitRepositoryManager.git" # Required - specified repository to clone/fetch data
|
||||||
name: GRM # Optional, Uniq - if no name is specified, the repository will be treated as a name
|
name: GRM # Optional, Uniq - if no name is specified, the repository will be treated as a name
|
||||||
dest: manager # Optional, Uniq - if no value is specified, name will be taken as destination
|
dest: manager # Optional, Uniq - if no value is specified, name will be taken as destination
|
||||||
|
tags: ['companyX', 'departmentY'] # Optional - tags to specify to limit/exclude actions on the repository
|
||||||
```
|
```
|
||||||
|
|
||||||
### Note
|
### Note
|
||||||
@ -25,8 +26,12 @@ By default, the config file is searched for in `[HOME_DIR]./config/grm/config.ya
|
|||||||
### Global args
|
### Global args
|
||||||
|
|
||||||
| argument | type | default | Description |
|
| argument | type | default | Description |
|
||||||
|-------------------|--------|--------------------------------------|----------------------------------------------------------------------|
|
|---------------------------|----------|--------------------------------------|------------------------------------------------------------------------|
|
||||||
| -c, --config-file | string | `[HOME_DIR]./config/grm/config.yaml` | Path to configuration file, where the repositories must be specified |
|
| **-c**, **--config-file** | *string* | `[HOME_DIR]./config/grm/config.yaml` | Path to configuration file, where the repositories must be specified |
|
||||||
|
| **-v**, **--version** | *bool* | `false` | Display current version |
|
||||||
|
| **--no-color** | *bool* | `false` | Turning off the display of output in color |
|
||||||
|
| **-n** **--name** | *string* | `empty` | Limit action to the specified repository name |
|
||||||
|
| **-t** **--tag** | *string* | `empty` | Limit action to the specified repository tag (may be more than one tag)|
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
@ -37,6 +42,7 @@ By default, the config file is searched for in `[HOME_DIR]./config/grm/config.ya
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
- 0.3.0 Adding the ability to limit actions to repositories containing a given name or tags
|
||||||
- 0.2.0 Add status command - get information about the current status in the repository
|
- 0.2.0 Add status command - get information about the current status in the repository
|
||||||
- 0.1.1 Allow to use env vars in config
|
- 0.1.1 Allow to use env vars in config
|
||||||
- 0.1.0 Add sync command - allow to fetch and clone repositories
|
- 0.1.0 Add sync command - allow to fetch and clone repositories
|
||||||
|
59
app/app.go
59
app/app.go
@ -1,6 +1,7 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gitlab.com/revalus/grm/commands"
|
"gitlab.com/revalus/grm/commands"
|
||||||
@ -10,7 +11,9 @@ import (
|
|||||||
const (
|
const (
|
||||||
APP_NAME = "Git repository manager"
|
APP_NAME = "Git repository manager"
|
||||||
APP_DESCRIPTION = "Manage your repository with simple app"
|
APP_DESCRIPTION = "Manage your repository with simple app"
|
||||||
VERSION = "0.2.0"
|
VERSION = "0.3.0"
|
||||||
|
errNotFoundTags = "no repository was found with the specified tags"
|
||||||
|
errNotFoundName = "no repository was found with the specified name"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GitRepositoryManager struct {
|
type GitRepositoryManager struct {
|
||||||
@ -47,17 +50,35 @@ func (g *GitRepositoryManager) Parse(args []string) {
|
|||||||
g.configuration = configuration
|
g.configuration = configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GitRepositoryManager) Run() {
|
func (g *GitRepositoryManager) Run() int {
|
||||||
if g.cliArguments.Sync {
|
|
||||||
|
exitCode := 0
|
||||||
|
|
||||||
|
if len(g.cliArguments.LimitTags) != 0 {
|
||||||
|
err := g.limitTags()
|
||||||
|
if err != nil {
|
||||||
|
g.console.ErrorfMsg(err.Error())
|
||||||
|
exitCode = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.cliArguments.LimitName != "" {
|
||||||
|
err := g.limitName()
|
||||||
|
if err != nil {
|
||||||
|
g.console.ErrorfMsg(err.Error())
|
||||||
|
exitCode = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if g.cliArguments.Sync && exitCode == 0 {
|
||||||
g.console.InfoFMsg("Synchronizing repositories")
|
g.console.InfoFMsg("Synchronizing repositories")
|
||||||
println()
|
|
||||||
sync := commands.NewSynchronizer(g.configuration.Workspace)
|
sync := commands.NewSynchronizer(g.configuration.Workspace)
|
||||||
g.runCommand(sync)
|
g.runCommand(sync)
|
||||||
println()
|
|
||||||
g.console.InfoFMsg("All repositories are synced")
|
g.console.InfoFMsg("All repositories are synced")
|
||||||
}
|
}
|
||||||
|
|
||||||
if g.cliArguments.Status {
|
if g.cliArguments.Status && exitCode == 0 {
|
||||||
|
g.console.InfoFMsg("Current status of repositories")
|
||||||
status := commands.NewStatusChecker(g.configuration.Workspace)
|
status := commands.NewStatusChecker(g.configuration.Workspace)
|
||||||
g.runCommand(status)
|
g.runCommand(status)
|
||||||
}
|
}
|
||||||
@ -65,6 +86,7 @@ func (g *GitRepositoryManager) Run() {
|
|||||||
if g.cliArguments.Version {
|
if g.cliArguments.Version {
|
||||||
g.console.InfoFMsg("Current version: %v", VERSION)
|
g.console.InfoFMsg("Current version: %v", VERSION)
|
||||||
}
|
}
|
||||||
|
return exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g GitRepositoryManager) describeStatus(status commands.CommandStatus) {
|
func (g GitRepositoryManager) describeStatus(status commands.CommandStatus) {
|
||||||
@ -80,6 +102,31 @@ func (g GitRepositoryManager) describeStatus(status commands.CommandStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GitRepositoryManager) limitTags() error {
|
||||||
|
limitedTagsTmp := []config.RepositoryConfig{}
|
||||||
|
|
||||||
|
for _, item := range g.configuration.Repositories {
|
||||||
|
if checkAnyOfItemInSlice(item.Tags, g.cliArguments.LimitTags) {
|
||||||
|
limitedTagsTmp = append(limitedTagsTmp, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(limitedTagsTmp) == 0 {
|
||||||
|
return errors.New(errNotFoundTags)
|
||||||
|
}
|
||||||
|
g.configuration.Repositories = reverseRepositoryConfigs(limitedTagsTmp)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GitRepositoryManager) limitName() error {
|
||||||
|
for _, item := range g.configuration.Repositories {
|
||||||
|
if g.cliArguments.LimitName == item.Name {
|
||||||
|
g.configuration.Repositories = []config.RepositoryConfig{item}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors.New(errNotFoundName)
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GitRepositoryManager) runCommand(cmd commands.Command) {
|
func (g *GitRepositoryManager) runCommand(cmd commands.Command) {
|
||||||
statusChan := make(chan commands.CommandStatus)
|
statusChan := make(chan commands.CommandStatus)
|
||||||
|
|
||||||
|
147
app/app_test.go
147
app/app_test.go
@ -3,11 +3,36 @@ package app
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"gitlab.com/revalus/grm/commands"
|
||||||
"gitlab.com/revalus/grm/config"
|
"gitlab.com/revalus/grm/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FakeCommandToTest struct {
|
||||||
|
triggerError bool
|
||||||
|
triggerChanged bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fk FakeCommandToTest) Command(repoCfg config.RepositoryConfig, cmdStatus chan commands.CommandStatus) {
|
||||||
|
status := commands.CommandStatus{
|
||||||
|
Name: repoCfg.Name,
|
||||||
|
Changed: false,
|
||||||
|
Message: "response from fake command",
|
||||||
|
Error: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if fk.triggerError {
|
||||||
|
status.Error = true
|
||||||
|
}
|
||||||
|
if fk.triggerChanged {
|
||||||
|
status.Changed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdStatus <- status
|
||||||
|
}
|
||||||
|
|
||||||
func prepareConfigContent() (string, string) {
|
func prepareConfigContent() (string, string) {
|
||||||
checkErrorDuringPreparation := func(err error) {
|
checkErrorDuringPreparation := func(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,7 +60,9 @@ func prepareConfigContent() (string, string) {
|
|||||||
yamlConfig := fmt.Sprintf(`
|
yamlConfig := fmt.Sprintf(`
|
||||||
workspace: %v
|
workspace: %v
|
||||||
repositories:
|
repositories:
|
||||||
- src: "https://github.com/golang/example.git"`, tempDir)
|
- src: "https://github.com/golang/example.git"
|
||||||
|
tags: ['example']
|
||||||
|
`, tempDir)
|
||||||
|
|
||||||
_, err = file.WriteString(yamlConfig)
|
_, err = file.WriteString(yamlConfig)
|
||||||
|
|
||||||
@ -65,12 +92,12 @@ func TestParseApplication(t *testing.T) {
|
|||||||
Name: "example",
|
Name: "example",
|
||||||
Src: "https://github.com/golang/example.git",
|
Src: "https://github.com/golang/example.git",
|
||||||
Dest: "example",
|
Dest: "example",
|
||||||
|
Tags: []string{"example"},
|
||||||
}
|
}
|
||||||
|
|
||||||
if expectedRepo != grm.configuration.Repositories[0] {
|
if !reflect.DeepEqual(expectedRepo, grm.configuration.Repositories[0]) {
|
||||||
t.Errorf("Expected to get %v, instead of this got %v", expectedRepo, grm.configuration.Repositories[0])
|
t.Errorf("Expected to get %v, instead of this got %v", expectedRepo, grm.configuration.Repositories[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Example_test_sync_output() {
|
func Example_test_sync_output() {
|
||||||
@ -90,5 +117,117 @@ func Example_test_sync_output() {
|
|||||||
// Output:
|
// Output:
|
||||||
// Info: Synchronizing repositories
|
// Info: Synchronizing repositories
|
||||||
// Info: All repositories are synced
|
// Info: All repositories are synced
|
||||||
// Info: Current version: 0.2.0
|
// Info: Current version: 0.3.0
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_limit_test_tags() {
|
||||||
|
grm := GitRepositoryManager{
|
||||||
|
cliArguments: config.CliArguments{
|
||||||
|
LimitTags: []string{"example"},
|
||||||
|
},
|
||||||
|
configuration: config.Configuration{
|
||||||
|
Repositories: []config.RepositoryConfig{
|
||||||
|
{Name: "example1", Tags: []string{"example"}},
|
||||||
|
{Name: "example2", Tags: []string{"example"}},
|
||||||
|
{Name: "notExample"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
console: ConsoleOutput{
|
||||||
|
Color: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fakeCommand := FakeCommandToTest{
|
||||||
|
triggerError: false,
|
||||||
|
triggerChanged: false,
|
||||||
|
}
|
||||||
|
grm.limitTags()
|
||||||
|
grm.runCommand(fakeCommand)
|
||||||
|
// Output:
|
||||||
|
// Repository "example1": response from fake command
|
||||||
|
// Repository "example2": response from fake command
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_limit_name() {
|
||||||
|
grm := GitRepositoryManager{
|
||||||
|
cliArguments: config.CliArguments{
|
||||||
|
LimitName: "notExample",
|
||||||
|
},
|
||||||
|
configuration: config.Configuration{
|
||||||
|
Repositories: []config.RepositoryConfig{
|
||||||
|
{Name: "example1", Tags: []string{"example"}},
|
||||||
|
{Name: "example2", Tags: []string{"example"}},
|
||||||
|
{Name: "notExample"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
console: ConsoleOutput{
|
||||||
|
Color: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fakeCommand := FakeCommandToTest{
|
||||||
|
triggerError: false,
|
||||||
|
triggerChanged: false,
|
||||||
|
}
|
||||||
|
grm.limitName()
|
||||||
|
grm.runCommand(fakeCommand)
|
||||||
|
// Output:
|
||||||
|
// Repository "notExample": response from fake command
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_run_with_limit_not_existing_name() {
|
||||||
|
grm := GitRepositoryManager{
|
||||||
|
cliArguments: config.CliArguments{
|
||||||
|
LimitName: "not-existing-name",
|
||||||
|
},
|
||||||
|
configuration: config.Configuration{
|
||||||
|
Repositories: []config.RepositoryConfig{
|
||||||
|
{Name: "example1", Tags: []string{"example"}},
|
||||||
|
{Name: "example2", Tags: []string{"example"}},
|
||||||
|
{Name: "notExample"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
console: ConsoleOutput{
|
||||||
|
Color: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
grm.Run()
|
||||||
|
// Output:
|
||||||
|
// Error: no repository was found with the specified name
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_run_with_limit_not_existing_tags() {
|
||||||
|
grm := GitRepositoryManager{
|
||||||
|
cliArguments: config.CliArguments{
|
||||||
|
LimitTags: []string{"not-existing-tag"},
|
||||||
|
},
|
||||||
|
configuration: config.Configuration{
|
||||||
|
Repositories: []config.RepositoryConfig{
|
||||||
|
{Name: "example1", Tags: []string{"example"}},
|
||||||
|
{Name: "example2", Tags: []string{"example"}},
|
||||||
|
{Name: "notExample"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
console: ConsoleOutput{
|
||||||
|
Color: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
grm.Run()
|
||||||
|
// Output:
|
||||||
|
// Error: no repository was found with the specified tags
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example_test_status_output() {
|
||||||
|
grm := GitRepositoryManager{
|
||||||
|
configuration: config.Configuration{
|
||||||
|
Workspace: "/tmp",
|
||||||
|
},
|
||||||
|
cliArguments: config.CliArguments{
|
||||||
|
Status: true,
|
||||||
|
},
|
||||||
|
console: ConsoleOutput{
|
||||||
|
Color: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
grm.Run()
|
||||||
|
// Output:
|
||||||
|
// Info: Current status of repositories
|
||||||
}
|
}
|
||||||
|
30
app/utils.go
30
app/utils.go
@ -5,6 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gitlab.com/revalus/grm/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getFileContent(pathToFile string) ([]byte, error) {
|
func getFileContent(pathToFile string) ([]byte, error) {
|
||||||
@ -23,3 +25,31 @@ func getFileExcension(pathToFile string) (string, error) {
|
|||||||
|
|
||||||
return fileExcension, nil
|
return fileExcension, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkIsItemInSlice(check string, sliceToCheck []string) bool {
|
||||||
|
for _, item := range sliceToCheck {
|
||||||
|
if item == check {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkAnyOfItemInSlice(check []string, sliceToCheck []string) bool {
|
||||||
|
|
||||||
|
for _, item := range check {
|
||||||
|
if checkIsItemInSlice(item, sliceToCheck) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func reverseRepositoryConfigs(repositories []config.RepositoryConfig) []config.RepositoryConfig {
|
||||||
|
for i, j := 0, len(repositories)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
repositories[i], repositories[j] = repositories[j], repositories[i]
|
||||||
|
}
|
||||||
|
return repositories
|
||||||
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gitlab.com/revalus/grm/config"
|
||||||
|
)
|
||||||
|
|
||||||
func TestGetFileExtension(t *testing.T) {
|
func TestGetFileExtension(t *testing.T) {
|
||||||
|
|
||||||
@ -32,5 +37,49 @@ func TestErrorInGetExcensionFile(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Expected to get error, instead of this got result %v", result)
|
t.Errorf("Expected to get error, instead of this got result %v", result)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsItemInSlice(t *testing.T) {
|
||||||
|
testedSlice := []string{"1", "2", "3", "4", "5"}
|
||||||
|
|
||||||
|
result := checkIsItemInSlice("0", testedSlice)
|
||||||
|
if result {
|
||||||
|
t.Error("Expected to get false as result")
|
||||||
|
}
|
||||||
|
|
||||||
|
result = checkIsItemInSlice("1", testedSlice)
|
||||||
|
if !result {
|
||||||
|
t.Error("Expected to get true as result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsAnyInSlice(t *testing.T) {
|
||||||
|
testedSlice := []string{"1", "2", "3", "4", "5"}
|
||||||
|
|
||||||
|
result := checkAnyOfItemInSlice([]string{"0", "10"}, testedSlice)
|
||||||
|
if result {
|
||||||
|
t.Error("Expected to get false as result")
|
||||||
|
}
|
||||||
|
|
||||||
|
result = checkAnyOfItemInSlice([]string{"0", "5"}, testedSlice)
|
||||||
|
if !result {
|
||||||
|
t.Error("Expected to get true as result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReverseStringsSlice(t *testing.T) {
|
||||||
|
testedSlice := []config.RepositoryConfig{
|
||||||
|
{Name: "test1"},
|
||||||
|
{Name: "test2"},
|
||||||
|
{Name: "test3"},
|
||||||
|
}
|
||||||
|
expectedResult := []config.RepositoryConfig{
|
||||||
|
{Name: "test3"},
|
||||||
|
{Name: "test2"},
|
||||||
|
{Name: "test1"},
|
||||||
|
}
|
||||||
|
result := reverseRepositoryConfigs(testedSlice)
|
||||||
|
if !reflect.DeepEqual(result, expectedResult) {
|
||||||
|
t.Errorf("Expected to get \"%#v\", instead of this got \"%#v\"", expectedResult, result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,14 @@ func ParseCliArguments(name, description string, arguments []string) (CliArgumen
|
|||||||
Help: "Turn off color printing",
|
Help: "Turn off color printing",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
limitName := parser.String("n", "name", &argparse.Options{
|
||||||
|
Help: "Limit action to the specified repository name",
|
||||||
|
})
|
||||||
|
|
||||||
|
limitTags := parser.StringList("t", "tag", &argparse.Options{
|
||||||
|
Help: "Limit actions to repositories that contain specific tags",
|
||||||
|
})
|
||||||
|
|
||||||
if err := parser.Parse(arguments); err != nil {
|
if err := parser.Parse(arguments); err != nil {
|
||||||
return CliArguments{}, errors.New(parser.Usage("Please follow this help"))
|
return CliArguments{}, errors.New(parser.Usage("Please follow this help"))
|
||||||
}
|
}
|
||||||
@ -48,11 +56,17 @@ func ParseCliArguments(name, description string, arguments []string) (CliArgumen
|
|||||||
return CliArguments{}, errors.New(errNoCommand)
|
return CliArguments{}, errors.New(errNoCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *limitName != "" && len(*limitTags) != 0 {
|
||||||
|
return CliArguments{}, errors.New(errNameAndTagsTogether)
|
||||||
|
}
|
||||||
|
|
||||||
return CliArguments{
|
return CliArguments{
|
||||||
ConfigurationFile: *configFile,
|
ConfigurationFile: *configFile,
|
||||||
Sync: syncCMD.Happened(),
|
Sync: syncCMD.Happened(),
|
||||||
Status: statusCMD.Happened(),
|
Status: statusCMD.Happened(),
|
||||||
Version: *version,
|
Version: *version,
|
||||||
Color: !(*color),
|
Color: !(*color),
|
||||||
|
LimitName: *limitName,
|
||||||
|
LimitTags: *limitTags,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,22 @@ func TestParsingDefaultArguments(t *testing.T) {
|
|||||||
|
|
||||||
func TestParsingWithoutCommand(t *testing.T) {
|
func TestParsingWithoutCommand(t *testing.T) {
|
||||||
|
|
||||||
|
// First item in os.Args is appPath, this have to be mocked
|
||||||
|
fakeOSArgs := []string{"appName", "--name", "test"}
|
||||||
|
|
||||||
|
results, err := ParseCliArguments("", "", fakeOSArgs)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error, not results: %v", results)
|
||||||
|
}
|
||||||
|
if err.Error() != errNoCommand {
|
||||||
|
t.Errorf("Expected to get \"%v\", instead of this got \"%v\"", errNoCommand, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParsingNothingProvided(t *testing.T) {
|
||||||
|
|
||||||
// First item in os.Args is appPath, this have to be mocked
|
// First item in os.Args is appPath, this have to be mocked
|
||||||
fakeOSArgs := []string{"appName"}
|
fakeOSArgs := []string{"appName"}
|
||||||
|
|
||||||
@ -49,3 +65,19 @@ func TestParsingWithoutCommand(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
func TestParsingNameAndTags(t *testing.T) {
|
||||||
|
|
||||||
|
// First item in os.Args is appPath, this have to be mocked
|
||||||
|
fakeOSArgs := []string{"appName", "status", "--tag", "example", "--name", "example"}
|
||||||
|
|
||||||
|
results, err := ParseCliArguments("", "", fakeOSArgs)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error, not results: %v", results)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err.Error() != errNameAndTagsTogether {
|
||||||
|
t.Errorf("Expected to get \"%v\", instead of this got \"%v\"", errNameAndTagsTogether, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -27,6 +27,8 @@ repositories:
|
|||||||
dest: "example/path"
|
dest: "example/path"
|
||||||
name: "custom_example"
|
name: "custom_example"
|
||||||
- src: https://github.com/example/example2.git
|
- src: https://github.com/example/example2.git
|
||||||
|
tags:
|
||||||
|
- "example"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
homedir, _ := os.UserHomeDir()
|
homedir, _ := os.UserHomeDir()
|
||||||
@ -43,6 +45,7 @@ repositories:
|
|||||||
Name: "example2",
|
Name: "example2",
|
||||||
Src: "https://github.com/example/example2.git",
|
Src: "https://github.com/example/example2.git",
|
||||||
Dest: "example2",
|
Dest: "example2",
|
||||||
|
Tags: []string{"example"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -12,6 +11,7 @@ const (
|
|||||||
errNotSupportedType = "not supported configuration type"
|
errNotSupportedType = "not supported configuration type"
|
||||||
errMissingWorkspaceField = "missing required \"workspace\" field"
|
errMissingWorkspaceField = "missing required \"workspace\" field"
|
||||||
errMissingSrcField = "missing required field the \"src\" in row %v"
|
errMissingSrcField = "missing required field the \"src\" in row %v"
|
||||||
|
errNameAndTagsTogether = "name and tags arguments connot be used together"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getDuplicateFieldError(field string, name string, rows []int) error {
|
func getDuplicateFieldError(field string, name string, rows []int) error {
|
||||||
@ -21,7 +21,5 @@ func getDuplicateFieldError(field string, name string, rows []int) error {
|
|||||||
rowsInString = append(rowsInString, strconv.Itoa(row))
|
rowsInString = append(rowsInString, strconv.Itoa(row))
|
||||||
}
|
}
|
||||||
|
|
||||||
errorMessage := fmt.Sprintf("The %v \"%v\" is duplicated in rows: %v", field, name, strings.Join(rowsInString, ","))
|
return fmt.Errorf("the %v \"%v\" is duplicated in rows: %v", field, name, strings.Join(rowsInString, ","))
|
||||||
|
|
||||||
return errors.New(errorMessage)
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ type RepositoryConfig struct {
|
|||||||
Name string `yaml:",omitempty"`
|
Name string `yaml:",omitempty"`
|
||||||
Src string `yaml:",omitempty"`
|
Src string `yaml:",omitempty"`
|
||||||
Dest string `yaml:",omitempty"`
|
Dest string `yaml:",omitempty"`
|
||||||
|
Tags []string `yaml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CliArguments struct {
|
type CliArguments struct {
|
||||||
@ -17,4 +18,6 @@ type CliArguments struct {
|
|||||||
Status bool
|
Status bool
|
||||||
Version bool
|
Version bool
|
||||||
Color bool
|
Color bool
|
||||||
|
LimitName string
|
||||||
|
LimitTags []string
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user