-
Notifications
You must be signed in to change notification settings - Fork 7k
Issue #34 - Support ssh git URLs and ssh key authentication #37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ package git | |
|
|
||
| import ( | ||
| "fmt" | ||
| "io/ioutil" | ||
| "net/url" | ||
| "os" | ||
| "os/exec" | ||
|
|
@@ -11,20 +12,59 @@ import ( | |
|
|
||
| // NormalizeGitURL normalizes a git URL for lookup and storage | ||
| func NormalizeGitURL(repo string) string { | ||
| repoURL, _ := url.Parse(repo) | ||
| repoURL, err := url.Parse(repo) | ||
| if err != nil { | ||
| return strings.ToLower(repo) | ||
| } | ||
| return repoURL.String() | ||
| } | ||
|
|
||
| // IsSshURL returns true is supplied URL is SSH URL | ||
| func IsSshURL(url string) bool { | ||
| return strings.Index(url, "git@") == 0 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexmt The URL library for Golang has a URL parser that returns a URL struct where you can access the scheme, user, and other attributes. Wondering if this might help make this function more robust. Edited to add: maybe Parse (which you use above) is more appropriate if we want to support URLs without a scheme attached.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also wondering if a unit test could be written for this function.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, URL parser considers SSH URL invalid and returns error. Therefore I had to use |
||
| } | ||
|
|
||
| // GetGitCommandOptions returns URL and env options for git operation | ||
| func GetGitCommandEnvAndURL(repo, username, password string, sshPrivateKey string) (string, []string, error) { | ||
| cmdURL := repo | ||
| env := os.Environ() | ||
| if IsSshURL(repo) { | ||
| if sshPrivateKey != "" { | ||
| sshFile, err := ioutil.TempFile("", "") | ||
| if err != nil { | ||
| return "", nil, err | ||
| } | ||
| _, err = sshFile.WriteString(sshPrivateKey) | ||
| if err != nil { | ||
| return "", nil, err | ||
| } | ||
| err = sshFile.Close() | ||
| if err != nil { | ||
| return "", nil, err | ||
| } | ||
| env = append(env, fmt.Sprintf("GIT_SSH_COMMAND=ssh -i %s", sshFile.Name())) | ||
| } | ||
| } else { | ||
| env = append(env, "GIT_ASKPASS=") | ||
| repoURL, err := url.ParseRequestURI(repo) | ||
| if err != nil { | ||
| return "", nil, err | ||
| } | ||
|
|
||
| repoURL.User = url.UserPassword(username, password) | ||
| cmdURL = repoURL.String() | ||
| } | ||
| return cmdURL, env, nil | ||
| } | ||
|
|
||
| // TestRepo tests if a repo exists and is accessible with the given credentials | ||
| func TestRepo(repo, username, password string) error { | ||
| repoURL, err := url.ParseRequestURI(repo) | ||
| func TestRepo(repo, username, password string, sshPrivateKey string) error { | ||
| repo, env, err := GetGitCommandEnvAndURL(repo, username, password, sshPrivateKey) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| repoURL.User = url.UserPassword(username, password) | ||
| cmd := exec.Command("git", "ls-remote", repoURL.String(), "HEAD") | ||
| env := os.Environ() | ||
| env = append(env, "GIT_ASKPASS=") | ||
| cmd := exec.Command("git", "ls-remote", repo, "HEAD") | ||
|
|
||
| cmd.Env = env | ||
| _, err = cmd.Output() | ||
| if err != nil { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package git | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func TestReturnsTrueForSSHUrl(t *testing.T) { | ||
| assert.True(t, IsSshURL("git@github.com:test.git")) | ||
| } | ||
|
|
||
| func TestReturnsFalseForNonSSHUrl(t *testing.T) { | ||
| assert.False(t, IsSshURL("https://github.com/test.git")) | ||
| } | ||
|
|
||
| func TestNormalizeUrl(t *testing.T) { | ||
| assert.Equal(t, NormalizeGitURL("git@GITHUB.com:test.git"), "git@github.com:test.git") | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering about unit tests for this function, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.