@@ -69,9 +69,33 @@ extension Process {
69
69
do {
70
70
try process. launch ( )
71
71
} catch Process . Error . workingDirectoryNotSupported where workingDirectory != nil {
72
- // TODO (indexing): We need to figure out how to set the working directory on all platforms.
72
+ return try Process . launchWithWorkingDirectoryUsingSh (
73
+ arguments: arguments,
74
+ environmentBlock: environmentBlock,
75
+ workingDirectory: workingDirectory!,
76
+ outputRedirection: outputRedirection,
77
+ startNewProcessGroup: startNewProcessGroup,
78
+ loggingHandler: loggingHandler
79
+ )
80
+ }
81
+ return process
82
+ }
83
+
84
+ private static func launchWithWorkingDirectoryUsingSh(
85
+ arguments: [ String ] ,
86
+ environmentBlock: ProcessEnvironmentBlock = ProcessEnv . block,
87
+ workingDirectory: AbsolutePath ,
88
+ outputRedirection: OutputRedirection = . collect,
89
+ startNewProcessGroup: Bool = true ,
90
+ loggingHandler: LoggingHandler ? = . none
91
+ ) throws -> Process {
92
+ let shPath = " /usr/bin/sh "
93
+ guard FileManager . default. fileExists ( atPath: shPath) else {
73
94
logger. error (
74
- " Working directory not supported on the platform. Launching process without working directory \( workingDirectory!. pathString) "
95
+ """
96
+ Working directory not supported on the platform and 'sh' could not be found. \
97
+ Launching process without working directory \( workingDirectory. pathString)
98
+ """
75
99
)
76
100
return try Process . launch (
77
101
arguments: arguments,
@@ -82,7 +106,14 @@ extension Process {
82
106
loggingHandler: loggingHandler
83
107
)
84
108
}
85
- return process
109
+ return try Process . launch (
110
+ arguments: [ shPath, " -c " , #"cd "$0"; exec "$@""# , workingDirectory. pathString] + arguments,
111
+ environmentBlock: environmentBlock,
112
+ workingDirectory: nil ,
113
+ outputRedirection: outputRedirection,
114
+ startNewProcessGroup: startNewProcessGroup,
115
+ loggingHandler: loggingHandler
116
+ )
86
117
}
87
118
88
119
/// Runs a new process with the given parameters and waits for it to exit, sending SIGINT if this task is cancelled.
0 commit comments