resolveImportPath is the canonical import-path resolver for pkg/cli. importPath is the raw path from the workflow's imports/includes field. baseDir is the directory against which relative paths are resolved; callers that have a workflow file path should pass filepath.Dir(workflowPath).
(importPath, baseDir string, opts importPathResolverOpts)
| 76 | // baseDir is the directory against which relative paths are resolved; callers |
| 77 | // that have a workflow file path should pass filepath.Dir(workflowPath). |
| 78 | func resolveImportPath(importPath, baseDir string, opts importPathResolverOpts) string { |
| 79 | // 1. Strip section references (e.g. "shared.md#Section" → "shared.md"). |
| 80 | if opts.StripSectionRef { |
| 81 | if i := strings.Index(importPath, "#"); i >= 0 { |
| 82 | importPath = importPath[:i] |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | // 2. Workflowspec-format handling ("owner/repo/path[@sha]"). |
| 87 | if isWorkflowSpecFormat(importPath) { |
| 88 | if opts.WorkflowSpecPassthrough { |
| 89 | return importPath |
| 90 | } |
| 91 | if opts.WorkflowSpecSkip { |
| 92 | return "" |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | // 3. Absolute paths (starting with "/"). |
| 97 | if withoutLeadingSlash, hasLeadingSlash := strings.CutPrefix(importPath, "/"); hasLeadingSlash { |
| 98 | if opts.RepoRelativeAbsolute { |
| 99 | // Strip "/" and return as a repo-relative string (no disk lookup). |
| 100 | return withoutLeadingSlash |
| 101 | } |
| 102 | if !opts.UseParserFallback { |
| 103 | // Resolve against the git root on disk. |
| 104 | gitRoot := opts.GitRoot |
| 105 | if gitRoot == "" { |
| 106 | var err error |
| 107 | gitRoot, err = gitutil.FindGitRoot() |
| 108 | if err != nil { |
| 109 | return "" |
| 110 | } |
| 111 | } |
| 112 | return filepath.Join(gitRoot, withoutLeadingSlash) |
| 113 | } |
| 114 | // UseParserFallback=true: fall through to parser resolution below. |
| 115 | } |
| 116 | |
| 117 | // 4. Relative paths (and "/" prefix paths in parser-fallback mode). |
| 118 | if opts.UseParserFallback { |
| 119 | // Only attempt stat for non-absolute paths (absolute paths go directly to parser, |
| 120 | // matching the original dependency_graph.go behaviour). |
| 121 | if !strings.HasPrefix(importPath, "/") { |
| 122 | absPath := filepath.Join(baseDir, importPath) |
| 123 | if fileutil.FileExists(absPath) { |
| 124 | return absPath |
| 125 | } |
| 126 | } |
| 127 | importCache := parser.NewImportCache(opts.ParserGitRoot) |
| 128 | fullPath, err := parser.ResolveIncludePath(importPath, baseDir, importCache) |
| 129 | if err != nil { |
| 130 | return "" |
| 131 | } |
| 132 | return fullPath |
| 133 | } |
| 134 | |
| 135 | // Direct resolution with optional path normalisation. |