feat: vendor add end-to-end with deterministic lockfile v2

- 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
This commit is contained in:
2026-08-22 21:52:30 +02:00
parent 2a6498dae1
commit 2c7200380b
16 changed files with 1648 additions and 2 deletions
+41
View File
@@ -0,0 +1,41 @@
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
}