BREAKING CHANGE(update the API): update
This commit is contained in:
parent
a63ae38437
commit
2ca593297c
@ -1,32 +0,0 @@
|
|||||||
# smartshell
|
|
||||||
|
|
||||||
shell actions designed as promises
|
|
||||||
|
|
||||||
## Availabililty
|
|
||||||
|
|
||||||
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartshell)
|
|
||||||
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartshell)
|
|
||||||
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartshell)
|
|
||||||
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartshell/)
|
|
||||||
|
|
||||||
## Status for master
|
|
||||||
|
|
||||||
[![build status](https://GitLab.com/pushrocks/smartshell/badges/master/build.svg)](https://GitLab.com/pushrocks/smartshell/commits/master)
|
|
||||||
[![coverage report](https://GitLab.com/pushrocks/smartshell/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartshell/commits/master)
|
|
||||||
[![npm downloads per month](https://img.shields.io/npm/dm/smartshell.svg)](https://www.npmjs.com/package/smartshell)
|
|
||||||
[![Dependency Status](https://david-dm.org/pushrocks/smartshell.svg)](https://david-dm.org/pushrocks/smartshell)
|
|
||||||
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/smartshell/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/smartshell/master/dependencies/npm)
|
|
||||||
[![bitHound Code](https://www.bithound.io/github/pushrocks/smartshell/badges/code.svg)](https://www.bithound.io/github/pushrocks/smartshell)
|
|
||||||
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
|
||||||
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
|
||||||
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Use TypeScript for best in class instellisense.
|
|
||||||
|
|
||||||
For further information read the linked docs at the top of this README.
|
|
||||||
|
|
||||||
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
|
|
||||||
|
|
||||||
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)
|
|
28
test/test.ts
28
test/test.ts
@ -1,23 +1,31 @@
|
|||||||
import { expect, tap } from '@pushrocks/tapbundle';
|
import { expect, tap } from '@pushrocks/tapbundle';
|
||||||
|
|
||||||
import * as smartshell from '../ts/index';
|
import * as smartshell from '../ts';
|
||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@pushrocks/smartpromise';
|
||||||
|
|
||||||
let testSmartshell: smartshell.Smartshell;
|
let testSmartshell: smartshell.Smartshell;
|
||||||
|
|
||||||
|
tap.test('smartshell should create a Smartshell instance', async () => {
|
||||||
|
testSmartshell = new smartshell.Smartshell({
|
||||||
|
executor: 'bash',
|
||||||
|
sourceFilePaths: []
|
||||||
|
});
|
||||||
|
expect(testSmartshell).to.be.instanceof(smartshell.Smartshell);
|
||||||
|
});
|
||||||
|
|
||||||
tap.test('smartshell should run async', async () => {
|
tap.test('smartshell should run async', async () => {
|
||||||
let execResult = await smartshell.exec('npm -v');
|
let execResult = await testSmartshell.exec('npm -v');
|
||||||
expect(execResult.stdout).to.match(/[0-9\.]*/);
|
expect(execResult.stdout).to.match(/[0-9\.]*/);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('smartshell should run async and silent', async () => {
|
tap.test('smartshell should run async and silent', async () => {
|
||||||
let execResult = await smartshell.execSilent('npm -v');
|
let execResult = await testSmartshell.execSilent('npm -v');
|
||||||
expect(execResult.stdout).to.match(/[0-9\.]*/);
|
expect(execResult.stdout).to.match(/[0-9\.]*/);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('smartshell should stream a shell execution', async () => {
|
tap.test('smartshell should stream a shell execution', async () => {
|
||||||
let done = smartpromise.defer();
|
let done = smartpromise.defer();
|
||||||
let execStreamingResponse = smartshell.execStreaming('npm -v');
|
let execStreamingResponse = await testSmartshell.execStreaming('npm -v');
|
||||||
execStreamingResponse.childProcess.stdout.on('data', data => {
|
execStreamingResponse.childProcess.stdout.on('data', data => {
|
||||||
done.resolve(data);
|
done.resolve(data);
|
||||||
});
|
});
|
||||||
@ -27,17 +35,7 @@ tap.test('smartshell should stream a shell execution', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.test('it should execute and wait for a line in the output', async () => {
|
tap.test('it should execute and wait for a line in the output', async () => {
|
||||||
await smartshell.execAndWaitForLine('echo "5.0.4"', /5.0.4/);
|
await testSmartshell.execAndWaitForLine('echo "5.0.4"', /5.0.4/);
|
||||||
});
|
|
||||||
|
|
||||||
// Smartshell class
|
|
||||||
|
|
||||||
tap.test('smartshell should create a Smartshell instance', async () => {
|
|
||||||
testSmartshell = new smartshell.Smartshell({
|
|
||||||
executor: 'bash',
|
|
||||||
sourceFilePaths: []
|
|
||||||
});
|
|
||||||
expect(testSmartshell).to.be.instanceof(smartshell.Smartshell);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('smartshell should run async', async () => {
|
tap.test('smartshell should run async', async () => {
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export * from './smartshell.wrap';
|
|
||||||
export * from './smartshell.classes.smartshell';
|
export * from './smartshell.classes.smartshell';
|
||||||
|
50
ts/smartshell.classes.shellenv.ts
Normal file
50
ts/smartshell.classes.shellenv.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
export type TExecutor = 'sh' | 'bash';
|
||||||
|
|
||||||
|
export interface IShellEnvContructorOptions {
|
||||||
|
executor: TExecutor;
|
||||||
|
sourceFilePaths: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ShellEnv {
|
||||||
|
executor: TExecutor;
|
||||||
|
sourceFileArray: string[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for the shellenv
|
||||||
|
*/
|
||||||
|
constructor(optionsArg: IShellEnvContructorOptions) {
|
||||||
|
this.executor = optionsArg.executor;
|
||||||
|
for (let sourceFilePath of optionsArg.sourceFilePaths) {
|
||||||
|
this.sourceFileArray.push(sourceFilePath);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add files that are going to be sourced when running a command
|
||||||
|
* @param sourceFilePathsArray
|
||||||
|
*/
|
||||||
|
addSourceFiles(sourceFilePathsArray: string[]) {
|
||||||
|
for (let sourceFilePath of sourceFilePathsArray) {
|
||||||
|
this.sourceFileArray.push(sourceFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cleans the source files array
|
||||||
|
*/
|
||||||
|
cleanSourceFiles() {
|
||||||
|
this.sourceFileArray = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
createEnvExecString(commandArg): string {
|
||||||
|
if (this.executor === 'bash') {
|
||||||
|
let sourceString = '';
|
||||||
|
for (let sourceFilePath of this.sourceFileArray) {
|
||||||
|
sourceString = sourceString + `source ${sourceFilePath} && `;
|
||||||
|
}
|
||||||
|
return `bash -c '${sourceString} ${commandArg}'`;
|
||||||
|
} else {
|
||||||
|
return commandArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
ts/smartshell.classes.shelllog.ts
Normal file
44
ts/smartshell.classes.shelllog.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import * as plugins from './smartshell.plugins';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a log handler for spawned logs
|
||||||
|
* making sure the process doesn't run out of memory
|
||||||
|
*/
|
||||||
|
export class ShellLog {
|
||||||
|
logStore = Buffer.from('');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* log data to console
|
||||||
|
* @param dataArg
|
||||||
|
*/
|
||||||
|
logToConsole(dataArg: string | Buffer): void {
|
||||||
|
// make sure we have the data as string
|
||||||
|
const dataString: string = (() => {
|
||||||
|
if (Buffer.isBuffer(dataArg)) {
|
||||||
|
return dataArg.toString();
|
||||||
|
}
|
||||||
|
return dataArg;
|
||||||
|
})();
|
||||||
|
console.log(dataString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add data to Buffer for later consumption
|
||||||
|
* @param dataArg
|
||||||
|
*/
|
||||||
|
addToBuffer(dataArg: string | Buffer): void {
|
||||||
|
// make sure we have the data as Buffer
|
||||||
|
const dataBuffer: Buffer = (() => {
|
||||||
|
if (!Buffer.isBuffer(dataArg)) {
|
||||||
|
return Buffer.from(dataArg);
|
||||||
|
}
|
||||||
|
return dataArg;
|
||||||
|
})();
|
||||||
|
this.logStore = Buffer.concat([this.logStore,dataBuffer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
logAndAdd(dataArg: string | Buffer): void {
|
||||||
|
this.logToConsole(dataArg);
|
||||||
|
this.addToBuffer(dataArg);
|
||||||
|
}
|
||||||
|
}
|
@ -1,64 +1,177 @@
|
|||||||
|
// -- imports --
|
||||||
import * as plugins from './smartshell.plugins';
|
import * as plugins from './smartshell.plugins';
|
||||||
import * as smartshellWrap from './smartshell.wrap';
|
import * as smartshellWrap from './smartshell.wrap';
|
||||||
|
import { ShellEnv, IShellEnvContructorOptions, TExecutor, } from './smartshell.classes.shellenv';
|
||||||
|
import { ShellLog } from './smartshell.classes.shelllog';
|
||||||
|
|
||||||
export type TExecutor = 'sh' | 'bash';
|
import * as cp from "child_process";
|
||||||
|
import { Deferred } from "@pushrocks/smartpromise";
|
||||||
|
|
||||||
export interface ISmartshellContructorOptions {
|
// -- interfaces --
|
||||||
executor: TExecutor;
|
/**
|
||||||
sourceFilePaths: string[];
|
* interface for ExecResult
|
||||||
|
*/
|
||||||
|
export interface IExecResult {
|
||||||
|
exitCode: number;
|
||||||
|
stdout: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* interface for streaming ExecResult
|
||||||
|
*/
|
||||||
|
export interface IExecResultStreaming {
|
||||||
|
childProcess: cp.ChildProcess;
|
||||||
|
finalPromise: Promise<IExecResult>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- SmartShell --
|
||||||
export class Smartshell {
|
export class Smartshell {
|
||||||
executor: TExecutor;
|
shellEnv: ShellEnv;
|
||||||
sourceFileArray: string[] = [];
|
|
||||||
constructor(optionsArg: ISmartshellContructorOptions) {
|
|
||||||
this.executor = optionsArg.executor;
|
|
||||||
for (let sourceFilePath of optionsArg.sourceFilePaths) {
|
|
||||||
this.sourceFileArray.push(sourceFilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addSourceFiles(sourceFilePathsArray: string[]) {
|
constructor(optionsArg: IShellEnvContructorOptions) {
|
||||||
for (let sourceFilePath of sourceFilePathsArray) {
|
this.shellEnv = new ShellEnv(optionsArg);
|
||||||
this.sourceFileArray.push(sourceFilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanSourceFiles() {
|
|
||||||
this.sourceFileArray = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* executes silently and returns IExecResult
|
* imports path into the shell from env if available and returns it with
|
||||||
* @param commandArg
|
|
||||||
*/
|
*/
|
||||||
async execSilent(commandArg: string) {
|
private _importEnvVarPath (stringArg): string {
|
||||||
let execCommand = this.createExecString(commandArg);
|
if (process.env.SMARTSHELL_PATH) {
|
||||||
return await smartshellWrap.execSilent(execCommand);
|
let commandResult = `PATH=${process.env.SMARTSHELL_PATH} && ${stringArg}`;
|
||||||
}
|
// console.log(commandResult)
|
||||||
|
return commandResult;
|
||||||
/**
|
|
||||||
* executes and returns IExecResult
|
|
||||||
* @param commandArg
|
|
||||||
*/
|
|
||||||
async exec(commandArg: string) {
|
|
||||||
let execCommand = this.createExecString(commandArg);
|
|
||||||
return await smartshellWrap.exec(execCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* creates the final sourcing string
|
|
||||||
* @param commandArg
|
|
||||||
*/
|
|
||||||
private createExecString(commandArg): string {
|
|
||||||
if (this.executor === 'bash') {
|
|
||||||
let sourceString = '';
|
|
||||||
for (let sourceFilePath of this.sourceFileArray) {
|
|
||||||
sourceString = sourceString + `source ${sourceFilePath} && `;
|
|
||||||
}
|
|
||||||
return `bash -c '${sourceString} ${commandArg}'`;
|
|
||||||
} else {
|
} else {
|
||||||
return commandArg;
|
return stringArg;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a given command async
|
||||||
|
* @param commandStringArg
|
||||||
|
*/
|
||||||
|
private async _exec (
|
||||||
|
commandStringArg: string,
|
||||||
|
silentArg: boolean = false,
|
||||||
|
strictArg = false,
|
||||||
|
streamingArg = false
|
||||||
|
): Promise<IExecResult | IExecResultStreaming> {
|
||||||
|
// flow control promises
|
||||||
|
const done = plugins.smartpromise.defer<IExecResult | IExecResultStreaming>();
|
||||||
|
const childProcessEnded = plugins.smartpromise.defer<IExecResult>();
|
||||||
|
// build commandToExecute
|
||||||
|
let commandToExecute = commandStringArg
|
||||||
|
commandToExecute = this.shellEnv.createEnvExecString(commandStringArg);
|
||||||
|
commandToExecute = this._importEnvVarPath(commandToExecute);
|
||||||
|
const spawnlogInstance = new ShellLog();
|
||||||
|
const execChildProcess = cp.spawn(commandToExecute, [], {
|
||||||
|
shell: true,
|
||||||
|
env: process.env
|
||||||
|
});
|
||||||
|
|
||||||
|
execChildProcess.stdout.on("data", data => {
|
||||||
|
if (!silentArg) {
|
||||||
|
spawnlogInstance.logToConsole(data);
|
||||||
}
|
}
|
||||||
|
spawnlogInstance.addToBuffer(data);
|
||||||
|
});
|
||||||
|
execChildProcess.stderr.on("data", data => {
|
||||||
|
if (!silentArg) {
|
||||||
|
spawnlogInstance.logToConsole(data);
|
||||||
|
}
|
||||||
|
spawnlogInstance.addToBuffer(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(streamingArg) {
|
||||||
|
done.resolve({
|
||||||
|
childProcess: execChildProcess,
|
||||||
|
finalPromise: childProcessEnded.promise
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
execChildProcess.on("exit", (code, signal) => {
|
||||||
|
if(strictArg && code === 1) {
|
||||||
|
done.reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
const execResult = {
|
||||||
|
exitCode: code,
|
||||||
|
stdout: spawnlogInstance.logStore.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!streamingArg) {
|
||||||
|
done.resolve(execResult);
|
||||||
|
}
|
||||||
|
childProcessEnded.resolve(execResult);
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await done.promise;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
async exec (
|
||||||
|
commandStringArg: string
|
||||||
|
): Promise<IExecResult> {
|
||||||
|
return (await this._exec(commandStringArg, false)) as IExecResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a given command async and silent
|
||||||
|
* @param commandStringArg
|
||||||
|
*/
|
||||||
|
async execSilent (
|
||||||
|
commandStringArg: string
|
||||||
|
): Promise<IExecResult> {
|
||||||
|
return (await this._exec(commandStringArg, true)) as IExecResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a command async and strict, meaning it rejects the promise if something happens
|
||||||
|
*/
|
||||||
|
async execStrict (
|
||||||
|
commandStringArg: string
|
||||||
|
): Promise<IExecResult> {
|
||||||
|
return (await this._exec(commandStringArg, true, true)) as IExecResult;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a command and allows you to stream output
|
||||||
|
*/
|
||||||
|
async execStreaming (
|
||||||
|
commandStringArg: string,
|
||||||
|
silentArg: boolean = false
|
||||||
|
): Promise<IExecResultStreaming> {
|
||||||
|
return (await this._exec(commandStringArg, silentArg, false, true)) as IExecResultStreaming;
|
||||||
|
};
|
||||||
|
|
||||||
|
async execStreamingSilent (commandStringArg: string) {
|
||||||
|
return (await this.execStreaming(commandStringArg, true)) as IExecResultStreaming;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes a command and returns promise that will be fullfilled once an putput line matches RegexArg
|
||||||
|
* @param commandStringArg
|
||||||
|
* @param regexArg
|
||||||
|
*/
|
||||||
|
async execAndWaitForLine (
|
||||||
|
commandStringArg: string,
|
||||||
|
regexArg: RegExp,
|
||||||
|
silentArg: boolean = false
|
||||||
|
) {
|
||||||
|
let done = plugins.smartpromise.defer();
|
||||||
|
let execStreamingResult = await this.execStreaming(commandStringArg, silentArg);
|
||||||
|
execStreamingResult.childProcess.stdout.on("data", (stdOutChunk: string) => {
|
||||||
|
if (regexArg.test(stdOutChunk)) {
|
||||||
|
done.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return done.promise;
|
||||||
|
};
|
||||||
|
|
||||||
|
async execAndWaitForLineSilent (
|
||||||
|
commandStringArg: string,
|
||||||
|
regexArg: RegExp
|
||||||
|
) {
|
||||||
|
this.execAndWaitForLine(commandStringArg, regexArg, true);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import * as plugins from "./smartshell.plugins";
|
import * as plugins from "./smartshell.plugins";
|
||||||
|
import { ShellLog } from "./smartshell.classes.shelllog";
|
||||||
|
|
||||||
// interfaces
|
// interfaces
|
||||||
import * as cp from "child_process";
|
import * as cp from "child_process";
|
||||||
@ -20,174 +21,7 @@ export interface IExecResultStreaming {
|
|||||||
finalPromise: Promise<IExecResult>;
|
finalPromise: Promise<IExecResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* imports path into the shell from env if available and returns it with
|
|
||||||
*/
|
|
||||||
let importEnvVarPath = (stringArg): string => {
|
|
||||||
if (process.env.SMARTSHELL_PATH) {
|
|
||||||
let commandResult = `PATH=${process.env.SMARTSHELL_PATH} && ${stringArg}`;
|
|
||||||
// console.log(commandResult)
|
|
||||||
return commandResult;
|
|
||||||
} else {
|
|
||||||
return stringArg;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* executes a given command async
|
|
||||||
* @param commandStringArg
|
|
||||||
*/
|
|
||||||
export let exec = (
|
|
||||||
commandStringArg: string,
|
|
||||||
silentArg: boolean = false,
|
|
||||||
strictArg = false
|
|
||||||
): Promise<IExecResult> => {
|
|
||||||
let done = plugins.smartpromise.defer<IExecResult>();
|
|
||||||
const commandToExecute = importEnvVarPath(commandStringArg);
|
|
||||||
try {
|
|
||||||
const execChildProcess = cp.exec(commandToExecute, {
|
|
||||||
timeout: null,
|
|
||||||
maxBuffer: 1000000,
|
|
||||||
env: process.env
|
|
||||||
});
|
|
||||||
|
|
||||||
let logStore = "";
|
|
||||||
|
|
||||||
execChildProcess.stdout.on("data", (data: string) => {
|
|
||||||
if (!silentArg) {
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
logStore += data;
|
|
||||||
});
|
|
||||||
execChildProcess.stderr.on("data", data => {
|
|
||||||
if (!silentArg) {
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
logStore += data;
|
|
||||||
});
|
|
||||||
execChildProcess.on("exit", (code, signal) => {
|
|
||||||
done.resolve({
|
|
||||||
exitCode: code,
|
|
||||||
stdout: logStore
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
const error = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*plugins.shelljs.exec(importEnvVarPath(commandStringArg), { async: true, silent: silentArg }, (code, stdout, stderr) => {
|
|
||||||
if (
|
|
||||||
stderr
|
|
||||||
&& (stderr !== '')
|
|
||||||
&& (!silentArg || strictArg)
|
|
||||||
&& (process.env.DEBUG === 'true')
|
|
||||||
) {
|
|
||||||
console.log('StdErr found.')
|
|
||||||
console.log(stderr)
|
|
||||||
}
|
|
||||||
if (strictArg) {
|
|
||||||
done.reject(new Error(stderr))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
done.resolve({
|
|
||||||
exitCode: code,
|
|
||||||
stdout: stdout
|
|
||||||
})
|
|
||||||
})*/
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* executes a given command async and silent
|
|
||||||
* @param commandStringArg
|
|
||||||
*/
|
|
||||||
export let execSilent = async (
|
|
||||||
commandStringArg: string
|
|
||||||
): Promise<IExecResult> => {
|
|
||||||
return await exec(commandStringArg, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* executes strict, meaning it rejects the promise if something happens
|
|
||||||
*/
|
|
||||||
export let execStrict = async (
|
|
||||||
commandStringArg: string
|
|
||||||
): Promise<IExecResult> => {
|
|
||||||
return await exec(commandStringArg, true, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* executes a command and allws you to stream output
|
|
||||||
*/
|
|
||||||
export let execStreaming = (
|
|
||||||
commandStringArg: string,
|
|
||||||
silentArg: boolean = false
|
|
||||||
) => {
|
|
||||||
let childProcessEnded = plugins.smartpromise.defer<IExecResult>();
|
|
||||||
const commandToExecute = importEnvVarPath(commandStringArg);
|
|
||||||
let execChildProcess = cp.exec(commandToExecute, {
|
|
||||||
timeout: null,
|
|
||||||
maxBuffer: 1000000,
|
|
||||||
env: process.env
|
|
||||||
});
|
|
||||||
|
|
||||||
let logStore = "";
|
|
||||||
|
|
||||||
execChildProcess.stdout.on("data", (data: string) => {
|
|
||||||
if (!silentArg) {
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
logStore += data;
|
|
||||||
});
|
|
||||||
execChildProcess.stderr.on("data", data => {
|
|
||||||
if (!silentArg) {
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
logStore += data;
|
|
||||||
});
|
|
||||||
execChildProcess.on("exit", (code, signal) => {
|
|
||||||
childProcessEnded.resolve({
|
|
||||||
exitCode: code,
|
|
||||||
stdout: logStore
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
childProcess: execChildProcess,
|
|
||||||
finalPromise: childProcessEnded.promise
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export let execStreamingSilent = (commandStringArg: string) => {
|
|
||||||
return execStreaming(commandStringArg, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* executes a command and returns promise that will be fullfilled once an putput line matches RegexArg
|
|
||||||
* @param commandStringArg
|
|
||||||
* @param regexArg
|
|
||||||
*/
|
|
||||||
export let execAndWaitForLine = (
|
|
||||||
commandStringArg: string,
|
|
||||||
regexArg: RegExp,
|
|
||||||
silentArg: boolean = false
|
|
||||||
) => {
|
|
||||||
let done = plugins.smartpromise.defer();
|
|
||||||
let execStreamingResult = execStreaming(commandStringArg, silentArg);
|
|
||||||
execStreamingResult.childProcess.stdout.on("data", (stdOutChunk: string) => {
|
|
||||||
if (regexArg.test(stdOutChunk)) {
|
|
||||||
done.resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
export let execAndWaitForLineSilent = (
|
|
||||||
commandStringArg: string,
|
|
||||||
regexArg: RegExp
|
|
||||||
) => {
|
|
||||||
execAndWaitForLine(commandStringArg, regexArg, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get a path
|
* get a path
|
||||||
@ -202,3 +36,24 @@ export let which = (cmd: string): Promise<string> => {
|
|||||||
});
|
});
|
||||||
return done.promise;
|
return done.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* /////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes silently and returns IExecResult
|
||||||
|
* @param commandArg
|
||||||
|
|
||||||
|
async execSilent(commandArg: string) {
|
||||||
|
let execCommand = this..createExecString(commandArg);
|
||||||
|
return await smartshellWrap.execSilent(execCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* executes and returns IExecResult
|
||||||
|
* @param commandArg
|
||||||
|
|
||||||
|
async exec(commandArg: string) {
|
||||||
|
let execCommand = this.createExecString(commandArg);
|
||||||
|
return await smartshellWrap.exec(execCommand);
|
||||||
|
} */
|
Loading…
Reference in New Issue
Block a user