diff --git a/pkg/cmd/add_repo.go b/pkg/cmd/add_repo.go index 00b8fce4e..9cd448a2a 100644 --- a/pkg/cmd/add_repo.go +++ b/pkg/cmd/add_repo.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/cobra" "github.com/ZupIT/ritchie-cli/pkg/api" + "github.com/ZupIT/ritchie-cli/pkg/credential" "github.com/ZupIT/ritchie-cli/pkg/formula" "github.com/ZupIT/ritchie-cli/pkg/formula/tree" "github.com/ZupIT/ritchie-cli/pkg/prompt" @@ -39,6 +40,12 @@ const ( priorityFlagName = "priority" tokenFlagName = "token" tagFlagName = "tag" + permissionError = ` + permission error: + You must overwrite the current token (%s-add-repo) with command: + rit set credential + Or switch to a new environment with the command: + rit set env` ) var ErrRepoNameNotEmpty = errors.New("the field repository name must not be empty") @@ -85,8 +92,8 @@ var addRepoFlags = flags{ type addRepoCmd struct { repo formula.RepositoryAddLister repoProviders formula.RepoProviders + cred credential.Resolver prompt.InputTextValidator - prompt.InputPassword prompt.InputURL prompt.InputList prompt.InputBool @@ -99,8 +106,8 @@ type addRepoCmd struct { func NewAddRepoCmd( repo formula.RepositoryAddLister, repoProviders formula.RepoProviders, + resolver credential.Resolver, inText prompt.InputTextValidator, - inPass prompt.InputPassword, inURL prompt.InputURL, inList prompt.InputList, inBool prompt.InputBool, @@ -117,10 +124,10 @@ func NewAddRepoCmd( InputList: inList, InputBool: inBool, InputInt: inInt, - InputPassword: inPass, tutorial: rtf, tree: treeChecker, detail: rd, + cred: resolver, } cmd := &cobra.Command{ Use: "repo", @@ -223,7 +230,7 @@ func (ar *addRepoCmd) resolvePrompt() (formula.Repo, error) { var token string if isPrivate { - token, err = ar.Password("Personal access tokens:") + token, err = ar.cred.Resolve("CREDENTIAL_" + provider + "-ADD-REPO_TOKEN") if err != nil { return formula.Repo{}, err } @@ -234,6 +241,10 @@ func (ar *addRepoCmd) resolvePrompt() (formula.Repo, error) { gitRepoInfo := git.NewRepoInfo(url, token) tags, err := git.Repos.Tags(gitRepoInfo) if err != nil { + if strings.Contains(err.Error(), "401") { + errorString := fmt.Sprintf(permissionError, provider) + return formula.Repo{}, errors.New(errorString) + } return formula.Repo{}, err } @@ -383,7 +394,7 @@ func (ar addRepoCmd) runStdin() CommandRunnerFunc { } } -func (ad addRepoCmd) repoNameValidator(text interface{}) error { +func (ar addRepoCmd) repoNameValidator(text interface{}) error { in := text.(string) if in == "" { return ErrRepoNameNotEmpty diff --git a/pkg/cmd/add_repo_test.go b/pkg/cmd/add_repo_test.go index 20bd17408..0e2407ea4 100644 --- a/pkg/cmd/add_repo_test.go +++ b/pkg/cmd/add_repo_test.go @@ -34,18 +34,12 @@ import ( func TestAddRepoCmd(t *testing.T) { someError := errors.New("some error") - - gitRepo := new(mocks.GitRepositoryMock) - gitRepo.On("Zipball", mock.Anything, mock.Anything).Return(nil, nil) - gitRepo.On("Tags", mock.Anything).Return(git.Tags{git.Tag{Name: "1.0.0"}}, nil) - gitRepo.On("LatestTag", mock.Anything).Return(git.Tag{Name: "2.0.0"}, nil) - - repoProviders := formula.NewRepoProviders() - repoProviders.Add("Github", formula.Git{Repos: gitRepo, NewRepoInfo: github.NewRepoInfo}) - repoProviders.Add("GitLab", formula.Git{Repos: gitRepositoryWithoutTagsMock, NewRepoInfo: github.NewRepoInfo}) - repoProviders.Add("Bitbucket", formula.Git{Repos: gitRepositoryErrorsMock, NewRepoInfo: github.NewRepoInfo}) - - repoList := repoProviders.List() + unauthorizedError := errors.New(` + permission error: + You must overwrite the current token (Github-add-repo) with command: + rit set credential + Or switch to a new environment with the command: + rit set env`) repoTest := &formula.Repo{ Provider: "Github", @@ -69,6 +63,8 @@ func TestAddRepoCmd(t *testing.T) { return inputListMock } + providers := []string{"Bitbucket", "GitLab", "Github"} + tests := []struct { name string args []string @@ -139,18 +135,19 @@ func TestAddRepoCmd(t *testing.T) { want: someError, }, { - name: "input bool error", - args: []string{}, + name: "Fail when repo.Add return 401 err", fields: fields{ - InputBool: returnOfInputBool{false, someError}, + repo: returnOfRepoListerAdder{errAdd: someError, reposList: formula.Repos{}, errList: nil}, + InputList: []returnOfInputList{{response: "Github", err: nil}}, + gitRepoTag: returnOfGitRepoTag{nil, errors.New("401 - Unauthorized")}, }, - want: someError, + want: unauthorizedError, }, { - name: "input password error", + name: "input bool error", args: []string{}, fields: fields{ - InputPassword: returnWithStringErr{"", someError}, + InputBool: returnOfInputBool{false, someError}, }, want: someError, }, @@ -249,7 +246,7 @@ func TestAddRepoCmd(t *testing.T) { name: "fail flags with wrong provider", args: []string{"--provider=github"}, fields: fields{}, - want: errors.New("please select a provider from " + strings.Join(repoList, ", ")), + want: errors.New("please select a provider from " + strings.Join(providers, ", ")), }, { name: "fail flags with empty name", @@ -286,6 +283,16 @@ func TestAddRepoCmd(t *testing.T) { t.Run(tt.name, func(t *testing.T) { fields := getFields(tt.fields) + gitRepo := new(mocks.GitRepositoryMock) + gitRepo.On("Zipball", mock.Anything, mock.Anything).Return(nil, nil) + gitRepo.On("Tags", mock.Anything).Return(fields.gitRepoTag.Tags, fields.gitRepoTag.error) + gitRepo.On("LatestTag", mock.Anything).Return(git.Tag{}, nil) + + repoProviders := formula.NewRepoProviders() + repoProviders.Add("Github", formula.Git{Repos: gitRepo, NewRepoInfo: github.NewRepoInfo}) + repoProviders.Add("GitLab", formula.Git{Repos: gitRepositoryWithoutTagsMock, NewRepoInfo: github.NewRepoInfo}) + repoProviders.Add("Bitbucket", formula.Git{Repos: gitRepositoryErrorsMock, NewRepoInfo: github.NewRepoInfo}) + detailMock := new(mocks.DetailManagerMock) detailMock.On("LatestTag", mock.Anything).Return(fields.detailLatestTag) inputURLMock := new(mocks.InputURLMock) @@ -295,8 +302,6 @@ func TestAddRepoCmd(t *testing.T) { inputListMock := addInputList(fields.InputList) inputIntMock := new(mocks.InputIntMock) inputIntMock.On("Int", mock.Anything, mock.Anything).Return(int64(0), nil) - inputPasswordMock := new(mocks.InputPasswordMock) - inputPasswordMock.On("Password", mock.Anything, mock.Anything).Return(fields.InputPassword.string, fields.InputPassword.error) inputTextValidatorMock := new(mocks.InputTextValidatorMock) inputTextValidatorMock.On("Text", mock.Anything, mock.Anything).Return(fields.InputTextValidator.string, nil) tutorialFindMock := new(mocks.TutorialFindSetterMock) @@ -304,12 +309,14 @@ func TestAddRepoCmd(t *testing.T) { repoListerAdderMock := new(mocks.RepoManager) repoListerAdderMock.On("Add", mock.Anything).Return(fields.repo.errAdd) repoListerAdderMock.On("List").Return(fields.repo.reposList, fields.repo.errList) + credResolverMock := new(mocks.CredResolverMock) + credResolverMock.On("Resolve", mock.Anything).Return(fields.credResolver.string, fields.credResolver.error) cmd := NewAddRepoCmd( repoListerAdderMock, repoProviders, + credResolverMock, inputTextValidatorMock, - inputPasswordMock, inputURLMock, inputListMock, inputBoolMock, @@ -355,41 +362,49 @@ type returnOfRepoListerAdder struct { reposList formula.Repos } +type returnOfGitRepoTag struct { + git.Tags + error +} + type fields struct { repo returnOfRepoListerAdder InputTextValidator returnWithStringErr - InputPassword returnWithStringErr InputURL returnWithStringErr InputList []returnOfInputList InputBool returnOfInputBool stdin string detailLatestTag string tutorialStatus returnWithStringErr + credResolver returnWithStringErr + gitRepoTag returnOfGitRepoTag } func getFields(testFields fields) fields { fieldsNil := fields{ repo: returnOfRepoListerAdder{}, InputTextValidator: returnWithStringErr{}, - InputPassword: returnWithStringErr{}, InputURL: returnWithStringErr{}, InputBool: returnOfInputBool{}, InputList: []returnOfInputList{}, stdin: "", detailLatestTag: "", tutorialStatus: returnWithStringErr{}, + credResolver: returnWithStringErr{}, + gitRepoTag: returnOfGitRepoTag{}, } fields := fields{ repo: returnOfRepoListerAdder{errAdd: nil, reposList: formula.Repos{}, errList: nil}, InputTextValidator: returnWithStringErr{"mocked text", nil}, - InputPassword: returnWithStringErr{"s3cr3t", nil}, InputURL: returnWithStringErr{"http://localhost/mocked", nil}, InputBool: returnOfInputBool{true, nil}, InputList: []returnOfInputList{{response: "Github", err: nil}}, tutorialStatus: returnWithStringErr{"disabled", nil}, stdin: "", detailLatestTag: "", + credResolver: returnWithStringErr{"token", nil}, + gitRepoTag: returnOfGitRepoTag{git.Tags{git.Tag{Name: "1.0.0"}}, nil}, } if testFields.repo.reposList.Len() != fieldsNil.repo.reposList.Len() || testFields.repo.errAdd != fieldsNil.repo.errAdd || testFields.repo.errList != fieldsNil.repo.errList { @@ -400,10 +415,6 @@ func getFields(testFields fields) fields { fields.InputTextValidator = testFields.InputTextValidator } - if testFields.InputPassword != fieldsNil.InputPassword { - fields.InputPassword = testFields.InputPassword - } - if testFields.InputURL != fieldsNil.InputURL { fields.InputURL = testFields.InputURL } @@ -428,5 +439,13 @@ func getFields(testFields fields) fields { fields.detailLatestTag = testFields.detailLatestTag } + if testFields.credResolver != fieldsNil.credResolver { + fields.credResolver = testFields.credResolver + } + + if len(testFields.gitRepoTag.Tags) != len(fieldsNil.gitRepoTag.Tags) || testFields.gitRepoTag.error != fieldsNil.gitRepoTag.error { + fields.gitRepoTag = testFields.gitRepoTag + } + return fields } diff --git a/pkg/commands/builder.go b/pkg/commands/builder.go index 68f0d07eb..a41ce9701 100644 --- a/pkg/commands/builder.go +++ b/pkg/commands/builder.go @@ -238,8 +238,7 @@ func Build() *cobra.Command { deleteEnvCmd := cmd.NewDeleteEnvCmd(envFindRemover, inputBool, inputList) setEnvCmd := cmd.NewSetEnvCmd(envFindSetter, inputText, inputList) showEnvCmd := cmd.NewShowEnvCmd(envFinder) - addRepoCmd := cmd.NewAddRepoCmd(repoAddLister, repoProviders, inputTextValidator, inputPassword, inputURL, inputList, inputBool, inputInt, tutorialFinder, treeChecker, repoDetail) - + addRepoCmd := cmd.NewAddRepoCmd(repoAddLister, repoProviders, credResolver, inputTextValidator, inputURL, inputList, inputBool, inputInt, tutorialFinder, treeChecker, repoDetail) updateRepoCmd := cmd.NewUpdateRepoCmd(http.DefaultClient, repoListUpdater, repoProviders, inputText, inputPassword, inputURL, inputList, inputBool, inputInt) listRepoCmd := cmd.NewListRepoCmd(repoLister, tutorialFinder) deleteRepoCmd := cmd.NewDeleteRepoCmd(repoLister, inputList, inputBool, repoDeleter)