parseGitURL parses a git URL that may contain a subdirectory path. It supports GitHub and GitLab "tree" URLs like: https://github.com/owner/repo/tree/branch/path/to/plugin https://gitlab.com/owner/repo/-/tree/branch/path/to/plugin Returns (cloneURL, branch, subDir). For plain repo URLs, branch a
(rawURL string)
| 399 | // |
| 400 | // Returns (cloneURL, branch, subDir). For plain repo URLs, branch and subDir are empty. |
| 401 | func parseGitURL(rawURL string) (cloneURL, branch, subDir string) { |
| 402 | // GitHub: https://github.com/{owner}/{repo}/tree/{branch}/{path...} |
| 403 | if idx := strings.Index(rawURL, "/tree/"); idx != -1 { |
| 404 | repoBase := rawURL[:idx] |
| 405 | rest := rawURL[idx+len("/tree/"):] |
| 406 | |
| 407 | // rest = "branch/path/to/plugin" or just "branch" |
| 408 | if slashIdx := strings.IndexByte(rest, '/'); slashIdx != -1 { |
| 409 | branch = rest[:slashIdx] |
| 410 | subDir = rest[slashIdx+1:] |
| 411 | } else { |
| 412 | branch = rest |
| 413 | } |
| 414 | // Remove trailing slashes from subDir |
| 415 | subDir = strings.TrimRight(subDir, "/") |
| 416 | return repoBase + ".git", branch, subDir |
| 417 | } |
| 418 | |
| 419 | // GitLab: https://gitlab.com/{owner}/{repo}/-/tree/{branch}/{path...} |
| 420 | if idx := strings.Index(rawURL, "/-/tree/"); idx != -1 { |
| 421 | repoBase := rawURL[:idx] |
| 422 | rest := rawURL[idx+len("/-/tree/"):] |
| 423 | |
| 424 | if slashIdx := strings.IndexByte(rest, '/'); slashIdx != -1 { |
| 425 | branch = rest[:slashIdx] |
| 426 | subDir = rest[slashIdx+1:] |
| 427 | } else { |
| 428 | branch = rest |
| 429 | } |
| 430 | subDir = strings.TrimRight(subDir, "/") |
| 431 | return repoBase + ".git", branch, subDir |
| 432 | } |
| 433 | |
| 434 | // Plain URL — return as-is. |
| 435 | return rawURL, "", "" |
| 436 | } |