| 221 | } |
| 222 | |
| 223 | func parseWorkspaceRemoteRef(ctx context.Context, remoteRef string) (workspaceRemoteRef, error) { |
| 224 | // Fragment refs are parsed via the same git URL parser used by Address.*. |
| 225 | if strings.Contains(remoteRef, "#") { |
| 226 | gitURL, err := gitutil.ParseURL(remoteRef) |
| 227 | if err != nil { |
| 228 | return workspaceRemoteRef{}, err |
| 229 | } |
| 230 | version := "" |
| 231 | subdir := "." |
| 232 | if gitURL.Fragment != nil { |
| 233 | version = gitURL.Fragment.Ref |
| 234 | subdir = gitURL.Fragment.Subdir |
| 235 | } |
| 236 | workspaceSubdir, err := normalizeWorkspaceRemoteSubdir(subdir) |
| 237 | if err != nil { |
| 238 | return workspaceRemoteRef{}, fmt.Errorf("invalid git subdir in workspace ref %q: %w", remoteRef, err) |
| 239 | } |
| 240 | return workspaceRemoteRef{ |
| 241 | cloneRef: gitURL.Remote(), |
| 242 | version: version, |
| 243 | workspaceSubdir: workspaceSubdir, |
| 244 | }, nil |
| 245 | } |
| 246 | |
| 247 | // Preserve legacy @ref parsing semantics for existing workspace refs. |
| 248 | parsedRef, err := core.ParseGitRefString(ctx, remoteRef) |
| 249 | if err != nil { |
| 250 | return workspaceRemoteRef{}, err |
| 251 | } |
| 252 | workspaceSubdir := "." |
| 253 | if parsedRef.RepoRootSubdir != "/" && parsedRef.RepoRootSubdir != "." { |
| 254 | workspaceSubdir = parsedRef.RepoRootSubdir |
| 255 | } |
| 256 | return workspaceRemoteRef{ |
| 257 | cloneRef: parsedRef.SourceCloneRef, |
| 258 | version: parsedRef.ModVersion, |
| 259 | workspaceSubdir: workspaceSubdir, |
| 260 | }, nil |
| 261 | } |
| 262 | |
| 263 | func normalizeWorkspaceRemoteSubdir(subdir string) (string, error) { |
| 264 | if subdir == "" { |