MCPcopy Create free account
hub / github.com/github/gh-aw / parseRemoteOrigin

Function parseRemoteOrigin

pkg/parser/import_remote.go:41–92  ·  view source on GitHub ↗

parseRemoteOrigin extracts the remote origin (owner, repo, ref, basePath) from a workflowspec path. Returns nil if the path is not a valid workflowspec. Format: owner/repo/path[@ref] where ref defaults to "main" if not specified. BasePath is derived from the parent workflowspec path and used for res

(spec string)

Source from the content-addressed store, hash-verified

39// For example, "elastic/ai-github-actions/gh-agent-workflows/gh-aw-workflows/file.md@main"
40// produces BasePath="gh-agent-workflows" so nested imports resolve relative to that directory.
41func parseRemoteOrigin(spec string) *remoteImportOrigin {
42 importRemoteLog.Printf("Parsing remote import origin from spec: %q", spec)
43 // Remove section reference if present
44 cleanSpec := spec
45 if before, _, ok := strings.Cut(spec, "#"); ok {
46 cleanSpec = before
47 }
48
49 // Split on @ to get path and ref
50 parts := strings.SplitN(cleanSpec, "@", 2)
51 pathPart := parts[0]
52 ref := "main"
53 if len(parts) == 2 {
54 ref = parts[1]
55 }
56
57 // Parse path: owner/repo/path/to/file.md
58 slashParts := strings.Split(pathPart, "/")
59 if len(slashParts) < 3 {
60 importRemoteLog.Printf("Spec %q has fewer than 3 path components; not a valid workflowspec", spec)
61 return nil
62 }
63
64 // Derive BasePath: everything between owner/repo and the last component (filename)
65 // Since imports are always 2-level (dir/file.md), the base is everything before the filename
66 // Examples:
67 // - "owner/repo/.github/workflows/file.md" -> BasePath = ".github/workflows"
68 // - "owner/repo/gh-agent-workflows/gh-aw-workflows/file.md" -> BasePath = "gh-agent-workflows/gh-aw-workflows"
69 // - "owner/repo/a/b/c/d/file.md" -> BasePath = "a/b/c/d"
70 var basePath string
71 repoRelativeParts := slashParts[2:] // Everything after owner/repo
72 if len(repoRelativeParts) >= 2 {
73 // Take everything except the last component (the file itself)
74 // For nested imports, we want the directory containing the file
75 baseDirParts := repoRelativeParts[:len(repoRelativeParts)-1]
76 if len(baseDirParts) > 0 {
77 // Clean the path to normalize it (remove ./ and resolve ..)
78 basePath = path.Clean(strings.Join(baseDirParts, "/"))
79 importRemoteLog.Printf("Derived BasePath=%q from spec=%q (owner=%s, repo=%s, ref=%s)",
80 basePath, spec, slashParts[0], slashParts[1], ref)
81 }
82 } else {
83 importRemoteLog.Printf("No BasePath derived from spec=%q (file at repo root)", spec)
84 }
85
86 return &remoteImportOrigin{
87 Owner: slashParts[0],
88 Repo: slashParts[1],
89 Ref: ref,
90 BasePath: basePath,
91 }
92}

Calls 1

PrintfMethod · 0.45