mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(cli): preserve invoked cwd for local launcher (#299)
This commit is contained in:
@@ -26,7 +26,8 @@
|
||||
*/
|
||||
|
||||
import { spawn, SpawnOptions, type ChildProcess } from 'child_process';
|
||||
import { join } from 'node:path';
|
||||
import { join, isAbsolute, resolve, win32 } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { isBunCompiled, projectPath } from '@/projectPath';
|
||||
import { logger } from '@/ui/logger';
|
||||
import { existsSync } from 'node:fs';
|
||||
@@ -48,6 +49,28 @@ export interface HappyCliCommand {
|
||||
args: string[];
|
||||
}
|
||||
|
||||
function isCrossPlatformAbsolutePath(value: string): boolean {
|
||||
return isAbsolute(value) || win32.isAbsolute(value);
|
||||
}
|
||||
|
||||
function resolveInvokedCwd(cwd: SpawnOptions['cwd']): string {
|
||||
if (cwd instanceof URL) {
|
||||
return fileURLToPath(cwd);
|
||||
}
|
||||
|
||||
if (typeof cwd === 'string' && cwd.trim().length > 0) {
|
||||
const normalizedCwd = cwd.trim();
|
||||
return isCrossPlatformAbsolutePath(normalizedCwd) ? normalizedCwd : resolve(normalizedCwd);
|
||||
}
|
||||
|
||||
const inheritedInvokedCwd = process.env.HAPI_INVOKED_CWD?.trim();
|
||||
if (inheritedInvokedCwd && isCrossPlatformAbsolutePath(inheritedInvokedCwd)) {
|
||||
return inheritedInvokedCwd;
|
||||
}
|
||||
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
export function getHappyCliCommand(args: string[]): HappyCliCommand {
|
||||
// Compiled binary mode: just use the executable directly
|
||||
if (isBunCompiled()) {
|
||||
@@ -63,10 +86,12 @@ export function getHappyCliCommand(args: string[]): HappyCliCommand {
|
||||
const isBunRuntime = Boolean((process.versions as Record<string, string | undefined>).bun);
|
||||
|
||||
if (isBunRuntime) {
|
||||
// Bun can run TypeScript directly
|
||||
// Bun can run TypeScript directly.
|
||||
// Force Bun's cwd to the CLI project root so alias resolution via bunfig.toml
|
||||
// keeps working even when external tools launch HAPI from another workspace.
|
||||
return {
|
||||
command: process.execPath,
|
||||
args: [entrypoint, ...args]
|
||||
args: ['--cwd', projectRoot, entrypoint, ...args]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -108,6 +133,14 @@ export function spawnHappyCLI(args: string[], options: SpawnOptions = {}): Child
|
||||
// On Windows, detached processes allocate a new console window by default.
|
||||
// windowsHide: true suppresses this to prevent cmd windows from accumulating.
|
||||
const finalOptions: SpawnOptions = { ...options };
|
||||
if (!isBunCompiled()) {
|
||||
const finalEnv = { ...process.env, ...options.env };
|
||||
const invokedCwd = finalEnv.HAPI_INVOKED_CWD?.trim();
|
||||
finalEnv.HAPI_INVOKED_CWD = invokedCwd && isCrossPlatformAbsolutePath(invokedCwd)
|
||||
? invokedCwd
|
||||
: resolveInvokedCwd(options.cwd);
|
||||
finalOptions.env = finalEnv;
|
||||
}
|
||||
if (process.platform === 'win32' && options.detached) {
|
||||
finalOptions.windowsHide = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user