2018-11-26 17:55:15 +01:00
|
|
|
export type TExecutor = 'sh' | 'bash';
|
2018-07-30 16:03:48 +02:00
|
|
|
|
|
|
|
|
export interface IShellEnvContructorOptions {
|
|
|
|
|
executor: TExecutor;
|
2018-08-04 16:43:02 +02:00
|
|
|
sourceFilePaths?: string[];
|
|
|
|
|
pathDirectories?: string[];
|
2018-07-30 16:03:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class ShellEnv {
|
|
|
|
|
executor: TExecutor;
|
|
|
|
|
sourceFileArray: string[] = [];
|
2018-08-04 16:43:02 +02:00
|
|
|
pathDirArray: string[] = [];
|
2018-07-30 16:08:14 +02:00
|
|
|
|
2018-07-30 16:03:48 +02:00
|
|
|
/**
|
|
|
|
|
* constructor for the shellenv
|
|
|
|
|
*/
|
|
|
|
|
constructor(optionsArg: IShellEnvContructorOptions) {
|
|
|
|
|
this.executor = optionsArg.executor;
|
2018-08-04 16:43:02 +02:00
|
|
|
|
|
|
|
|
// add sourcefiles
|
|
|
|
|
if (optionsArg.sourceFilePaths) {
|
2018-11-26 17:55:15 +01:00
|
|
|
this.sourceFileArray = this.sourceFileArray.concat(optionsArg.sourceFilePaths);
|
2018-08-04 16:43:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add pathDirectories
|
|
|
|
|
if (optionsArg.pathDirectories) {
|
|
|
|
|
this.pathDirArray = this.pathDirArray.concat(optionsArg.pathDirectories);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-05 10:18:43 +00:00
|
|
|
/**
|
|
|
|
|
* Detect if running under Windows Subsystem for Linux
|
|
|
|
|
*/
|
|
|
|
|
private static _isWSL(): boolean {
|
|
|
|
|
return !!(
|
|
|
|
|
process.env.WSL_DISTRO_NAME ||
|
|
|
|
|
process.env.WSLENV ||
|
|
|
|
|
(process.platform === 'linux' && process.env.PATH?.includes('/mnt/c/'))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-04 16:43:02 +02:00
|
|
|
/**
|
|
|
|
|
* imports path into the shell from env if available and returns it with
|
|
|
|
|
*/
|
2021-07-26 21:24:13 +02:00
|
|
|
private _setPath(commandStringArg: string): string {
|
2018-08-04 16:43:02 +02:00
|
|
|
let commandResult = commandStringArg;
|
2018-12-13 16:50:32 +01:00
|
|
|
let commandPaths: string[] = [];
|
|
|
|
|
commandPaths = commandPaths.concat(process.env.PATH.split(':'));
|
2018-08-04 16:43:02 +02:00
|
|
|
if (process.env.SMARTSHELL_PATH) {
|
2018-12-13 16:50:32 +01:00
|
|
|
commandPaths = commandPaths.concat(process.env.SMARTSHELL_PATH.split(':'));
|
2018-07-30 16:03:48 +02:00
|
|
|
}
|
2018-12-13 16:50:32 +01:00
|
|
|
|
2026-03-05 10:18:43 +00:00
|
|
|
// Only filter out WSL-specific paths when actually running under WSL
|
|
|
|
|
if (ShellEnv._isWSL()) {
|
|
|
|
|
commandPaths = commandPaths.filter((commandPathArg) => {
|
|
|
|
|
return (
|
|
|
|
|
!commandPathArg.startsWith('/mnt/c/') &&
|
|
|
|
|
!commandPathArg.startsWith('Files/1E') &&
|
|
|
|
|
!commandPathArg.includes(' ')
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
2018-12-13 16:50:32 +01:00
|
|
|
|
|
|
|
|
commandResult = `PATH=${commandPaths.join(':')} && ${commandStringArg}`;
|
2018-08-04 16:43:02 +02:00
|
|
|
return commandResult;
|
2018-07-30 16:08:14 +02:00
|
|
|
}
|
2018-07-30 16:03:48 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* add files that are going to be sourced when running a command
|
2018-07-30 16:08:14 +02:00
|
|
|
* @param sourceFilePathsArray
|
2018-07-30 16:03:48 +02:00
|
|
|
*/
|
|
|
|
|
addSourceFiles(sourceFilePathsArray: string[]) {
|
|
|
|
|
for (let sourceFilePath of sourceFilePathsArray) {
|
|
|
|
|
this.sourceFileArray.push(sourceFilePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cleans the source files array
|
|
|
|
|
*/
|
|
|
|
|
cleanSourceFiles() {
|
|
|
|
|
this.sourceFileArray = [];
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 22:41:20 +02:00
|
|
|
public createEnvExecString(commandArg: string): string {
|
2018-11-26 17:55:15 +01:00
|
|
|
let commandResult = '';
|
2018-12-13 16:50:32 +01:00
|
|
|
let sourceString = '';
|
|
|
|
|
|
2019-05-19 22:41:20 +02:00
|
|
|
// deal with sourcestring
|
|
|
|
|
for (const sourceFilePath of this.sourceFileArray) {
|
|
|
|
|
sourceString = sourceString + `source ${sourceFilePath} && `;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-26 15:17:52 +01:00
|
|
|
// deal with available path
|
2019-05-19 22:41:20 +02:00
|
|
|
let pathString = 'PATH=$PATH';
|
|
|
|
|
for (const pathDir of this.pathDirArray) {
|
|
|
|
|
pathString += `:${pathDir}`;
|
|
|
|
|
}
|
|
|
|
|
pathString += ` && `;
|
|
|
|
|
|
2026-03-05 10:18:43 +00:00
|
|
|
// For both bash and sh executors, build the command string directly.
|
|
|
|
|
// The shell nesting is handled by spawn() using the appropriate shell binary.
|
|
|
|
|
// Previously bash executor wrapped in `bash -c '...'` which caused triple
|
|
|
|
|
// shell nesting (Node spawn sh -> bash -c -> command). Now spawn() uses
|
|
|
|
|
// shell: '/bin/bash' directly, so we don't need the extra wrapping.
|
|
|
|
|
commandResult = `${pathString}${sourceString}${commandArg}`;
|
2018-08-04 16:43:02 +02:00
|
|
|
commandResult = this._setPath(commandResult);
|
|
|
|
|
return commandResult;
|
2018-07-30 16:03:48 +02:00
|
|
|
}
|
2018-07-30 16:08:14 +02:00
|
|
|
}
|