Files
smartshell/ts/classes.shellenv.ts

111 lines
3.2 KiB
TypeScript
Raw Permalink Normal View History

2018-11-26 17:55:15 +01:00
export type TExecutor = 'sh' | 'bash';
export interface IShellEnvContructorOptions {
executor: TExecutor;
sourceFilePaths?: string[];
pathDirectories?: string[];
}
export class ShellEnv {
executor: TExecutor;
sourceFileArray: string[] = [];
pathDirArray: string[] = [];
2018-07-30 16:08:14 +02:00
/**
* constructor for the shellenv
*/
constructor(optionsArg: IShellEnvContructorOptions) {
this.executor = optionsArg.executor;
// add sourcefiles
if (optionsArg.sourceFilePaths) {
2018-11-26 17:55:15 +01:00
this.sourceFileArray = this.sourceFileArray.concat(optionsArg.sourceFilePaths);
}
// add pathDirectories
if (optionsArg.pathDirectories) {
this.pathDirArray = this.pathDirArray.concat(optionsArg.pathDirectories);
}
}
/**
* 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/'))
);
}
/**
* 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 {
let commandResult = commandStringArg;
2018-12-13 16:50:32 +01:00
let commandPaths: string[] = [];
commandPaths = commandPaths.concat(process.env.PATH.split(':'));
if (process.env.SMARTSHELL_PATH) {
2018-12-13 16:50:32 +01:00
commandPaths = commandPaths.concat(process.env.SMARTSHELL_PATH.split(':'));
}
2018-12-13 16:50:32 +01: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}`;
return commandResult;
2018-07-30 16:08:14 +02:00
}
/**
* add files that are going to be sourced when running a command
2018-07-30 16:08:14 +02:00
* @param sourceFilePathsArray
*/
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 += ` && `;
// 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}`;
commandResult = this._setPath(commandResult);
return commandResult;
}
2018-07-30 16:08:14 +02:00
}