aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bridge/gitlab/config.go110
-rw-r--r--bridge/gitlab/config_test.go2
2 files changed, 94 insertions, 18 deletions
diff --git a/bridge/gitlab/config.go b/bridge/gitlab/config.go
index 3a48ec4e..1f542d39 100644
--- a/bridge/gitlab/config.go
+++ b/bridge/gitlab/config.go
@@ -43,8 +43,16 @@ func (g *Gitlab) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor
return nil, fmt.Errorf("you must provide a project URL to configure this bridge with a token")
}
- if params.URL == "" {
- params.URL = defaultBaseURL
+ var baseUrl string
+
+ switch {
+ case params.BaseURL != "":
+ baseUrl = params.BaseURL
+ default:
+ baseUrl, err = promptBaseUrlOptions()
+ if err != nil {
+ return nil, errors.Wrap(err, "base url prompt")
+ }
}
var url string
@@ -55,7 +63,7 @@ func (g *Gitlab) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor
url = params.URL
default:
// terminal prompt
- url, err = promptURL(repo)
+ url, err = promptURL(repo, baseUrl)
if err != nil {
return nil, errors.Wrap(err, "url prompt")
}
@@ -102,14 +110,14 @@ func (g *Gitlab) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor
}
// validate project url and get its ID
- id, err := validateProjectURL(params.BaseURL, url, token)
+ id, err := validateProjectURL(baseUrl, url, token)
if err != nil {
return nil, errors.Wrap(err, "project validation")
}
conf[core.ConfigKeyTarget] = target
conf[keyProjectID] = strconv.Itoa(id)
- conf[keyGitlabBaseUrl] = params.BaseURL
+ conf[keyGitlabBaseUrl] = baseUrl
err = g.ValidateConfig(conf)
if err != nil {
@@ -133,7 +141,9 @@ func (g *Gitlab) ValidateConfig(conf core.Configuration) error {
} else if v != target {
return fmt.Errorf("unexpected target name: %v", v)
}
-
+ if _, ok := conf[keyGitlabBaseUrl]; !ok {
+ return fmt.Errorf("missing %s key", keyGitlabBaseUrl)
+ }
if _, ok := conf[keyProjectID]; !ok {
return fmt.Errorf("missing %s key", keyProjectID)
}
@@ -141,6 +151,64 @@ func (g *Gitlab) ValidateConfig(conf core.Configuration) error {
return nil
}
+func promptBaseUrlOptions() (string, error) {
+ for {
+ fmt.Printf("Gitlab base url:\n")
+ fmt.Printf("[0]: https://gitlab.com\n")
+ fmt.Printf("[1]: enter your own base url\n")
+ fmt.Printf("Select option: ")
+
+ line, err := bufio.NewReader(os.Stdin).ReadString('\n')
+ if err != nil {
+ return "", err
+ }
+
+ line = strings.TrimSpace(line)
+
+ index, err := strconv.Atoi(line)
+ if err != nil || index < 0 || index > 1 {
+ fmt.Println("invalid input")
+ continue
+ }
+
+ switch index {
+ case 0:
+ return defaultBaseURL, nil
+ case 1:
+ return promptBaseUrl()
+ }
+ }
+}
+
+func promptBaseUrl() (string, error) {
+ for {
+ fmt.Print("Base url: ")
+
+ line, err := bufio.NewReader(os.Stdin).ReadString('\n')
+ if err != nil {
+ return "", err
+ }
+
+ line = strings.TrimSpace(line)
+
+ ok, err := validateBaseUrl(line)
+ if err != nil {
+ return "", err
+ }
+ if ok {
+ return line, nil
+ }
+ }
+}
+
+func validateBaseUrl(baseUrl string) (bool, error) {
+ u, err := url.Parse(baseUrl)
+ if err != nil {
+ return false, err
+ }
+ return u.Scheme != "" && u.Host != "", nil
+}
+
func promptTokenOptions(repo repository.RepoConfig, userId entity.Id) (auth.Credential, error) {
for {
creds, err := auth.List(repo, auth.WithUserId(userId), auth.WithTarget(target), auth.WithKind(auth.KindToken))
@@ -210,7 +278,7 @@ func promptToken() (string, error) {
fmt.Println("'api' access scope: to be able to make api calls")
fmt.Println()
- re, err := regexp.Compile(`^[a-zA-Z0-9\-]{20}`)
+ re, err := regexp.Compile(`^[a-zA-Z0-9\-\_]{20}`)
if err != nil {
panic("regexp compile:" + err.Error())
}
@@ -232,14 +300,14 @@ func promptToken() (string, error) {
}
}
-func promptURL(repo repository.RepoCommon) (string, error) {
+func promptURL(repo repository.RepoCommon, baseUrl string) (string, error) {
// remote suggestions
remotes, err := repo.GetRemotes()
if err != nil {
return "", errors.Wrap(err, "getting remotes")
}
- validRemotes := getValidGitlabRemoteURLs(remotes)
+ validRemotes := getValidGitlabRemoteURLs(baseUrl, remotes)
if len(validRemotes) > 0 {
for {
fmt.Println("\nDetected projects:")
@@ -293,7 +361,7 @@ func promptURL(repo repository.RepoCommon) (string, error) {
}
}
-func getProjectPath(projectUrl string) (string, error) {
+func getProjectPath(baseUrl, projectUrl string) (string, error) {
cleanUrl := strings.TrimSuffix(projectUrl, ".git")
cleanUrl = strings.Replace(cleanUrl, "git@", "https://", 1)
objectUrl, err := url.Parse(cleanUrl)
@@ -301,37 +369,45 @@ func getProjectPath(projectUrl string) (string, error) {
return "", ErrBadProjectURL
}
+ objectBaseUrl, err := url.Parse(baseUrl)
+ if err != nil {
+ return "", ErrBadProjectURL
+ }
+
+ if objectUrl.Hostname() != objectBaseUrl.Hostname() {
+ return "", fmt.Errorf("base url and project url hostnames doesn't match")
+ }
return objectUrl.Path[1:], nil
}
-func getValidGitlabRemoteURLs(remotes map[string]string) []string {
+func getValidGitlabRemoteURLs(baseUrl string, remotes map[string]string) []string {
urls := make([]string, 0, len(remotes))
for _, u := range remotes {
- path, err := getProjectPath(u)
+ path, err := getProjectPath(baseUrl, u)
if err != nil {
continue
}
- urls = append(urls, fmt.Sprintf("%s%s", "gitlab.com", path))
+ urls = append(urls, fmt.Sprintf("%s/%s", baseUrl, path))
}
return urls
}
-func validateProjectURL(baseURL, url string, token *auth.Token) (int, error) {
- projectPath, err := getProjectPath(url)
+func validateProjectURL(baseUrl, url string, token *auth.Token) (int, error) {
+ projectPath, err := getProjectPath(baseUrl, url)
if err != nil {
return 0, err
}
- client, err := buildClient(baseURL, token)
+ client, err := buildClient(baseUrl, token)
if err != nil {
return 0, err
}
project, _, err := client.Projects.GetProject(projectPath, &gitlab.GetProjectOptions{})
if err != nil {
- return 0, err
+ return 0, errors.Wrap(err, "wrong token scope ou inexistent project")
}
return project.ID, nil
diff --git a/bridge/gitlab/config_test.go b/bridge/gitlab/config_test.go
index 87469796..43ed649a 100644
--- a/bridge/gitlab/config_test.go
+++ b/bridge/gitlab/config_test.go
@@ -82,7 +82,7 @@ func TestProjectPath(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- path, err := getProjectPath(tt.args.url)
+ path, err := getProjectPath(defaultBaseURL, tt.args.url)
assert.Equal(t, tt.want.path, path)
assert.Equal(t, tt.want.err, err)
})