github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/url/url.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package url 7 8 import ( 9 "fmt" 10 stdurl "net/url" 11 "strings" 12 ) 13 14 // ErrWrongURLFormat represents an error with wrong url format 15 type ErrWrongURLFormat struct { 16 URL string 17 } 18 19 func (err ErrWrongURLFormat) Error() string { 20 return fmt.Sprintf("git URL %s format is wrong", err.URL) 21 } 22 23 // GitURL represents a git URL 24 type GitURL struct { 25 *stdurl.URL 26 extraMark int // 0 no extra 1 scp 2 file path with no prefix 27 } 28 29 // String returns the URL's string 30 func (u *GitURL) String() string { 31 switch u.extraMark { 32 case 0: 33 return u.URL.String() 34 case 1: 35 return fmt.Sprintf("%s@%s:%s", u.User.Username(), u.Host, u.Path) 36 case 2: 37 return u.Path 38 default: 39 return "" 40 } 41 } 42 43 // Parse parse all kinds of git URL 44 func Parse(remote string) (*GitURL, error) { 45 if strings.Contains(remote, "://") { 46 u, err := stdurl.Parse(remote) 47 if err != nil { 48 return nil, err 49 } 50 return &GitURL{URL: u}, nil 51 } else if strings.Contains(remote, "@") && strings.Contains(remote, ":") { 52 url := stdurl.URL{ 53 Scheme: "ssh", 54 } 55 squareBrackets := false 56 lastIndex := -1 57 FOR: 58 for i := 0; i < len(remote); i++ { 59 switch remote[i] { 60 case '@': 61 url.User = stdurl.User(remote[:i]) 62 lastIndex = i + 1 63 case ':': 64 if !squareBrackets { 65 url.Host = strings.ReplaceAll(remote[lastIndex:i], "%25", "%") 66 if len(remote) <= i+1 { 67 return nil, ErrWrongURLFormat{URL: remote} 68 } 69 url.Path = remote[i+1:] 70 break FOR 71 } 72 case '[': 73 squareBrackets = true 74 case ']': 75 squareBrackets = false 76 } 77 } 78 return &GitURL{ 79 URL: &url, 80 extraMark: 1, 81 }, nil 82 } 83 84 return &GitURL{ 85 URL: &stdurl.URL{ 86 Scheme: "file", 87 Path: remote, 88 }, 89 extraMark: 2, 90 }, nil 91 }