MCPcopy Create free account
hub / github.com/dagger/dagger / ParseGitRefString

Function ParseGitRefString

core/modulerefs.go:141–233  ·  view source on GitHub ↗
(ctx context.Context, refString string)

Source from the content-addressed store, hash-verified

139type gitEndpointError struct{ error }
140
141func ParseGitRefString(ctx context.Context, refString string) (_ ParsedGitRefString, rerr error) {
142 _, span := Tracer(ctx).Start(ctx, fmt.Sprintf("parseGitRefString: %s", refString), telemetry.Internal())
143 defer telemetry.EndWithCause(span, &rerr)
144
145 scheme, schemelessRef := parseScheme(refString)
146
147 if scheme == NoScheme && isSCPLike(schemelessRef) {
148 scheme = SchemeSCPLike
149 // transform the ":" into a "/" to rely on a unified logic after
150 // works because "git@github.com:user" is equivalent to "ssh://git@ref/user"
151 schemelessRef = strings.Replace(schemelessRef, ":", "/", 1)
152 }
153
154 // Trick:
155 // as we removed the scheme above with `parseScheme``, and the SCP-like refs are
156 // now without ":", all refs are in such format: "[git@]github.com/user/path...@version"
157 // transport.NewEndpoint parses users only for SSH refs. As HTTP refs without scheme are valid SSH refs
158 // we use the "ssh://" prefix to parse properly both explicit / SCP-like and HTTP refs
159 // and delegate the logic to parse the host / path and user to the library
160 endpoint, err := transport.NewEndpoint("ssh://" + schemelessRef)
161 if err != nil {
162 return ParsedGitRefString{}, gitEndpointError{fmt.Errorf("failed to create git endpoint: %w", err)}
163 }
164
165 gitParsed := ParsedGitRefString{
166 modPath: endpoint.Host + endpoint.Path,
167 scheme: scheme,
168 }
169
170 parts := strings.SplitN(endpoint.Path, "@", 2)
171 if len(parts) == 2 {
172 gitParsed.modPath = endpoint.Host + parts[0]
173 gitParsed.ModVersion = parts[1]
174 gitParsed.hasVersion = true
175 }
176
177 // Try to isolate the root of the git repo
178 // RepoRootForImportPath does not support SCP-like ref style. In parseGitEndpoint, we made sure that all refs
179 // would be compatible with this function to benefit from the repo URL and root splitting
180 repoRoot, err := vcs.RepoRootForImportPath(gitParsed.modPath, false)
181 if err != nil {
182 return ParsedGitRefString{}, gitEndpointError{fmt.Errorf("failed to get repo root for import path: %w", err)}
183 }
184 if repoRoot == nil || repoRoot.VCS == nil {
185 return ParsedGitRefString{}, fmt.Errorf("invalid repo root for import path: %s", gitParsed.modPath)
186 }
187 if repoRoot.VCS.Name != "Git" {
188 return ParsedGitRefString{}, fmt.Errorf("repo root is not a Git repo: %s", gitParsed.modPath)
189 }
190
191 gitParsed.RepoRoot = repoRoot
192
193 // the extra "/" trim is important as subpath traversal such as /../ are being cleaned by filePath.Clean
194 gitParsed.RepoRootSubdir = strings.TrimPrefix(strings.TrimPrefix(gitParsed.modPath, repoRoot.Root), "/")
195 if gitParsed.RepoRootSubdir == "" {
196 gitParsed.RepoRootSubdir = "/"
197 }
198 gitParsed.RepoRootSubdir = filepath.Clean(gitParsed.RepoRootSubdir)

Callers 3

parseWorkspaceRemoteRefFunction · 0.92
ParseRefStringFunction · 0.85

Calls 9

RepoRootForImportPathFunction · 0.92
parseSchemeFunction · 0.85
isSCPLikeFunction · 0.85
InternalMethod · 0.80
ReplaceMethod · 0.80
IsSSHMethod · 0.80
PrefixMethod · 0.80
TracerFunction · 0.70
StartMethod · 0.65

Tested by

no test coverage detected