gitlink-cli/internal/context/repo.go

92 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package context
import (
"fmt"
"net/url"
"os/exec"
"strings"
)
// ResolveOwnerRepo auto-detects owner and repo from git remote origin.
// Returns the explicitly provided values if non-empty.
func ResolveOwnerRepo(flagOwner, flagRepo string) (string, string, error) {
if flagOwner != "" && flagRepo != "" {
return flagOwner, flagRepo, nil
}
owner, repo, err := fromGitRemote()
if err != nil {
if flagOwner == "" || flagRepo == "" {
return "", "", fmt.Errorf("无法自动检测 owner/repo: %w\n 请使用 --owner 和 --repo 参数显式指定,或切换到 git 仓库目录下执行", err)
}
}
if flagOwner != "" {
owner = flagOwner
}
if flagRepo != "" {
repo = flagRepo
}
return owner, repo, nil
}
func fromGitRemote() (string, string, error) {
out, err := exec.Command("git", "remote", "get-url", "origin").Output()
if err != nil {
return "", "", fmt.Errorf("not a git repository or no remote 'origin'")
}
remote := strings.TrimSpace(string(out))
return parseRemoteURL(remote)
}
func parseRemoteURL(remote string) (string, string, error) {
// SSH format: git@www.gitlink.org.cn:owner/repo.git
if strings.HasPrefix(remote, "git@") {
parts := strings.SplitN(remote, ":", 2)
if len(parts) != 2 {
return "", "", fmt.Errorf("cannot parse SSH remote: %s", remote)
}
return parsePathSegments(parts[1])
}
// HTTPS format: https://www.gitlink.org.cn/owner/repo.git
u, err := url.Parse(remote)
if err != nil {
return "", "", fmt.Errorf("cannot parse remote URL: %s", remote)
}
return parsePathSegments(u.Path)
}
func parsePathSegments(path string) (string, string, error) {
// 处理URL路径格式可能包含域名前缀
// 例如://www.gitlink.org.cn/zzx-coder/gitlink-cli 或 /zzx-coder/gitlink-cli
// 先去掉域名部分(如果存在)
if strings.HasPrefix(path, "//www.gitlink.org.cn/") {
path = strings.TrimPrefix(path, "//www.gitlink.org.cn/")
} else if strings.HasPrefix(path, "//") {
// 处理其他可能的域名格式:找到第二个斜杠后的内容
if idx := strings.Index(path[2:], "/"); idx != -1 {
path = path[2+idx+1:]
} else {
path = path[2:]
}
} else if strings.HasPrefix(path, "/") {
// 去掉单个前导斜杠
path = strings.TrimPrefix(path, "/")
}
// 去掉.git后缀
path = strings.TrimSuffix(path, ".git")
// 现在应该得到 "zzx-coder/gitlink-cli" 格式
parts := strings.Split(path, "/")
if len(parts) < 2 {
return "", "", fmt.Errorf("cannot extract owner/repo from path: %s", path)
}
// 第一个部分是owner第二个是repo可能还有更多部分但忽略
return parts[0], parts[1], nil
}