package cmd import ( "fmt" "os/exec" "regexp" "strings" ) // parseOwnerRepo splits "owner/repo" into its parts. func parseOwnerRepo(s string) (owner, repo string, err error) { s = strings.TrimSuffix(strings.TrimSpace(s), ".git") parts := strings.Split(s, "/") if len(parts) != 2 || parts[0] == "" || parts[1] == "" { return "", "", fmt.Errorf("expected owner/repo, got %q", s) } return parts[0], parts[1], nil } // resolveRepo determines the target repo: an explicit --repo flag ("owner/repo") // wins; otherwise it infers "owner/repo" from the git "origin" remote of the // current directory. func resolveRepo(flagRepo string) (owner, repo string, err error) { if flagRepo != "" { return parseOwnerRepo(flagRepo) } url, err := gitOriginURL() if err != nil { return "", "", fmt.Errorf("no --repo given and could not infer from git remote: %w", err) } o, r, err := ownerRepoFromRemote(url) if err != nil { return "", "", fmt.Errorf("could not parse owner/repo from remote %q: %w", url, err) } return o, r, nil } func gitOriginURL() (string, error) { out, err := exec.Command("git", "remote", "get-url", "origin").Output() if err != nil { return "", err } return strings.TrimSpace(string(out)), nil } // remotePathRe captures the trailing owner/repo of a git remote URL, whether // http(s)://host/owner/repo(.git), ssh://git@host:port/owner/repo(.git), or // git@host:owner/repo(.git). var remotePathRe = regexp.MustCompile(`[:/]([^/:]+)/([^/]+?)(?:\.git)?/?$`) func ownerRepoFromRemote(url string) (owner, repo string, err error) { m := remotePathRe.FindStringSubmatch(url) if m == nil { return "", "", fmt.Errorf("unrecognized remote URL") } return m[1], m[2], nil }