forked from Gitlink/gitlink-cli
92 lines
2.6 KiB
Go
92 lines
2.6 KiB
Go
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
|
||
}
|