From df792aaa8a5c367c2bfab37aeaca6e6690d7db2c Mon Sep 17 00:00:00 2001 From: Puskar Basu Date: Tue, 7 Jan 2025 18:29:19 +0530 Subject: [PATCH 1/2] Support installing mods from Gitlab repositories --- modinstaller/git.go | 54 ++++++++++++++++------------ modinstaller/git_test.go | 46 ++++++++++++++++++++++++ modinstaller/github_access_tokens.go | 2 ++ 3 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 modinstaller/git_test.go diff --git a/modinstaller/git.go b/modinstaller/git.go index 68205c56..a14abc72 100644 --- a/modinstaller/git.go +++ b/modinstaller/git.go @@ -31,6 +31,7 @@ func getGitUrl(modName string, urlMode GitUrlMode) string { } func transformToGitURL(input string, urlMode GitUrlMode) string { + // If HTTPS mode is selected if urlMode == GitUrlModeHTTPS { if !strings.HasPrefix(input, "https://") { input = "https://" + input @@ -38,29 +39,33 @@ func transformToGitURL(input string, urlMode GitUrlMode) string { return input } - if !strings.HasPrefix(input, "github.com") { - return input - } - - if !strings.HasPrefix(input, "git@") { - input = "git@" + input - } + // check for GitHub and GitLab-specific transformations + // gitlab can have domain names like example.gitlab.com + if strings.Contains(input, "github.com") || strings.Contains(input, "gitlab.com") { + // For SSH mode + if !strings.HasPrefix(input, "git@") { + input = "git@" + input + } - if !strings.HasSuffix(input, ".git") { - input += ".git" - } + if !strings.HasSuffix(input, ".git") { + input += ".git" + } - // Add a colon after the "git@github.com" part, so it replaces the first / with : - if !strings.Contains(input, ":") { - index := strings.Index(input, "/") - input = input[:index] + ":" + input[index+1:] + // Add a colon after the "git@" part to replace the first / + if !strings.Contains(input, ":") { + index := strings.Index(input, "/") + if index > -1 { + input = input[:index] + ":" + input[index+1:] + } + } } + // Return the input unmodified for unsupported hosts or already formatted URLs return input } func getRefs(repo string) ([]*plumbing.Reference, error) { - gitHubToken := getGitToken() + gitToken := getGitToken() // Create the remote with repository URL rem := git.NewRemote(memory.NewStorage(), &config.RemoteConfig{ @@ -70,9 +75,9 @@ func getRefs(repo string) ([]*plumbing.Reference, error) { var listOption git.ListOptions // if a token was provided, use it - if gitHubToken != "" { + if gitToken != "" { listOption = git.ListOptions{ - Auth: getGitAuthForToken(gitHubToken), + Auth: getGitAuthForToken(gitToken), } } // load remote references @@ -83,21 +88,26 @@ func getRefs(repo string) ([]*plumbing.Reference, error) { return refs, nil } -func getGitAuthForToken(gitHubToken string) transport.AuthMethod { - if gitHubToken == "" { +func getGitAuthForToken(gitToken string) transport.AuthMethod { + if gitToken == "" { return nil } var auth transport.AuthMethod // if authentication token is an app token, we need to use the GitHub API to list - if strings.HasPrefix(gitHubToken, GitHubAppInstallationAccessTokenPrefix) { + if strings.HasPrefix(gitToken, GitHubAppInstallationAccessTokenPrefix) { // (NOTE: set user to x-access-token - this is required for github application tokens)) auth = &http.BasicAuth{ Username: "x-access-token", - Password: gitHubToken, + Password: gitToken, + } + } else if strings.HasPrefix(gitToken, GitLabPersonalAccessTokenPrefix) { + // for gitlab auth + auth = &http.BasicAuth{ + Password: gitToken, } } else { auth = &http.BasicAuth{ - Username: gitHubToken, + Username: gitToken, } } return auth diff --git a/modinstaller/git_test.go b/modinstaller/git_test.go new file mode 100644 index 00000000..431f2e9c --- /dev/null +++ b/modinstaller/git_test.go @@ -0,0 +1,46 @@ +package modinstaller + +import ( + "testing" +) + +func TestTransformToGitURL(t *testing.T) { + tests := []struct { + name string + input string + urlMode GitUrlMode + expected string + }{ + // GitHub - SSH mode + {"GitHub SSH - Basic", "github.com/user/repo", GitUrlModeSSH, "git@github.com:user/repo.git"}, + {"GitHub SSH - With Git Prefix", "git@github.com/user/repo", GitUrlModeSSH, "git@github.com:user/repo.git"}, + {"GitHub SSH - With .git", "github.com/user/repo.git", GitUrlModeSSH, "git@github.com:user/repo.git"}, + + // GitHub - HTTPS mode + {"GitHub HTTPS - Basic", "github.com/user/repo", GitUrlModeHTTPS, "https://github.com/user/repo"}, + {"GitHub HTTPS - Already HTTPS", "https://github.com/user/repo", GitUrlModeHTTPS, "https://github.com/user/repo"}, + + // GitLab - SSH mode + {"GitLab SSH - Basic", "gitlab.com/user/repo", GitUrlModeSSH, "git@gitlab.com:user/repo.git"}, + {"GitLab SSH - With Git Prefix", "git@gitlab.com/user/repo", GitUrlModeSSH, "git@gitlab.com:user/repo.git"}, + {"GitLab SSH - With .git", "gitlab.com/user/repo.git", GitUrlModeSSH, "git@gitlab.com:user/repo.git"}, + + // GitLab - HTTPS mode + {"GitLab HTTPS - Basic", "gitlab.com/user/repo", GitUrlModeHTTPS, "https://gitlab.com/user/repo"}, + {"GitLab HTTPS - Already HTTPS", "https://gitlab.com/user/repo", GitUrlModeHTTPS, "https://gitlab.com/user/repo"}, + {"GitLab HTTPS - with domain name", "example.gitlab.com/user/repo", GitUrlModeHTTPS, "https://example.gitlab.com/user/repo"}, + + // Edge cases + {"Unsupported Host", "other-host.com/user/repo", GitUrlModeSSH, "other-host.com/user/repo"}, + {"Invalid Input - Empty", "", GitUrlModeSSH, ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := transformToGitURL(tt.input, tt.urlMode) + if got != tt.expected { + t.Errorf("transformToGitURL(%q, %q) = %q; want %q", tt.input, tt.urlMode, got, tt.expected) + } + }) + } +} diff --git a/modinstaller/github_access_tokens.go b/modinstaller/github_access_tokens.go index dc92c5d7..97cba979 100644 --- a/modinstaller/github_access_tokens.go +++ b/modinstaller/github_access_tokens.go @@ -7,4 +7,6 @@ const ( GitHubAppUserAccessTokenPrefix = "ghu_" GitHubAppInstallationAccessTokenPrefix = "ghs_" GitHubAppRefreshTokenPrefix = "ghr_" + GitLabPersonalAccessTokenPrefix = "glpat-" + GitLabProjectAccessTokenPrefx = "glpat-" ) From 5f18d187e60fefa0bcc8c71d3850d42f49ab4863 Mon Sep 17 00:00:00 2001 From: Puskar Basu Date: Tue, 7 Jan 2025 18:31:01 +0530 Subject: [PATCH 2/2] update --- modinstaller/github_access_tokens.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modinstaller/github_access_tokens.go b/modinstaller/github_access_tokens.go index 97cba979..d1e717ee 100644 --- a/modinstaller/github_access_tokens.go +++ b/modinstaller/github_access_tokens.go @@ -8,5 +8,4 @@ const ( GitHubAppInstallationAccessTokenPrefix = "ghs_" GitHubAppRefreshTokenPrefix = "ghr_" GitLabPersonalAccessTokenPrefix = "glpat-" - GitLabProjectAccessTokenPrefx = "glpat-" )