github.com/harryzcy/snuuze@v0.3.3-0.20240314015559-83a8fc5627a8/platform/common.go (about) 1 package platform 2 3 import ( 4 "context" 5 "errors" 6 "strings" 7 8 "github.com/harryzcy/snuuze/config" 9 "github.com/harryzcy/snuuze/types" 10 ) 11 12 var ( 13 ErrUnimplemented = errors.New("not implemented") 14 ErrInvalidGitPlatform = errors.New("unsupported git platform") 15 ErrInvalidGitURL = errors.New("invalid git url") 16 ErrInvalidServerURL = errors.New("invalid server URL") 17 ErrNoInsecureServer = errors.New("insecure server is not supported") 18 ErrServerRequired = errors.New("server is required") 19 ) 20 21 type Client interface { 22 Token(ctx context.Context) (string, error) 23 24 ListRepos() ([]Repo, error) 25 // ListTags returns a sorted list of tags for the given repo 26 ListTags(params *ListTagsInput) ([]string, error) 27 28 CreatePullRequest(input *CreatePullRequestInput) error 29 } 30 31 type GitPlatform int 32 33 const ( 34 GitPlatformUnknown GitPlatform = iota 35 GitPlatformGitHub 36 GitPlatformGitea 37 ) 38 39 type NewClientOptions struct { 40 Platform GitPlatform 41 URL string 42 } 43 44 // NewClient returns a new Client based on Git URL 45 func NewClient(options NewClientOptions) (Client, error) { 46 platform := options.Platform 47 var host string 48 if platform == GitPlatformUnknown || platform == GitPlatformGitea { 49 platform, host = DetermineGitPlatform(options.URL) 50 } 51 52 switch platform { 53 case GitPlatformGitHub: 54 return NewGitHubClient() 55 case GitPlatformGitea: 56 return NewGiteaClient(host), nil 57 } 58 59 return nil, ErrInvalidGitPlatform 60 } 61 62 var getGiteaConfigs = func() []types.GiteaConfig { 63 return config.GetHostingConfig().Gitea 64 } 65 66 // DetermineGitPlatform returns the GitPlatform and the host of the given git URL 67 func DetermineGitPlatform(gitURL string) (GitPlatform, string) { 68 urlInfo, err := parseURL(gitURL) 69 if err != nil { 70 return GitPlatformUnknown, "" 71 } 72 73 if urlInfo.host == "github.com" { 74 return GitPlatformGitHub, "https://github.com" 75 } 76 77 for _, giteaConfig := range getGiteaConfigs() { 78 configuredHost := giteaConfig.GetHost() 79 configuredInfo, err := parseURL(configuredHost) 80 if err != nil { 81 continue 82 } 83 84 if urlInfo.host == configuredInfo.host { 85 return GitPlatformGitea, configuredHost 86 } 87 } 88 89 return GitPlatformUnknown, "" 90 } 91 92 type hostInfo struct { 93 protocol string 94 host string 95 } 96 97 func parseURL(url string) (*hostInfo, error) { 98 for _, protocol := range []string{"https", "http"} { 99 prefix := protocol + "://" 100 if strings.HasPrefix(url, prefix) { 101 url = strings.TrimPrefix(url, prefix) 102 url = strings.SplitN(url, "/", 2)[0] 103 return &hostInfo{ 104 protocol: protocol, 105 host: url, 106 }, nil 107 } 108 } 109 110 if strings.HasPrefix(url, "git@") { 111 url = strings.TrimPrefix(url, "git@") 112 url = strings.SplitN(url, ":", 2)[0] 113 return &hostInfo{ 114 protocol: "ssh", 115 host: url, 116 }, nil 117 } 118 119 return nil, ErrInvalidGitURL 120 } 121 122 type Repo struct { 123 Server string `json:"server"` 124 Owner string `json:"owner"` 125 Repo string `json:"repo"` 126 URL string `json:"url"` 127 IsPrivate bool `json:"isPrivate"` 128 DefaultBranch string `json:"defaultBranch"` 129 } 130 131 type ListTagsInput struct { 132 Owner string 133 Repo string 134 Prefix string // optional 135 } 136 137 type CreatePullRequestInput struct { 138 Title string 139 Body string 140 Base string 141 Head string 142 Owner string 143 Repo string 144 }