Fix alias resolution and improve cross-platform support

- Fixed alias regex to handle both 'alias name=value' and 'name=value' formats
- Added platform-specific shell execution with proper flags for Windows/Unix
- Skip alias resolution on Windows (not supported)
- Use expanded alias value instead of running the alias name
- PowerShell uses -NoProfile -Command, cmd.exe uses /C, Unix shells use -c/-i
This commit is contained in:
Mario Zechner 2025-06-24 14:36:10 +02:00
parent 1470da3129
commit d37f813b83

View file

@ -230,13 +230,18 @@ export class ProcessUtils {
// Not in PATH - try to resolve as an alias // Not in PATH - try to resolve as an alias
const aliasValue = ProcessUtils.getAliasValue(cmdName); const aliasValue = ProcessUtils.getAliasValue(cmdName);
if (aliasValue) { if (aliasValue) {
// Just use interactive shell to run the full command with the alias
logger.log(chalk.cyan(`Using alias '${cmdName}' → '${aliasValue}'`)); logger.log(chalk.cyan(`Using alias '${cmdName}' → '${aliasValue}'`));
// Expand the alias and add any additional arguments
const expandedCommand =
cmdArgs.length > 0 ? `${aliasValue} ${cmdArgs.join(' ')}` : aliasValue;
const userShell = ProcessUtils.getUserShell(); const userShell = ProcessUtils.getUserShell();
const fullCommand = cmdArgs.length > 0 ? `${cmdName} ${cmdArgs.join(' ')}` : cmdName; const shellArgs = ProcessUtils.getShellExecuteArgs(userShell, expandedCommand, false);
return { return {
command: userShell, command: userShell,
args: ['-i', '-c', fullCommand], args: shellArgs,
useShell: true, useShell: true,
isInteractive: false, isInteractive: false,
resolvedFrom: 'alias', resolvedFrom: 'alias',
@ -245,12 +250,12 @@ export class ProcessUtils {
} }
// Not an executable or alias - probably a shell builtin or function // Not an executable or alias - probably a shell builtin or function
// For commands not found, we need interactive shell to load aliases logger.debug(`Command '${cmdName}' not found in PATH or aliases, using shell`);
logger.debug(`Command '${cmdName}' not found in PATH or aliases, using interactive shell`);
const userShell = ProcessUtils.getUserShell(); const userShell = ProcessUtils.getUserShell();
const shellArgs = ProcessUtils.getShellExecuteArgs(userShell, command.join(' '), false);
return { return {
command: userShell, command: userShell,
args: ['-i', '-c', command.join(' ')], args: shellArgs,
useShell: true, useShell: true,
isInteractive: false, isInteractive: false,
resolvedFrom: 'builtin', resolvedFrom: 'builtin',
@ -297,6 +302,15 @@ export class ProcessUtils {
* Returns null if not an alias * Returns null if not an alias
*/ */
private static getAliasValue(aliasName: string): string | null { private static getAliasValue(aliasName: string): string | null {
// Alias resolution is platform-specific
if (process.platform === 'win32') {
// Windows doesn't have Unix-style aliases
// PowerShell has aliases but they work differently
// For now, skip alias resolution on Windows
logger.debug(`Alias resolution not implemented for Windows`);
return null;
}
try { try {
// Get the user's shell to check aliases // Get the user's shell to check aliases
const userShell = process.env.SHELL || '/bin/bash'; const userShell = process.env.SHELL || '/bin/bash';
@ -313,11 +327,12 @@ export class ProcessUtils {
return null; return null;
} }
// Parse the alias output (format: alias key='value') // Parse the alias output
// Format can be either "alias name='value'" or just "name='value'"
const lines = aliasOutput.stdout.split('\n'); const lines = aliasOutput.stdout.split('\n');
for (const line of lines) { for (const line of lines) {
// Match pattern: alias name='command' or alias name="command" // Match both formats: with or without 'alias' prefix
const match = line.match(/^alias\s+([^=]+)=(['"]?)(.+)\2$/); const match = line.match(/^(?:alias\s+)?([^=]+)=(['"]?)(.+)\2$/);
if (match && match[1] === aliasName) { if (match && match[1] === aliasName) {
// Return the value with quotes stripped // Return the value with quotes stripped
return match[3]; return match[3];
@ -330,6 +345,36 @@ export class ProcessUtils {
return null; return null;
} }
/**
* Get platform-specific shell execution arguments
*/
private static getShellExecuteArgs(
shell: string,
command: string,
needsInteractive: boolean
): string[] {
const shellName = path.basename(shell).toLowerCase();
if (process.platform === 'win32') {
// Windows shells
if (shellName.includes('powershell') || shellName.includes('pwsh')) {
// PowerShell
return ['-NoProfile', '-Command', command];
} else if (shellName.includes('cmd')) {
// cmd.exe
return ['/C', command];
} else if (shellName.includes('bash')) {
// Git Bash on Windows
return needsInteractive ? ['-i', '-c', command] : ['-c', command];
}
// Default Windows
return ['/C', command];
} else {
// Unix shells - handle interactive mode for aliases
return needsInteractive ? ['-i', '-c', command] : ['-c', command];
}
}
/** /**
* Get the user's preferred shell * Get the user's preferred shell
* Falls back to sensible defaults if SHELL env var is not set * Falls back to sensible defaults if SHELL env var is not set