( options: WorkspaceInitHookOptions )
| 215 | * plus any runtime-specific preparation that must happen before hook gating. |
| 216 | */ |
| 217 | export async function runWorkspaceInitHook( |
| 218 | options: WorkspaceInitHookOptions |
| 219 | ): Promise<WorkspaceInitResult> { |
| 220 | const { params, runtimeType, hookCheckPath, beforeHook, runHook } = options; |
| 221 | const { projectPath, branchName, initLogger, abortSignal, env } = params; |
| 222 | |
| 223 | try { |
| 224 | // skipInitHook only disables repo-controlled hook execution; provisioning/materialization |
| 225 | // that makes the workspace usable still belongs in beforeHook(). |
| 226 | await beforeHook?.(); |
| 227 | |
| 228 | if (shouldSkipInitHook(params, initLogger)) { |
| 229 | initLogger.logComplete(0); |
| 230 | return { success: true }; |
| 231 | } |
| 232 | |
| 233 | const hookExists = await checkInitHookExists(hookCheckPath); |
| 234 | if (!hookExists) { |
| 235 | initLogger.logComplete(0); |
| 236 | return { success: true }; |
| 237 | } |
| 238 | |
| 239 | initLogger.enterHookPhase?.(); |
| 240 | const muxEnv = { ...env, ...getMuxEnv(projectPath, runtimeType, branchName) }; |
| 241 | await runHook({ muxEnv, initLogger, abortSignal }); |
| 242 | return { success: true }; |
| 243 | } catch (error) { |
| 244 | const errorMsg = error instanceof Error ? error.message : String(error); |
| 245 | initLogger.logStderr(`Initialization failed: ${errorMsg}`); |
| 246 | initLogger.logComplete(-1); |
| 247 | return { |
| 248 | success: false, |
| 249 | error: errorMsg, |
| 250 | }; |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | /** |
| 255 | * Run .mux/init hook on a runtime and stream output to logger. |
no test coverage detected