(cliHost: CLIHost, workspace: Workspace | undefined, config: DevContainerConfig, mountWorkspaceGitRoot: boolean, mountGitWorktreeCommonDir: boolean, output: Log, consistency?: BindMountConsistency)
| 408 | } |
| 409 | |
| 410 | export async function getWorkspaceConfiguration(cliHost: CLIHost, workspace: Workspace | undefined, config: DevContainerConfig, mountWorkspaceGitRoot: boolean, mountGitWorktreeCommonDir: boolean, output: Log, consistency?: BindMountConsistency): Promise<WorkspaceConfiguration> { |
| 411 | if ('dockerComposeFile' in config) { |
| 412 | return { |
| 413 | workspaceFolder: getRemoteWorkspaceFolder(config), |
| 414 | workspaceMount: undefined, |
| 415 | additionalMountString: undefined, |
| 416 | }; |
| 417 | } |
| 418 | let { workspaceFolder, workspaceMount } = config; |
| 419 | let additionalMountString: string | undefined; |
| 420 | if (workspace && (!workspaceFolder || !('workspaceMount' in config))) { |
| 421 | const hostMountFolder = await getHostMountFolder(cliHost, workspace.rootFolderPath, mountWorkspaceGitRoot, output); |
| 422 | |
| 423 | // Check if .git is a file (worktree) with a relative gitdir path |
| 424 | let containerMountFolder = path.posix.join('/workspaces', cliHost.path.basename(hostMountFolder)); |
| 425 | if (mountWorkspaceGitRoot && mountGitWorktreeCommonDir) { |
| 426 | const dotGitPath = cliHost.path.join(hostMountFolder, '.git'); |
| 427 | if (await cliHost.isFile(dotGitPath)) { |
| 428 | const dotGitContent = (await cliHost.readFile(dotGitPath)).toString(); |
| 429 | const match = /^gitdir:\s*(.+)$/m.exec(dotGitContent); |
| 430 | if (match) { |
| 431 | const gitdir = match[1]; |
| 432 | // Only handle if gitdir is a relative path |
| 433 | if (!cliHost.path.isAbsolute(gitdir)) { |
| 434 | // gitdir points to .git/worktrees/<name>/, common dir is .git/ (two levels up) |
| 435 | const gitCommonDir = cliHost.path.resolve(hostMountFolder, gitdir, '..', '..'); |
| 436 | // Collect path segments from hostMountFolder up to the parent of gitCommonDir |
| 437 | const segments: string[] = []; |
| 438 | for (let current = hostMountFolder; !gitCommonDir.startsWith(current + cliHost.path.sep) && current !== cliHost.path.dirname(current); current = cliHost.path.dirname(current)) { |
| 439 | segments.unshift(cliHost.path.basename(current)); |
| 440 | } |
| 441 | containerMountFolder = path.posix.join('/workspaces', ...segments); |
| 442 | // Calculate where the common dir should be mounted in the container |
| 443 | const containerGitdir = cliHost.platform === 'win32' ? gitdir.replace(/\\/g, '/') : gitdir; |
| 444 | const containerGitCommonDir = path.posix.resolve(containerMountFolder, containerGitdir, '..', '..'); |
| 445 | const cons = cliHost.platform !== 'linux' ? `,consistency=${consistency || 'consistent'}` : ''; |
| 446 | const srcQuote = gitCommonDir.indexOf(',') !== -1 ? '"' : ''; |
| 447 | const tgtQuote = containerGitCommonDir.indexOf(',') !== -1 ? '"' : ''; |
| 448 | additionalMountString = `type=bind,${srcQuote}source=${gitCommonDir}${srcQuote},${tgtQuote}target=${containerGitCommonDir}${tgtQuote}${cons}`; |
| 449 | } |
| 450 | } |
| 451 | } |
| 452 | } |
| 453 | |
| 454 | if (!workspaceFolder) { |
| 455 | const rel = cliHost.path.relative(hostMountFolder, workspace.rootFolderPath); |
| 456 | workspaceFolder = path.posix.join(containerMountFolder, cliHost.platform === 'win32' ? rel.replace(/\\/g, '/') : rel); |
| 457 | } |
| 458 | if (!('workspaceMount' in config)) { |
| 459 | const cons = cliHost.platform !== 'linux' ? `,consistency=${consistency || 'consistent'}` : ''; // Podman does not tolerate consistency= |
| 460 | const srcQuote = hostMountFolder.indexOf(',') !== -1 ? '"' : ''; |
| 461 | const tgtQuote = containerMountFolder.indexOf(',') !== -1 ? '"' : ''; |
| 462 | workspaceMount = `type=bind,${srcQuote}source=${hostMountFolder}${srcQuote},${tgtQuote}target=${containerMountFolder}${tgtQuote}${cons}`; |
| 463 | } |
| 464 | } |
| 465 | return { |
| 466 | workspaceFolder, |
| 467 | workspaceMount, |
no test coverage detected