@push.rocks/smartshell 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +3 -0
- package/dist_ts/smartshell.classes.shellenv.d.ts +29 -0
- package/dist_ts/smartshell.classes.shellenv.js +82 -0
- package/dist_ts/smartshell.classes.shelllog.d.ts +19 -0
- package/dist_ts/smartshell.classes.shelllog.js +37 -0
- package/dist_ts/smartshell.classes.smartshell.d.ts +33 -0
- package/dist_ts/smartshell.classes.smartshell.js +127 -0
- package/dist_ts/smartshell.plugins.d.ts +7 -0
- package/dist_ts/smartshell.plugins.js +9 -0
- package/npmextra.json +18 -0
- package/package.json +58 -0
- package/readme.md +37 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +2 -0
- package/ts/smartshell.classes.shellenv.ts +103 -0
- package/ts/smartshell.classes.shelllog.ts +38 -0
- package/ts/smartshell.classes.smartshell.ts +184 -0
- package/ts/smartshell.plugins.ts +11 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* autocreated commitinfo by @pushrocks/commitinfo
|
|
3
|
+
*/
|
|
4
|
+
export const commitinfo = {
|
|
5
|
+
name: '@pushrocks/smartshell',
|
|
6
|
+
version: '3.0.3',
|
|
7
|
+
description: 'shell actions designed as promises'
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx1QkFBdUI7SUFDN0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLG9DQUFvQztDQUNsRCxDQUFBIn0=
|
package/dist_ts/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export * from './smartshell.classes.smartshell.js';
|
|
2
|
+
export { which } from './smartshell.plugins.js';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG9DQUFvQyxDQUFDO0FBQ25ELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQyJ9
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type TExecutor = 'sh' | 'bash';
|
|
2
|
+
export interface IShellEnvContructorOptions {
|
|
3
|
+
executor: TExecutor;
|
|
4
|
+
sourceFilePaths?: string[];
|
|
5
|
+
pathDirectories?: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare class ShellEnv {
|
|
8
|
+
executor: TExecutor;
|
|
9
|
+
sourceFileArray: string[];
|
|
10
|
+
pathDirArray: string[];
|
|
11
|
+
/**
|
|
12
|
+
* constructor for the shellenv
|
|
13
|
+
*/
|
|
14
|
+
constructor(optionsArg: IShellEnvContructorOptions);
|
|
15
|
+
/**
|
|
16
|
+
* imports path into the shell from env if available and returns it with
|
|
17
|
+
*/
|
|
18
|
+
private _setPath;
|
|
19
|
+
/**
|
|
20
|
+
* add files that are going to be sourced when running a command
|
|
21
|
+
* @param sourceFilePathsArray
|
|
22
|
+
*/
|
|
23
|
+
addSourceFiles(sourceFilePathsArray: string[]): void;
|
|
24
|
+
/**
|
|
25
|
+
* cleans the source files array
|
|
26
|
+
*/
|
|
27
|
+
cleanSourceFiles(): void;
|
|
28
|
+
createEnvExecString(commandArg: string): string;
|
|
29
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export class ShellEnv {
|
|
2
|
+
/**
|
|
3
|
+
* constructor for the shellenv
|
|
4
|
+
*/
|
|
5
|
+
constructor(optionsArg) {
|
|
6
|
+
this.sourceFileArray = [];
|
|
7
|
+
this.pathDirArray = [];
|
|
8
|
+
this.executor = optionsArg.executor;
|
|
9
|
+
// add sourcefiles
|
|
10
|
+
if (optionsArg.sourceFilePaths) {
|
|
11
|
+
this.sourceFileArray = this.sourceFileArray.concat(optionsArg.sourceFilePaths);
|
|
12
|
+
}
|
|
13
|
+
// add pathDirectories
|
|
14
|
+
if (optionsArg.pathDirectories) {
|
|
15
|
+
this.pathDirArray = this.pathDirArray.concat(optionsArg.pathDirectories);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* imports path into the shell from env if available and returns it with
|
|
20
|
+
*/
|
|
21
|
+
_setPath(commandStringArg) {
|
|
22
|
+
let commandResult = commandStringArg;
|
|
23
|
+
let commandPaths = [];
|
|
24
|
+
commandPaths = commandPaths.concat(process.env.PATH.split(':'));
|
|
25
|
+
if (process.env.SMARTSHELL_PATH) {
|
|
26
|
+
commandPaths = commandPaths.concat(process.env.SMARTSHELL_PATH.split(':'));
|
|
27
|
+
}
|
|
28
|
+
// lets filter for unwanted paths
|
|
29
|
+
// Windows WSL
|
|
30
|
+
commandPaths = commandPaths.filter((commandPathArg) => {
|
|
31
|
+
const filterResult = !commandPathArg.startsWith('/mnt/c/') &&
|
|
32
|
+
!commandPathArg.startsWith('Files/1E') &&
|
|
33
|
+
!commandPathArg.includes(' ');
|
|
34
|
+
if (!filterResult) {
|
|
35
|
+
// console.log(`${commandPathArg} will be filtered!`);
|
|
36
|
+
}
|
|
37
|
+
return filterResult;
|
|
38
|
+
});
|
|
39
|
+
commandResult = `PATH=${commandPaths.join(':')} && ${commandStringArg}`;
|
|
40
|
+
return commandResult;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* add files that are going to be sourced when running a command
|
|
44
|
+
* @param sourceFilePathsArray
|
|
45
|
+
*/
|
|
46
|
+
addSourceFiles(sourceFilePathsArray) {
|
|
47
|
+
for (let sourceFilePath of sourceFilePathsArray) {
|
|
48
|
+
this.sourceFileArray.push(sourceFilePath);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* cleans the source files array
|
|
53
|
+
*/
|
|
54
|
+
cleanSourceFiles() {
|
|
55
|
+
this.sourceFileArray = [];
|
|
56
|
+
}
|
|
57
|
+
createEnvExecString(commandArg) {
|
|
58
|
+
let commandResult = '';
|
|
59
|
+
let sourceString = '';
|
|
60
|
+
// deal with sourcestring
|
|
61
|
+
for (const sourceFilePath of this.sourceFileArray) {
|
|
62
|
+
sourceString = sourceString + `source ${sourceFilePath} && `;
|
|
63
|
+
}
|
|
64
|
+
// deal with available path
|
|
65
|
+
let pathString = 'PATH=$PATH';
|
|
66
|
+
for (const pathDir of this.pathDirArray) {
|
|
67
|
+
pathString += `:${pathDir}`;
|
|
68
|
+
}
|
|
69
|
+
pathString += ` && `;
|
|
70
|
+
switch (this.executor) {
|
|
71
|
+
case 'bash':
|
|
72
|
+
commandResult = `bash -c '${pathString}${sourceString}${commandArg}'`;
|
|
73
|
+
break;
|
|
74
|
+
case 'sh':
|
|
75
|
+
commandResult = `${pathString}${sourceString}${commandArg}`;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
commandResult = this._setPath(commandResult);
|
|
79
|
+
return commandResult;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC5jbGFzc2VzLnNoZWxsZW52LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzaGVsbC5jbGFzc2VzLnNoZWxsZW52LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE1BQU0sT0FBTyxRQUFRO0lBS25COztPQUVHO0lBQ0gsWUFBWSxVQUFzQztRQU5sRCxvQkFBZSxHQUFhLEVBQUUsQ0FBQztRQUMvQixpQkFBWSxHQUFhLEVBQUUsQ0FBQztRQU0xQixJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7UUFFcEMsa0JBQWtCO1FBQ2xCLElBQUksVUFBVSxDQUFDLGVBQWUsRUFBRTtZQUM5QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxlQUFlLENBQUMsQ0FBQztTQUNoRjtRQUVELHNCQUFzQjtRQUN0QixJQUFJLFVBQVUsQ0FBQyxlQUFlLEVBQUU7WUFDOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLENBQUM7U0FDMUU7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxRQUFRLENBQUMsZ0JBQXdCO1FBQ3ZDLElBQUksYUFBYSxHQUFHLGdCQUFnQixDQUFDO1FBQ3JDLElBQUksWUFBWSxHQUFhLEVBQUUsQ0FBQztRQUNoQyxZQUFZLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNoRSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFO1lBQy9CLFlBQVksR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQzVFO1FBRUQsaUNBQWlDO1FBQ2pDLGNBQWM7UUFDZCxZQUFZLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGNBQWMsRUFBRSxFQUFFO1lBQ3BELE1BQU0sWUFBWSxHQUNoQixDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDO2dCQUNyQyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO2dCQUN0QyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEMsSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDakIsc0RBQXNEO2FBQ3ZEO1lBQ0QsT0FBTyxZQUFZLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxhQUFhLEdBQUcsUUFBUSxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLGdCQUFnQixFQUFFLENBQUM7UUFDeEUsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7T0FHRztJQUNILGNBQWMsQ0FBQyxvQkFBOEI7UUFDM0MsS0FBSyxJQUFJLGNBQWMsSUFBSSxvQkFBb0IsRUFBRTtZQUMvQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztTQUMzQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILGdCQUFnQjtRQUNkLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFTSxtQkFBbUIsQ0FBQyxVQUFrQjtRQUMzQyxJQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBRXRCLHlCQUF5QjtRQUN6QixLQUFLLE1BQU0sY0FBYyxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFDakQsWUFBWSxHQUFHLFlBQVksR0FBRyxVQUFVLGNBQWMsTUFBTSxDQUFDO1NBQzlEO1FBRUQsMkJBQTJCO1FBQzNCLElBQUksVUFBVSxHQUFHLFlBQVksQ0FBQztRQUM5QixLQUFLLE1BQU0sT0FBTyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDdkMsVUFBVSxJQUFJLElBQUksT0FBTyxFQUFFLENBQUM7U0FDN0I7UUFDRCxVQUFVLElBQUksTUFBTSxDQUFDO1FBRXJCLFFBQVEsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNyQixLQUFLLE1BQU07Z0JBQ1QsYUFBYSxHQUFHLFlBQVksVUFBVSxHQUFHLFlBQVksR0FBRyxVQUFVLEdBQUcsQ0FBQztnQkFDdEUsTUFBTTtZQUNSLEtBQUssSUFBSTtnQkFDUCxhQUFhLEdBQUcsR0FBRyxVQUFVLEdBQUcsWUFBWSxHQUFHLFVBQVUsRUFBRSxDQUFDO2dCQUM1RCxNQUFNO1NBQ1Q7UUFDRCxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM3QyxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0NBQ0YifQ==
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/**
|
|
3
|
+
* a log handler for spawned logs
|
|
4
|
+
* making sure the process doesn't run out of memory
|
|
5
|
+
*/
|
|
6
|
+
export declare class ShellLog {
|
|
7
|
+
logStore: Buffer;
|
|
8
|
+
/**
|
|
9
|
+
* log data to console
|
|
10
|
+
* @param dataArg
|
|
11
|
+
*/
|
|
12
|
+
writeToConsole(dataArg: string | Buffer): void;
|
|
13
|
+
/**
|
|
14
|
+
* add data to Buffer for later consumption
|
|
15
|
+
* @param dataArg
|
|
16
|
+
*/
|
|
17
|
+
addToBuffer(dataArg: string | Buffer): void;
|
|
18
|
+
logAndAdd(dataArg: string | Buffer): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as plugins from './smartshell.plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* a log handler for spawned logs
|
|
4
|
+
* making sure the process doesn't run out of memory
|
|
5
|
+
*/
|
|
6
|
+
export class ShellLog {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.logStore = Buffer.from('');
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* log data to console
|
|
12
|
+
* @param dataArg
|
|
13
|
+
*/
|
|
14
|
+
writeToConsole(dataArg) {
|
|
15
|
+
// make sure we have the data as string
|
|
16
|
+
process.stdout.write(dataArg);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* add data to Buffer for later consumption
|
|
20
|
+
* @param dataArg
|
|
21
|
+
*/
|
|
22
|
+
addToBuffer(dataArg) {
|
|
23
|
+
// make sure we have the data as Buffer
|
|
24
|
+
const dataBuffer = (() => {
|
|
25
|
+
if (!Buffer.isBuffer(dataArg)) {
|
|
26
|
+
return Buffer.from(dataArg);
|
|
27
|
+
}
|
|
28
|
+
return dataArg;
|
|
29
|
+
})();
|
|
30
|
+
this.logStore = Buffer.concat([this.logStore, dataBuffer]);
|
|
31
|
+
}
|
|
32
|
+
logAndAdd(dataArg) {
|
|
33
|
+
this.writeToConsole(dataArg);
|
|
34
|
+
this.addToBuffer(dataArg);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC5jbGFzc2VzLnNoZWxsbG9nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzaGVsbC5jbGFzc2VzLnNoZWxsbG9nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0seUJBQXlCLENBQUM7QUFFbkQ7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFBckI7UUFDUyxhQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQThCcEMsQ0FBQztJQTVCQzs7O09BR0c7SUFDSSxjQUFjLENBQUMsT0FBd0I7UUFDNUMsdUNBQXVDO1FBQ3ZDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7O09BR0c7SUFDSSxXQUFXLENBQUMsT0FBd0I7UUFDekMsdUNBQXVDO1FBQ3ZDLE1BQU0sVUFBVSxHQUFXLENBQUMsR0FBRyxFQUFFO1lBQy9CLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUM3QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDN0I7WUFDRCxPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ0wsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFTSxTQUFTLENBQUMsT0FBd0I7UUFDdkMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVCLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import * as plugins from './smartshell.plugins.js';
|
|
3
|
+
import { ShellEnv } from './smartshell.classes.shellenv.js';
|
|
4
|
+
import type { IShellEnvContructorOptions } from './smartshell.classes.shellenv.js';
|
|
5
|
+
import * as cp from 'child_process';
|
|
6
|
+
export interface IExecResult {
|
|
7
|
+
exitCode: number;
|
|
8
|
+
stdout: string;
|
|
9
|
+
}
|
|
10
|
+
export interface IExecResultStreaming {
|
|
11
|
+
childProcess: cp.ChildProcess;
|
|
12
|
+
finalPromise: Promise<IExecResult>;
|
|
13
|
+
kill: () => void;
|
|
14
|
+
terminate: () => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class Smartshell {
|
|
17
|
+
shellEnv: ShellEnv;
|
|
18
|
+
smartexit: plugins.smartexit.SmartExit;
|
|
19
|
+
constructor(optionsArg: IShellEnvContructorOptions);
|
|
20
|
+
/**
|
|
21
|
+
* executes a given command async
|
|
22
|
+
*/
|
|
23
|
+
private _exec;
|
|
24
|
+
exec(commandString: string): Promise<IExecResult>;
|
|
25
|
+
execSilent(commandString: string): Promise<IExecResult>;
|
|
26
|
+
execStrict(commandString: string): Promise<IExecResult>;
|
|
27
|
+
execStrictSilent(commandString: string): Promise<IExecResult>;
|
|
28
|
+
execStreaming(commandString: string, silent?: boolean): Promise<IExecResultStreaming>;
|
|
29
|
+
execStreamingSilent(commandString: string): Promise<IExecResultStreaming>;
|
|
30
|
+
execInteractive(commandString: string): Promise<void>;
|
|
31
|
+
execAndWaitForLine(commandString: string, regexArg: RegExp, silentArg?: boolean): Promise<unknown>;
|
|
32
|
+
execAndWaitForLineSilent(commandString: string, regexArg: RegExp): Promise<unknown>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as plugins from './smartshell.plugins.js';
|
|
2
|
+
import { ShellEnv } from './smartshell.classes.shellenv.js';
|
|
3
|
+
import { ShellLog } from './smartshell.classes.shelllog.js';
|
|
4
|
+
import * as cp from 'child_process';
|
|
5
|
+
export class Smartshell {
|
|
6
|
+
constructor(optionsArg) {
|
|
7
|
+
this.smartexit = new plugins.smartexit.SmartExit();
|
|
8
|
+
this.shellEnv = new ShellEnv(optionsArg);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* executes a given command async
|
|
12
|
+
*/
|
|
13
|
+
async _exec(options) {
|
|
14
|
+
if (options.interactive) {
|
|
15
|
+
if (process.env.CI) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const done = plugins.smartpromise.defer();
|
|
19
|
+
// Notice that stdio is set to 'inherit'
|
|
20
|
+
const shell = cp.spawn(options.commandString, {
|
|
21
|
+
stdio: 'inherit',
|
|
22
|
+
shell: true,
|
|
23
|
+
detached: true
|
|
24
|
+
});
|
|
25
|
+
this.smartexit.addProcess(shell);
|
|
26
|
+
shell.on('close', (code) => {
|
|
27
|
+
console.log(`interactive shell terminated with code ${code}`);
|
|
28
|
+
this.smartexit.removeProcess(shell);
|
|
29
|
+
done.resolve();
|
|
30
|
+
});
|
|
31
|
+
await done.promise;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const done = plugins.smartpromise.defer();
|
|
35
|
+
const childProcessEnded = plugins.smartpromise.defer();
|
|
36
|
+
let commandToExecute = options.commandString;
|
|
37
|
+
commandToExecute = this.shellEnv.createEnvExecString(options.commandString);
|
|
38
|
+
const spawnlogInstance = new ShellLog();
|
|
39
|
+
const execChildProcess = cp.spawn(commandToExecute, [], {
|
|
40
|
+
shell: true,
|
|
41
|
+
cwd: process.cwd(),
|
|
42
|
+
env: process.env,
|
|
43
|
+
detached: false,
|
|
44
|
+
});
|
|
45
|
+
this.smartexit.addProcess(execChildProcess);
|
|
46
|
+
execChildProcess.stdout.on('data', (data) => {
|
|
47
|
+
if (!options.silent) {
|
|
48
|
+
spawnlogInstance.writeToConsole(data);
|
|
49
|
+
}
|
|
50
|
+
spawnlogInstance.addToBuffer(data);
|
|
51
|
+
});
|
|
52
|
+
execChildProcess.stderr.on('data', (data) => {
|
|
53
|
+
if (!options.silent) {
|
|
54
|
+
spawnlogInstance.writeToConsole(data);
|
|
55
|
+
}
|
|
56
|
+
spawnlogInstance.addToBuffer(data);
|
|
57
|
+
});
|
|
58
|
+
execChildProcess.on('exit', (code, signal) => {
|
|
59
|
+
this.smartexit.removeProcess(execChildProcess);
|
|
60
|
+
if (options.strict && code === 1) {
|
|
61
|
+
done.reject();
|
|
62
|
+
}
|
|
63
|
+
const execResult = {
|
|
64
|
+
exitCode: code,
|
|
65
|
+
stdout: spawnlogInstance.logStore.toString(),
|
|
66
|
+
};
|
|
67
|
+
if (!options.streaming) {
|
|
68
|
+
done.resolve(execResult);
|
|
69
|
+
}
|
|
70
|
+
childProcessEnded.resolve(execResult);
|
|
71
|
+
});
|
|
72
|
+
if (options.streaming) {
|
|
73
|
+
done.resolve({
|
|
74
|
+
childProcess: execChildProcess,
|
|
75
|
+
finalPromise: childProcessEnded.promise,
|
|
76
|
+
kill: () => {
|
|
77
|
+
console.log(`running tree kill with SIGKILL on process ${execChildProcess.pid}`);
|
|
78
|
+
plugins.treeKill(execChildProcess.pid, 'SIGKILL');
|
|
79
|
+
},
|
|
80
|
+
terminate: () => {
|
|
81
|
+
console.log(`running tree kill with SIGTERM on process ${execChildProcess.pid}`);
|
|
82
|
+
plugins.treeKill(execChildProcess.pid, 'SIGTERM');
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return await done.promise;
|
|
87
|
+
}
|
|
88
|
+
async exec(commandString) {
|
|
89
|
+
return (await this._exec({ commandString }));
|
|
90
|
+
}
|
|
91
|
+
async execSilent(commandString) {
|
|
92
|
+
return (await this._exec({ commandString, silent: true }));
|
|
93
|
+
}
|
|
94
|
+
async execStrict(commandString) {
|
|
95
|
+
return (await this._exec({ commandString, strict: true }));
|
|
96
|
+
}
|
|
97
|
+
async execStrictSilent(commandString) {
|
|
98
|
+
return (await this._exec({ commandString, silent: true, strict: true }));
|
|
99
|
+
}
|
|
100
|
+
async execStreaming(commandString, silent = false) {
|
|
101
|
+
return (await this._exec({ commandString, silent, streaming: true }));
|
|
102
|
+
}
|
|
103
|
+
async execStreamingSilent(commandString) {
|
|
104
|
+
return (await this._exec({
|
|
105
|
+
commandString,
|
|
106
|
+
silent: true,
|
|
107
|
+
streaming: true,
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
async execInteractive(commandString) {
|
|
111
|
+
await this._exec({ commandString, interactive: true });
|
|
112
|
+
}
|
|
113
|
+
async execAndWaitForLine(commandString, regexArg, silentArg = false) {
|
|
114
|
+
let done = plugins.smartpromise.defer();
|
|
115
|
+
let execStreamingResult = await this.execStreaming(commandString, silentArg);
|
|
116
|
+
execStreamingResult.childProcess.stdout.on('data', (stdOutChunk) => {
|
|
117
|
+
if (regexArg.test(stdOutChunk)) {
|
|
118
|
+
done.resolve();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return done.promise;
|
|
122
|
+
}
|
|
123
|
+
async execAndWaitForLineSilent(commandString, regexArg) {
|
|
124
|
+
return this.execAndWaitForLine(commandString, regexArg, true);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC5jbGFzc2VzLnNtYXJ0c2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHNoZWxsLmNsYXNzZXMuc21hcnRzaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUU1RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFNUQsT0FBTyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFlcEMsTUFBTSxPQUFPLFVBQVU7SUFJckIsWUFBWSxVQUFzQztRQUYzQyxjQUFTLEdBQUcsSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBR25ELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLEtBQUssQ0FBQyxPQU1uQjtRQUNDLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUN2QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO2dCQUNsQixPQUFPO2FBQ1I7WUFFRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRTFDLHdDQUF3QztZQUN4QyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUU7Z0JBQzVDLEtBQUssRUFBRSxTQUFTO2dCQUNoQixLQUFLLEVBQUUsSUFBSTtnQkFDWCxRQUFRLEVBQUUsSUFBSTthQUNmLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRWpDLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsSUFB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
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as smartdelay from '@pushrocks/smartdelay';
|
|
2
|
+
import * as smartexit from '@pushrocks/smartexit';
|
|
3
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
4
|
+
import which from 'which';
|
|
5
|
+
export { smartdelay, smartexit, smartpromise, which };
|
|
6
|
+
import treeKill from 'tree-kill';
|
|
7
|
+
export { treeKill };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as smartdelay from '@pushrocks/smartdelay';
|
|
2
|
+
import * as smartexit from '@pushrocks/smartexit';
|
|
3
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
4
|
+
import which from 'which';
|
|
5
|
+
export { smartdelay, smartexit, smartpromise, which };
|
|
6
|
+
// third party
|
|
7
|
+
import treeKill from 'tree-kill';
|
|
8
|
+
export { treeKill };
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzaGVsbC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRzaGVsbC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEtBQUssWUFBWSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hELE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUUxQixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFFdEQsY0FBYztBQUNkLE9BQU8sUUFBUSxNQUFNLFdBQVcsQ0FBQztBQUVqQyxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUMifQ==
|
package/npmextra.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"npmci": {
|
|
3
|
+
"npmGlobalTools": [],
|
|
4
|
+
"npmAccessLevel": "public",
|
|
5
|
+
"npmRegistryUrl": "registry.npmjs.org"
|
|
6
|
+
},
|
|
7
|
+
"gitzone": {
|
|
8
|
+
"projectType": "npm",
|
|
9
|
+
"module": {
|
|
10
|
+
"githost": "gitlab.com",
|
|
11
|
+
"gitscope": "pushrocks",
|
|
12
|
+
"gitrepo": "smartshell",
|
|
13
|
+
"description": "shell actions designed as promises",
|
|
14
|
+
"npmPackagename": "@pushrocks/smartshell",
|
|
15
|
+
"license": "MIT"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@push.rocks/smartshell",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "3.0.3",
|
|
5
|
+
"description": "shell actions designed as promises",
|
|
6
|
+
"main": "dist_ts/index.js",
|
|
7
|
+
"typings": "dist_ts/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "(tstest test/)",
|
|
11
|
+
"build": "(tsbuild --web)",
|
|
12
|
+
"buildDocs": "tsdoc"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+ssh://git@gitlab.com/pushrocks/smartshell.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"shell",
|
|
20
|
+
"promise"
|
|
21
|
+
],
|
|
22
|
+
"author": "Lossless GmbH",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://gitlab.com/pushrocks/smartshell/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://gitlab.com/pushrocks/smartshell#README",
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@gitzone/tsbuild": "^2.1.66",
|
|
30
|
+
"@gitzone/tsrun": "^1.2.42",
|
|
31
|
+
"@gitzone/tstest": "^1.0.74",
|
|
32
|
+
"@pushrocks/tapbundle": "^5.0.8",
|
|
33
|
+
"@types/node": "^20.3.1"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@pushrocks/smartdelay": "^3.0.1",
|
|
37
|
+
"@pushrocks/smartexit": "^1.0.20",
|
|
38
|
+
"@pushrocks/smartpromise": "^4.0.2",
|
|
39
|
+
"@types/which": "^3.0.0",
|
|
40
|
+
"tree-kill": "^1.2.2",
|
|
41
|
+
"which": "^3.0.1"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"ts/**/*",
|
|
45
|
+
"ts_web/**/*",
|
|
46
|
+
"dist/**/*",
|
|
47
|
+
"dist_*/**/*",
|
|
48
|
+
"dist_ts/**/*",
|
|
49
|
+
"dist_ts_web/**/*",
|
|
50
|
+
"assets/**/*",
|
|
51
|
+
"cli.js",
|
|
52
|
+
"npmextra.json",
|
|
53
|
+
"readme.md"
|
|
54
|
+
],
|
|
55
|
+
"browserslist": [
|
|
56
|
+
"last 1 chrome versions"
|
|
57
|
+
]
|
|
58
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @pushrocks/smartshell
|
|
2
|
+
shell actions designed as promises
|
|
3
|
+
|
|
4
|
+
## Availabililty and Links
|
|
5
|
+
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartshell)
|
|
6
|
+
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartshell)
|
|
7
|
+
* [github.com (source mirror)](https://github.com/pushrocks/smartshell)
|
|
8
|
+
* [docs (typedoc)](https://pushrocks.gitlab.io/smartshell/)
|
|
9
|
+
|
|
10
|
+
## Status for master
|
|
11
|
+
|
|
12
|
+
Status Category | Status Badge
|
|
13
|
+
-- | --
|
|
14
|
+
GitLab Pipelines | [](https://lossless.cloud)
|
|
15
|
+
GitLab Pipline Test Coverage | [](https://lossless.cloud)
|
|
16
|
+
npm | [](https://lossless.cloud)
|
|
17
|
+
Snyk | [](https://lossless.cloud)
|
|
18
|
+
TypeScript Support | [](https://lossless.cloud)
|
|
19
|
+
node Support | [](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
|
20
|
+
Code Style | [](https://lossless.cloud)
|
|
21
|
+
PackagePhobia (total standalone install weight) | [](https://lossless.cloud)
|
|
22
|
+
PackagePhobia (package size on registry) | [](https://lossless.cloud)
|
|
23
|
+
BundlePhobia (total size when bundled) | [](https://lossless.cloud)
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Use TypeScript for best in class instellisense.
|
|
28
|
+
|
|
29
|
+
## Contribution
|
|
30
|
+
|
|
31
|
+
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
|
32
|
+
|
|
33
|
+
For further information read the linked docs at the top of this readme.
|
|
34
|
+
|
|
35
|
+
## Legal
|
|
36
|
+
> MIT licensed | **©** [Task Venture Capital GmbH](https://task.vc)
|
|
37
|
+
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
|
package/ts/index.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export type TExecutor = 'sh' | 'bash';
|
|
2
|
+
|
|
3
|
+
export interface IShellEnvContructorOptions {
|
|
4
|
+
executor: TExecutor;
|
|
5
|
+
sourceFilePaths?: string[];
|
|
6
|
+
pathDirectories?: string[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ShellEnv {
|
|
10
|
+
executor: TExecutor;
|
|
11
|
+
sourceFileArray: string[] = [];
|
|
12
|
+
pathDirArray: string[] = [];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* constructor for the shellenv
|
|
16
|
+
*/
|
|
17
|
+
constructor(optionsArg: IShellEnvContructorOptions) {
|
|
18
|
+
this.executor = optionsArg.executor;
|
|
19
|
+
|
|
20
|
+
// add sourcefiles
|
|
21
|
+
if (optionsArg.sourceFilePaths) {
|
|
22
|
+
this.sourceFileArray = this.sourceFileArray.concat(optionsArg.sourceFilePaths);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// add pathDirectories
|
|
26
|
+
if (optionsArg.pathDirectories) {
|
|
27
|
+
this.pathDirArray = this.pathDirArray.concat(optionsArg.pathDirectories);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* imports path into the shell from env if available and returns it with
|
|
33
|
+
*/
|
|
34
|
+
private _setPath(commandStringArg: string): string {
|
|
35
|
+
let commandResult = commandStringArg;
|
|
36
|
+
let commandPaths: string[] = [];
|
|
37
|
+
commandPaths = commandPaths.concat(process.env.PATH.split(':'));
|
|
38
|
+
if (process.env.SMARTSHELL_PATH) {
|
|
39
|
+
commandPaths = commandPaths.concat(process.env.SMARTSHELL_PATH.split(':'));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// lets filter for unwanted paths
|
|
43
|
+
// Windows WSL
|
|
44
|
+
commandPaths = commandPaths.filter((commandPathArg) => {
|
|
45
|
+
const filterResult =
|
|
46
|
+
!commandPathArg.startsWith('/mnt/c/') &&
|
|
47
|
+
!commandPathArg.startsWith('Files/1E') &&
|
|
48
|
+
!commandPathArg.includes(' ');
|
|
49
|
+
if (!filterResult) {
|
|
50
|
+
// console.log(`${commandPathArg} will be filtered!`);
|
|
51
|
+
}
|
|
52
|
+
return filterResult;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
commandResult = `PATH=${commandPaths.join(':')} && ${commandStringArg}`;
|
|
56
|
+
return commandResult;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* add files that are going to be sourced when running a command
|
|
61
|
+
* @param sourceFilePathsArray
|
|
62
|
+
*/
|
|
63
|
+
addSourceFiles(sourceFilePathsArray: string[]) {
|
|
64
|
+
for (let sourceFilePath of sourceFilePathsArray) {
|
|
65
|
+
this.sourceFileArray.push(sourceFilePath);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* cleans the source files array
|
|
71
|
+
*/
|
|
72
|
+
cleanSourceFiles() {
|
|
73
|
+
this.sourceFileArray = [];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public createEnvExecString(commandArg: string): string {
|
|
77
|
+
let commandResult = '';
|
|
78
|
+
let sourceString = '';
|
|
79
|
+
|
|
80
|
+
// deal with sourcestring
|
|
81
|
+
for (const sourceFilePath of this.sourceFileArray) {
|
|
82
|
+
sourceString = sourceString + `source ${sourceFilePath} && `;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// deal with available path
|
|
86
|
+
let pathString = 'PATH=$PATH';
|
|
87
|
+
for (const pathDir of this.pathDirArray) {
|
|
88
|
+
pathString += `:${pathDir}`;
|
|
89
|
+
}
|
|
90
|
+
pathString += ` && `;
|
|
91
|
+
|
|
92
|
+
switch (this.executor) {
|
|
93
|
+
case 'bash':
|
|
94
|
+
commandResult = `bash -c '${pathString}${sourceString}${commandArg}'`;
|
|
95
|
+
break;
|
|
96
|
+
case 'sh':
|
|
97
|
+
commandResult = `${pathString}${sourceString}${commandArg}`;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
commandResult = this._setPath(commandResult);
|
|
101
|
+
return commandResult;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as plugins from './smartshell.plugins.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* a log handler for spawned logs
|
|
5
|
+
* making sure the process doesn't run out of memory
|
|
6
|
+
*/
|
|
7
|
+
export class ShellLog {
|
|
8
|
+
public logStore = Buffer.from('');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* log data to console
|
|
12
|
+
* @param dataArg
|
|
13
|
+
*/
|
|
14
|
+
public writeToConsole(dataArg: string | Buffer): void {
|
|
15
|
+
// make sure we have the data as string
|
|
16
|
+
process.stdout.write(dataArg);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* add data to Buffer for later consumption
|
|
21
|
+
* @param dataArg
|
|
22
|
+
*/
|
|
23
|
+
public addToBuffer(dataArg: string | Buffer): void {
|
|
24
|
+
// make sure we have the data as Buffer
|
|
25
|
+
const dataBuffer: Buffer = (() => {
|
|
26
|
+
if (!Buffer.isBuffer(dataArg)) {
|
|
27
|
+
return Buffer.from(dataArg);
|
|
28
|
+
}
|
|
29
|
+
return dataArg;
|
|
30
|
+
})();
|
|
31
|
+
this.logStore = Buffer.concat([this.logStore, dataBuffer]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public logAndAdd(dataArg: string | Buffer): void {
|
|
35
|
+
this.writeToConsole(dataArg);
|
|
36
|
+
this.addToBuffer(dataArg);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import * as plugins from './smartshell.plugins.js';
|
|
2
|
+
import { ShellEnv } from './smartshell.classes.shellenv.js';
|
|
3
|
+
import type { IShellEnvContructorOptions, TExecutor } from './smartshell.classes.shellenv.js';
|
|
4
|
+
import { ShellLog } from './smartshell.classes.shelllog.js';
|
|
5
|
+
|
|
6
|
+
import * as cp from 'child_process';
|
|
7
|
+
|
|
8
|
+
// -- interfaces --
|
|
9
|
+
export interface IExecResult {
|
|
10
|
+
exitCode: number;
|
|
11
|
+
stdout: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IExecResultStreaming {
|
|
15
|
+
childProcess: cp.ChildProcess;
|
|
16
|
+
finalPromise: Promise<IExecResult>;
|
|
17
|
+
kill: () => void;
|
|
18
|
+
terminate: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class Smartshell {
|
|
22
|
+
public shellEnv: ShellEnv;
|
|
23
|
+
public smartexit = new plugins.smartexit.SmartExit();
|
|
24
|
+
|
|
25
|
+
constructor(optionsArg: IShellEnvContructorOptions) {
|
|
26
|
+
this.shellEnv = new ShellEnv(optionsArg);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* executes a given command async
|
|
31
|
+
*/
|
|
32
|
+
private async _exec(options: {
|
|
33
|
+
commandString: string;
|
|
34
|
+
silent?: boolean;
|
|
35
|
+
strict?: boolean;
|
|
36
|
+
streaming?: boolean;
|
|
37
|
+
interactive?: boolean;
|
|
38
|
+
}): Promise<IExecResult | IExecResultStreaming | void> {
|
|
39
|
+
if (options.interactive) {
|
|
40
|
+
if (process.env.CI) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const done = plugins.smartpromise.defer();
|
|
45
|
+
|
|
46
|
+
// Notice that stdio is set to 'inherit'
|
|
47
|
+
const shell = cp.spawn(options.commandString, {
|
|
48
|
+
stdio: 'inherit',
|
|
49
|
+
shell: true,
|
|
50
|
+
detached: true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.smartexit.addProcess(shell);
|
|
54
|
+
|
|
55
|
+
shell.on('close', (code) => {
|
|
56
|
+
console.log(`interactive shell terminated with code ${code}`);
|
|
57
|
+
this.smartexit.removeProcess(shell);
|
|
58
|
+
done.resolve();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
await done.promise;
|
|
62
|
+
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const done = plugins.smartpromise.defer<IExecResult | IExecResultStreaming>();
|
|
67
|
+
const childProcessEnded = plugins.smartpromise.defer<IExecResult>();
|
|
68
|
+
|
|
69
|
+
let commandToExecute = options.commandString;
|
|
70
|
+
commandToExecute = this.shellEnv.createEnvExecString(options.commandString);
|
|
71
|
+
|
|
72
|
+
const spawnlogInstance = new ShellLog();
|
|
73
|
+
const execChildProcess = cp.spawn(commandToExecute, [], {
|
|
74
|
+
shell: true,
|
|
75
|
+
cwd: process.cwd(),
|
|
76
|
+
env: process.env,
|
|
77
|
+
detached: false,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
this.smartexit.addProcess(execChildProcess);
|
|
81
|
+
|
|
82
|
+
execChildProcess.stdout.on('data', (data) => {
|
|
83
|
+
if (!options.silent) {
|
|
84
|
+
spawnlogInstance.writeToConsole(data);
|
|
85
|
+
}
|
|
86
|
+
spawnlogInstance.addToBuffer(data);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
execChildProcess.stderr.on('data', (data) => {
|
|
90
|
+
if (!options.silent) {
|
|
91
|
+
spawnlogInstance.writeToConsole(data);
|
|
92
|
+
}
|
|
93
|
+
spawnlogInstance.addToBuffer(data);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
execChildProcess.on('exit', (code, signal) => {
|
|
97
|
+
this.smartexit.removeProcess(execChildProcess);
|
|
98
|
+
if (options.strict && code === 1) {
|
|
99
|
+
done.reject();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const execResult = {
|
|
103
|
+
exitCode: code,
|
|
104
|
+
stdout: spawnlogInstance.logStore.toString(),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (!options.streaming) {
|
|
108
|
+
done.resolve(execResult);
|
|
109
|
+
}
|
|
110
|
+
childProcessEnded.resolve(execResult);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (options.streaming) {
|
|
114
|
+
done.resolve({
|
|
115
|
+
childProcess: execChildProcess,
|
|
116
|
+
finalPromise: childProcessEnded.promise,
|
|
117
|
+
kill: () => {
|
|
118
|
+
console.log(`running tree kill with SIGKILL on process ${execChildProcess.pid}`);
|
|
119
|
+
plugins.treeKill(execChildProcess.pid, 'SIGKILL');
|
|
120
|
+
},
|
|
121
|
+
terminate: () => {
|
|
122
|
+
console.log(`running tree kill with SIGTERM on process ${execChildProcess.pid}`);
|
|
123
|
+
plugins.treeKill(execChildProcess.pid, 'SIGTERM');
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return await done.promise;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public async exec(commandString: string): Promise<IExecResult> {
|
|
132
|
+
return (await this._exec({ commandString })) as IExecResult;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public async execSilent(commandString: string): Promise<IExecResult> {
|
|
136
|
+
return (await this._exec({ commandString, silent: true })) as IExecResult;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public async execStrict(commandString: string): Promise<IExecResult> {
|
|
140
|
+
return (await this._exec({ commandString, strict: true })) as IExecResult;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public async execStrictSilent(commandString: string): Promise<IExecResult> {
|
|
144
|
+
return (await this._exec({ commandString, silent: true, strict: true })) as IExecResult;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public async execStreaming(
|
|
148
|
+
commandString: string,
|
|
149
|
+
silent: boolean = false
|
|
150
|
+
): Promise<IExecResultStreaming> {
|
|
151
|
+
return (await this._exec({ commandString, silent, streaming: true })) as IExecResultStreaming;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public async execStreamingSilent(commandString: string): Promise<IExecResultStreaming> {
|
|
155
|
+
return (await this._exec({
|
|
156
|
+
commandString,
|
|
157
|
+
silent: true,
|
|
158
|
+
streaming: true,
|
|
159
|
+
})) as IExecResultStreaming;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public async execInteractive(commandString: string) {
|
|
163
|
+
await this._exec({ commandString, interactive: true });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public async execAndWaitForLine(
|
|
167
|
+
commandString: string,
|
|
168
|
+
regexArg: RegExp,
|
|
169
|
+
silentArg: boolean = false
|
|
170
|
+
) {
|
|
171
|
+
let done = plugins.smartpromise.defer();
|
|
172
|
+
let execStreamingResult = await this.execStreaming(commandString, silentArg);
|
|
173
|
+
execStreamingResult.childProcess.stdout.on('data', (stdOutChunk: string) => {
|
|
174
|
+
if (regexArg.test(stdOutChunk)) {
|
|
175
|
+
done.resolve();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return done.promise;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public async execAndWaitForLineSilent(commandString: string, regexArg: RegExp) {
|
|
182
|
+
return this.execAndWaitForLine(commandString, regexArg, true);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as smartdelay from '@pushrocks/smartdelay';
|
|
2
|
+
import * as smartexit from '@pushrocks/smartexit';
|
|
3
|
+
import * as smartpromise from '@pushrocks/smartpromise';
|
|
4
|
+
import which from 'which';
|
|
5
|
+
|
|
6
|
+
export { smartdelay, smartexit, smartpromise, which };
|
|
7
|
+
|
|
8
|
+
// third party
|
|
9
|
+
import treeKill from 'tree-kill';
|
|
10
|
+
|
|
11
|
+
export { treeKill };
|