@@ -5,6 +5,7 @@ import type { PlatformError } from "@effect/platform/Error"
55import { Duration , Effect , pipe , Schedule } from "effect"
66
77import { runCommandCapture , runCommandExitCode , runCommandWithExitCodes } from "./command-runner.js"
8+ import { resolveDockerVolumeHostPath } from "./docker-auth.js"
89import { CommandFailedError , DockerCommandError } from "./errors.js"
910
1011export { classifyDockerAccessIssue , ensureDockerDaemonAccess } from "./docker-daemon-access.js"
@@ -16,6 +17,46 @@ const composeSpec = (cwd: string, args: ReadonlyArray<string>) => ({
1617 args : [ "compose" , "--ansi" , "never" , "--progress" , "plain" , ...args ]
1718} )
1819
20+ const resolveEnvValue = ( key : string ) : string | null => {
21+ const value = process . env [ key ] ?. trim ( )
22+ return value && value . length > 0 ? value : null
23+ }
24+
25+ const trimTrailingSlash = ( value : string ) : string => {
26+ let end = value . length
27+ while ( end > 0 ) {
28+ const char = value [ end - 1 ]
29+ if ( char !== "/" && char !== "\\" ) {
30+ break
31+ }
32+ end -= 1
33+ }
34+ return value . slice ( 0 , end )
35+ }
36+
37+ const resolveProjectsRootCandidate = ( ) : string | null => {
38+ const explicit = resolveEnvValue ( "DOCKER_GIT_PROJECTS_ROOT" )
39+ if ( explicit !== null ) {
40+ return explicit
41+ }
42+
43+ const home = resolveEnvValue ( "HOME" ) ?? resolveEnvValue ( "USERPROFILE" )
44+ return home === null ? null : `${ trimTrailingSlash ( home ) } /.docker-git`
45+ }
46+
47+ const resolveComposeEnv = (
48+ cwd : string
49+ ) : Effect . Effect < Readonly < Record < string , string > > , never , CommandExecutor . CommandExecutor > =>
50+ Effect . gen ( function * ( _ ) {
51+ const projectsRoot = resolveProjectsRootCandidate ( )
52+ if ( projectsRoot === null ) {
53+ return { }
54+ }
55+
56+ const remappedProjectsRoot = yield * _ ( resolveDockerVolumeHostPath ( cwd , projectsRoot ) )
57+ return remappedProjectsRoot === projectsRoot ? { } : { DOCKER_GIT_PROJECTS_ROOT_HOST : remappedProjectsRoot }
58+ } )
59+
1960const parseInspectNetworkEntry = ( line : string ) : ReadonlyArray < readonly [ string , string ] > => {
2061 const idx = line . indexOf ( "=" )
2162 if ( idx <= 0 ) {
@@ -35,22 +76,38 @@ const runCompose = (
3576 args : ReadonlyArray < string > ,
3677 okExitCodes : ReadonlyArray < number >
3778) : Effect . Effect < void , DockerCommandError | PlatformError , CommandExecutor . CommandExecutor > =>
38- runCommandWithExitCodes (
39- composeSpec ( cwd , args ) ,
40- okExitCodes ,
41- ( exitCode ) => new DockerCommandError ( { exitCode } )
42- )
79+ Effect . gen ( function * ( _ ) {
80+ const env = yield * _ ( resolveComposeEnv ( cwd ) )
81+ yield * _ (
82+ runCommandWithExitCodes (
83+ {
84+ ...composeSpec ( cwd , args ) ,
85+ ...( Object . keys ( env ) . length > 0 ? { env } : { } )
86+ } ,
87+ okExitCodes ,
88+ ( exitCode ) => new DockerCommandError ( { exitCode } )
89+ )
90+ )
91+ } )
4392
4493const runComposeCapture = (
4594 cwd : string ,
4695 args : ReadonlyArray < string > ,
4796 okExitCodes : ReadonlyArray < number >
4897) : Effect . Effect < string , DockerCommandError | PlatformError , CommandExecutor . CommandExecutor > =>
49- runCommandCapture (
50- composeSpec ( cwd , args ) ,
51- okExitCodes ,
52- ( exitCode ) => new DockerCommandError ( { exitCode } )
53- )
98+ Effect . gen ( function * ( _ ) {
99+ const env = yield * _ ( resolveComposeEnv ( cwd ) )
100+ return yield * _ (
101+ runCommandCapture (
102+ {
103+ ...composeSpec ( cwd , args ) ,
104+ ...( Object . keys ( env ) . length > 0 ? { env } : { } )
105+ } ,
106+ okExitCodes ,
107+ ( exitCode ) => new DockerCommandError ( { exitCode } )
108+ )
109+ )
110+ } )
54111
55112const dockerComposeUpRetrySchedule = Schedule . addDelay (
56113 Schedule . recurs ( 2 ) ,
0 commit comments