(repository string)
| 413 | } |
| 414 | |
| 415 | func GitHubRepositoryParts(repository string) (string, string, error) { |
| 416 | repository = strings.TrimSpace(repository) |
| 417 | parsed, errParse := url.Parse(repository) |
| 418 | if errParse != nil { |
| 419 | return "", "", fmt.Errorf("invalid repository URL: %w", errParse) |
| 420 | } |
| 421 | if parsed.Scheme != "https" || parsed.Host != "github.com" || parsed.RawQuery != "" || parsed.Fragment != "" { |
| 422 | return "", "", fmt.Errorf("repository must be https://github.com/{owner}/{repo}") |
| 423 | } |
| 424 | segments := strings.Split(strings.Trim(parsed.EscapedPath(), "/"), "/") |
| 425 | if len(segments) != 2 || segments[0] == "" || segments[1] == "" { |
| 426 | return "", "", fmt.Errorf("repository must be https://github.com/{owner}/{repo}") |
| 427 | } |
| 428 | owner, errOwner := url.PathUnescape(segments[0]) |
| 429 | if errOwner != nil { |
| 430 | return "", "", fmt.Errorf("invalid repository owner: %w", errOwner) |
| 431 | } |
| 432 | repo, errRepo := url.PathUnescape(segments[1]) |
| 433 | if errRepo != nil { |
| 434 | return "", "", fmt.Errorf("invalid repository name: %w", errRepo) |
| 435 | } |
| 436 | if strings.HasSuffix(repo, ".git") { |
| 437 | return "", "", fmt.Errorf("repository must be https://github.com/{owner}/{repo}") |
| 438 | } |
| 439 | return owner, repo, nil |
| 440 | } |
| 441 | |
| 442 | func (r Registry) PluginByID(id string) (Plugin, bool) { |
| 443 | id = strings.TrimSpace(id) |
no outgoing calls