@@ -2,12 +2,20 @@ package ebutil
22
33import (
44 "fmt"
5- "net/url"
65 "strings"
76
87 gittransport "github.com/go-git/go-git/v5/plumbing/transport"
98)
109
10+ type InvalidRepoURLError struct {
11+ repoURL string
12+ inner error
13+ }
14+
15+ func (e * InvalidRepoURLError ) Error () string {
16+ return fmt .Sprintf ("invalid repository URL %q, please see https://github.com/coder/envbuilder/blob/main/docs/git-auth.md for supported formats: %v" , e .repoURL , e .inner )
17+ }
18+
1119type ParsedURL struct {
1220 Protocol string
1321 User string
@@ -21,22 +29,17 @@ type ParsedURL struct {
2129// ParseRepoURL parses the given repository URL into its components.
2230// We used to use chainguard-dev/git-urls for this, but its behaviour
2331// diverges from the go-git URL parser. To ensure consistency, we now
24- // use go-git directly with some tweaks .
32+ // use go-git directly.
2533func ParseRepoURL (repoURL string ) (* ParsedURL , error ) {
26- repoURL = fixupScheme (repoURL , "ssh://" )
27- repoURL = fixupScheme (repoURL , "git://" )
28- repoURL = fixupScheme (repoURL , "git+ssh://" )
29- parsed , err := gittransport .NewEndpoint (repoURL )
30- if err != nil {
31- return nil , fmt .Errorf ("parse repo url %q: %w" , repoURL , err )
32- }
3334 // Trim #reference from path
3435 var reference string
35- if len (parsed .Path ) > 0 { // annoyingly, strings.Index returns 0 if len(s) == 0
36- if idx := strings .Index (parsed .Path , "#" ); idx > - 1 {
37- reference = parsed .Path [idx + 1 :]
38- parsed .Path = parsed .Path [:idx ]
39- }
36+ if idx := strings .Index (repoURL , "#" ); idx > - 1 {
37+ reference = repoURL [idx + 1 :]
38+ repoURL = repoURL [:idx ]
39+ }
40+ parsed , err := gittransport .NewEndpoint (repoURL )
41+ if err != nil {
42+ return nil , & InvalidRepoURLError {repoURL : repoURL , inner : err }
4043 }
4144 return & ParsedURL {
4245 Protocol : parsed .Protocol ,
@@ -48,14 +51,3 @@ func ParseRepoURL(repoURL string) (*ParsedURL, error) {
4851 Reference : reference ,
4952 }, nil
5053}
51-
52- func fixupScheme (repoURL , scheme string ) string {
53- // go-git tries to handle protocol:// URLs with url.Parse. This fails
54- // in the case of e.g. (ssh|git)://git@host:user/path.git
55- if cut , found := strings .CutPrefix (repoURL , scheme ); found {
56- if _ , err := url .Parse (repoURL ); err != nil && strings .Contains (err .Error (), "invalid port" ) {
57- return cut
58- }
59- }
60- return repoURL
61- }
0 commit comments