- go-git in-process clone, default-branch/tag resolution, optional token auth - web-tree URL normalization (github/gitlab) with implied discovery root - discovery of skills/commands/agents/mcp, lenient frontmatter with warnings - selection: all by default, --include with missing-entry hard errors - external/<source>/<type>/ materialization preserving exec bits - lockfile v2: deterministic JSON, pinned url/ref/rev, inventory, warnings - offline black-box e2e suite against local fixture git repositories
42 lines
1.5 KiB
Go
42 lines
1.5 KiB
Go
package gitsource
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
githubTreeRe = regexp.MustCompile(`^https://([^/]*github[^/]*)/([^/]+)/([^/]+)/tree/([^/]+)(/.*)?$`)
|
|
gitlabTreeRe = regexp.MustCompile(`^https://([^/]*gitlab[^/]*)/([^/]+)/([^/]+)/-/tree/([^/]+)(/.*)?$`)
|
|
)
|
|
|
|
// NormalizeURL converts pasted GitHub/GitLab web-tree URLs into plain git
|
|
// clone URLs and returns the implied discovery root ("" for the repo root).
|
|
// URLs that are already cloneable pass through unchanged.
|
|
func NormalizeURL(raw string) (url, root string, err error) {
|
|
s := strings.TrimSpace(raw)
|
|
if s == "" {
|
|
return "", "", fmt.Errorf("empty source URL")
|
|
}
|
|
if m := githubTreeRe.FindStringSubmatch(s); m != nil {
|
|
return fmt.Sprintf("https://%s/%s/%s.git", m[1], m[2], m[3]), strings.TrimPrefix(m[5], "/"), nil
|
|
}
|
|
if m := gitlabTreeRe.FindStringSubmatch(s); m != nil {
|
|
return fmt.Sprintf("https://%s/%s/%s.git", m[1], m[2], m[3]), strings.TrimPrefix(m[5], "/"), nil
|
|
}
|
|
if strings.HasSuffix(s, ".git") {
|
|
return s, "", nil
|
|
}
|
|
if m := regexp.MustCompile(`^https://([^/]*github[^/]*)/([^/]+)/([^/]+)$`).FindStringSubmatch(s); m != nil {
|
|
return fmt.Sprintf("https://%s/%s/%s.git", m[1], m[2], m[3]), "", nil
|
|
}
|
|
if m := regexp.MustCompile(`^https://([^/]*gitlab[^/]*)/([^/]+)/([^/]+)$`).FindStringSubmatch(s); m != nil {
|
|
return fmt.Sprintf("https://%s/%s/%s.git", m[1], m[2], m[3]), "", nil
|
|
}
|
|
if strings.HasPrefix(s, "file://") {
|
|
return strings.TrimPrefix(s, "file://"), "", nil
|
|
}
|
|
return s, "", nil
|
|
}
|