textrun-shell 0.1.2 → 0.2.0
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/README.md +4 -4
- package/dist/actions/command-output.js +5 -9
- package/dist/actions/command-with-input.js +9 -13
- package/dist/actions/command.js +11 -14
- package/dist/actions/server-output.js +3 -7
- package/dist/actions/server.js +8 -12
- package/dist/actions/stop-server.js +7 -11
- package/dist/helpers/configuration.js +6 -9
- package/dist/helpers/current-command.js +1 -5
- package/dist/helpers/current-server.js +1 -5
- package/dist/helpers/path-mapper.js +1 -5
- package/dist/helpers/trim-dollar.js +1 -5
- package/dist/index.js +13 -16
- package/package.json +22 -11
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ You can define the absolute path of documented binaries in a
|
|
|
16
16
|
an example:
|
|
17
17
|
|
|
18
18
|
```js
|
|
19
|
-
|
|
19
|
+
export default {
|
|
20
20
|
binaries: {
|
|
21
21
|
"text-run": path.join(__dirname, "node_modules", ".bin", "text-run"),
|
|
22
22
|
},
|
|
@@ -26,7 +26,7 @@ module.exports = {
|
|
|
26
26
|
### Run shell commands
|
|
27
27
|
|
|
28
28
|
The <b type="action/name-full">shell/command</b> action runs a shell command and
|
|
29
|
-
waits until it finishes. As an example, here is a little hypothetical
|
|
29
|
+
waits until it finishes. As an example, here is a little hypothetical Shell
|
|
30
30
|
tutorial:
|
|
31
31
|
|
|
32
32
|
> The "echo" command prints text on the command line. For example, let's run:
|
|
@@ -41,7 +41,7 @@ tutorial:
|
|
|
41
41
|
> Hello world!
|
|
42
42
|
> ```
|
|
43
43
|
|
|
44
|
-
The source code of this
|
|
44
|
+
The source code of this Shell tutorial when executed and verified by Text-Runner
|
|
45
45
|
looks like this:
|
|
46
46
|
|
|
47
47
|
<a type="extension/runnable-region">
|
|
@@ -77,7 +77,7 @@ As an example, let's say we have a command-line tool written in JavaScript
|
|
|
77
77
|
called **greeter.js**:
|
|
78
78
|
|
|
79
79
|
```js
|
|
80
|
-
|
|
80
|
+
import * as readline from "readline"
|
|
81
81
|
var rl = readline.createInterface({
|
|
82
82
|
input: process.stdin,
|
|
83
83
|
output: process.stdout,
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const current_command_1 = require("../helpers/current-command");
|
|
6
|
-
const stripAnsi = require("strip-ansi");
|
|
7
|
-
function commandOutput(action) {
|
|
1
|
+
import * as assertNoDiff from "assert-no-diff";
|
|
2
|
+
import stripAnsi from "strip-ansi";
|
|
3
|
+
import { CurrentCommand } from "../helpers/current-command.js";
|
|
4
|
+
export function commandOutput(action) {
|
|
8
5
|
action.name("verifying the output of the last run console command");
|
|
9
6
|
const expectedText = action.region.text();
|
|
10
7
|
const expectedLines = expectedText
|
|
11
8
|
.split("\n")
|
|
12
9
|
.map((line) => line.trim())
|
|
13
10
|
.filter((line) => line);
|
|
14
|
-
const actualOutput = stripAnsi(
|
|
11
|
+
const actualOutput = stripAnsi(CurrentCommand.instance().combinedText);
|
|
15
12
|
const actualLines = actualOutput
|
|
16
13
|
.split("\n")
|
|
17
14
|
.map(line => line.trim())
|
|
@@ -22,5 +19,4 @@ function commandOutput(action) {
|
|
|
22
19
|
}
|
|
23
20
|
assertNoDiff.trimmedLines(expectedLines.join("\n"), commonLines.join("\n"));
|
|
24
21
|
}
|
|
25
|
-
exports.commandOutput = commandOutput;
|
|
26
22
|
//# sourceMappingURL=command-output.js.map
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const textrun_extension_1 = require("textrun-extension");
|
|
7
|
-
const current_command_1 = require("../helpers/current-command");
|
|
8
|
-
const trim_dollar_1 = require("../helpers/trim-dollar");
|
|
1
|
+
import * as color from "colorette";
|
|
2
|
+
import * as observableProcess from "observable-process";
|
|
3
|
+
import { callArgs } from "textrun-extension";
|
|
4
|
+
import { CurrentCommand } from "../helpers/current-command.js";
|
|
5
|
+
import { trimDollar } from "../helpers/trim-dollar.js";
|
|
9
6
|
/**
|
|
10
7
|
* The "runConsoleCommand" action runs the given commands on the console
|
|
11
8
|
* and waits until the command is finished.
|
|
12
9
|
*/
|
|
13
|
-
async function commandWithInput(action) {
|
|
10
|
+
export async function commandWithInput(action) {
|
|
14
11
|
const content = action.region.textInNodeOfTypes("fence", "code");
|
|
15
12
|
const commandsToRun = content
|
|
16
13
|
.split("\n")
|
|
17
14
|
.map((command) => command.trim())
|
|
18
15
|
.filter((e) => e)
|
|
19
|
-
.map(
|
|
16
|
+
.map(trimDollar)
|
|
20
17
|
.join(" && ");
|
|
21
18
|
if (commandsToRun === "") {
|
|
22
19
|
throw new Error(`the <${action.region[0].tag} ${action.configuration.regionMarker}="exec-with-input"> region contains no commands to run`);
|
|
@@ -27,17 +24,16 @@ async function commandWithInput(action) {
|
|
|
27
24
|
input = getInput(action.region);
|
|
28
25
|
}
|
|
29
26
|
// this needs to be global because it is used in the "verify-run-console-output" step
|
|
30
|
-
const processor = observableProcess.start(
|
|
27
|
+
const processor = observableProcess.start(callArgs(commandsToRun, process.platform), {
|
|
31
28
|
cwd: action.configuration.workspace.platformified(),
|
|
32
29
|
});
|
|
33
30
|
for (const inputLine of input) {
|
|
34
31
|
await enter(processor, inputLine);
|
|
35
32
|
}
|
|
36
33
|
const finished = (await processor.waitForEnd());
|
|
37
|
-
|
|
34
|
+
CurrentCommand.set(finished);
|
|
38
35
|
action.log(processor.output.fullText());
|
|
39
36
|
}
|
|
40
|
-
exports.commandWithInput = commandWithInput;
|
|
41
37
|
async function enter(processor, input) {
|
|
42
38
|
processor.stdin.write(input.input + "\n");
|
|
43
39
|
if (input.textToWait) {
|
package/dist/actions/command.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const configuration_1 = require("../helpers/configuration");
|
|
8
|
-
const current_command_1 = require("../helpers/current-command");
|
|
9
|
-
const trim_dollar_1 = require("../helpers/trim-dollar");
|
|
1
|
+
import * as color from "colorette";
|
|
2
|
+
import * as observableProcess from "observable-process";
|
|
3
|
+
import * as trExt from "textrun-extension";
|
|
4
|
+
import { Configuration } from "../helpers/configuration.js";
|
|
5
|
+
import { CurrentCommand } from "../helpers/current-command.js";
|
|
6
|
+
import { trimDollar } from "../helpers/trim-dollar.js";
|
|
10
7
|
/** Runs the given commands synchronously on the console. */
|
|
11
|
-
async function command(action) {
|
|
12
|
-
const
|
|
8
|
+
export async function command(action) {
|
|
9
|
+
const configPath = action.configuration.sourceDir.joinStr("textrun-shell.js");
|
|
10
|
+
const config = await Configuration.load(configPath);
|
|
13
11
|
const commandsToRun = action.region
|
|
14
12
|
.text()
|
|
15
13
|
.split("\n")
|
|
16
14
|
.map((line) => line.trim())
|
|
17
|
-
.map(
|
|
15
|
+
.map(trimDollar)
|
|
18
16
|
.filter((line) => line.length > 0)
|
|
19
17
|
.map(config.pathMapper().globalizePathFunc())
|
|
20
18
|
.join(" && ");
|
|
@@ -28,10 +26,9 @@ async function command(action) {
|
|
|
28
26
|
// this is also used in the "verify-run-console-output" step
|
|
29
27
|
const finished = (await processor.waitForEnd());
|
|
30
28
|
action.log(finished.combinedText);
|
|
31
|
-
|
|
29
|
+
CurrentCommand.set(finished);
|
|
32
30
|
if (finished.exitCode !== 0) {
|
|
33
31
|
throw new Error(`command "${commandsToRun}" failed with exit code ${finished.exitCode}`);
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
|
-
exports.command = command;
|
|
37
34
|
//# sourceMappingURL=command.js.map
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.serverOutput = void 0;
|
|
4
|
-
const current_server_1 = require("../helpers/current-server");
|
|
1
|
+
import { CurrentServer } from "../helpers/current-server.js";
|
|
5
2
|
/**
|
|
6
3
|
* The "start-output" action waits until the currently running console command
|
|
7
4
|
* produces the given output.
|
|
8
5
|
*/
|
|
9
|
-
async function serverOutput(action) {
|
|
6
|
+
export async function serverOutput(action) {
|
|
10
7
|
action.name("verifying the output of the long-running process");
|
|
11
8
|
const expectedOutput = action.region.textInNodeOfType("fence");
|
|
12
9
|
const expectedLines = expectedOutput
|
|
13
10
|
.split("\n")
|
|
14
11
|
.map((line) => line.trim())
|
|
15
12
|
.filter((line) => line);
|
|
16
|
-
const process =
|
|
13
|
+
const process = CurrentServer.instance().process;
|
|
17
14
|
if (!process) {
|
|
18
15
|
throw new Error("Cannot verify process output since no process has been started");
|
|
19
16
|
}
|
|
@@ -23,5 +20,4 @@ async function serverOutput(action) {
|
|
|
23
20
|
}
|
|
24
21
|
action.log(process.output.fullText());
|
|
25
22
|
}
|
|
26
|
-
exports.serverOutput = serverOutput;
|
|
27
23
|
//# sourceMappingURL=server-output.js.map
|
package/dist/actions/server.js
CHANGED
|
@@ -1,27 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const trExt = require("textrun-extension");
|
|
7
|
-
const current_server_1 = require("../helpers/current-server");
|
|
8
|
-
const trim_dollar_1 = require("../helpers/trim-dollar");
|
|
1
|
+
import * as color from "colorette";
|
|
2
|
+
import * as observableProcess from "observable-process";
|
|
3
|
+
import * as trExt from "textrun-extension";
|
|
4
|
+
import { CurrentServer } from "../helpers/current-server.js";
|
|
5
|
+
import { trimDollar } from "../helpers/trim-dollar.js";
|
|
9
6
|
/**
|
|
10
7
|
* The "start" action runs the given commands on the console.
|
|
11
8
|
* It leaves the command running.
|
|
12
9
|
*/
|
|
13
|
-
function server(action) {
|
|
10
|
+
export function server(action) {
|
|
14
11
|
const commandsToRun = action.region
|
|
15
12
|
.text()
|
|
16
13
|
.split("\n")
|
|
17
14
|
.map((line) => line.trim())
|
|
18
15
|
.filter((line) => line.length > 0)
|
|
19
|
-
.map(
|
|
16
|
+
.map(trimDollar)
|
|
20
17
|
.join(" && ");
|
|
21
18
|
action.name(`starting a server process: ${color.bold(color.cyan(commandsToRun))}`);
|
|
22
|
-
|
|
19
|
+
CurrentServer.instance().set(observableProcess.start(trExt.callArgs(commandsToRun, process.platform), {
|
|
23
20
|
cwd: action.configuration.workspace.platformified(),
|
|
24
21
|
}));
|
|
25
22
|
}
|
|
26
|
-
exports.server = server;
|
|
27
23
|
//# sourceMappingURL=server.js.map
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.stopServer = void 0;
|
|
4
|
-
const end_child_processes_1 = require("end-child-processes");
|
|
5
|
-
const current_server_1 = require("../helpers/current-server");
|
|
1
|
+
import { endChildProcesses } from "end-child-processes";
|
|
2
|
+
import { CurrentServer } from "../helpers/current-server.js";
|
|
6
3
|
/**
|
|
7
4
|
* The "stop" action stops the currently running server process,
|
|
8
5
|
* started by the "start" action.
|
|
9
6
|
*/
|
|
10
|
-
async function stopServer(action) {
|
|
7
|
+
export async function stopServer(action) {
|
|
11
8
|
action.name("stopping the long-running process");
|
|
12
|
-
if (!
|
|
9
|
+
if (!CurrentServer.instance().hasProcess()) {
|
|
13
10
|
throw new Error("No running process found");
|
|
14
11
|
}
|
|
15
|
-
await
|
|
16
|
-
await
|
|
17
|
-
|
|
12
|
+
await CurrentServer.instance().kill();
|
|
13
|
+
await endChildProcesses();
|
|
14
|
+
CurrentServer.instance().reset();
|
|
18
15
|
}
|
|
19
|
-
exports.stopServer = stopServer;
|
|
20
16
|
//# sourceMappingURL=stop-server.js.map
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Configuration = void 0;
|
|
4
|
-
const path_mapper_1 = require("./path-mapper");
|
|
1
|
+
import { PathMapper } from "./path-mapper.js";
|
|
5
2
|
/** Configuration represents the configuration options for the textrun-shell library. */
|
|
6
|
-
class Configuration {
|
|
3
|
+
export class Configuration {
|
|
7
4
|
constructor(file) {
|
|
8
5
|
this.file = file;
|
|
9
6
|
}
|
|
@@ -15,8 +12,9 @@ class Configuration {
|
|
|
15
12
|
/** Provides the configuration stored in the file with the given path. */
|
|
16
13
|
static async load(filePath) {
|
|
17
14
|
try {
|
|
18
|
-
const content = await
|
|
19
|
-
|
|
15
|
+
const content = await import(filePath);
|
|
16
|
+
const config = content.default;
|
|
17
|
+
return new Configuration(config);
|
|
20
18
|
}
|
|
21
19
|
catch (e) {
|
|
22
20
|
return Configuration.default();
|
|
@@ -24,8 +22,7 @@ class Configuration {
|
|
|
24
22
|
}
|
|
25
23
|
/** provides the PathMapper instance to use */
|
|
26
24
|
pathMapper() {
|
|
27
|
-
return new
|
|
25
|
+
return new PathMapper(this.file.globals);
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
|
-
exports.Configuration = Configuration;
|
|
31
28
|
//# sourceMappingURL=configuration.js.map
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CurrentCommand = void 0;
|
|
4
1
|
/** CurrentCommand provides global access to the currently running console command. */
|
|
5
|
-
class CurrentCommand {
|
|
2
|
+
export class CurrentCommand {
|
|
6
3
|
static instance() {
|
|
7
4
|
if (!instance) {
|
|
8
5
|
throw new Error("no instance");
|
|
@@ -13,6 +10,5 @@ class CurrentCommand {
|
|
|
13
10
|
instance = process;
|
|
14
11
|
}
|
|
15
12
|
}
|
|
16
|
-
exports.CurrentCommand = CurrentCommand;
|
|
17
13
|
let instance = null;
|
|
18
14
|
//# sourceMappingURL=current-command.js.map
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CurrentServer = void 0;
|
|
4
1
|
/** CurrentServer provides global access to the currently running server process. */
|
|
5
|
-
class CurrentServer {
|
|
2
|
+
export class CurrentServer {
|
|
6
3
|
constructor() {
|
|
7
4
|
this.process = null;
|
|
8
5
|
}
|
|
@@ -23,6 +20,5 @@ class CurrentServer {
|
|
|
23
20
|
this.process = process;
|
|
24
21
|
}
|
|
25
22
|
}
|
|
26
|
-
exports.CurrentServer = CurrentServer;
|
|
27
23
|
const instance = new CurrentServer();
|
|
28
24
|
//# sourceMappingURL=current-server.js.map
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PathMapper = void 0;
|
|
4
1
|
/** Absolutifier makes */
|
|
5
|
-
class PathMapper {
|
|
2
|
+
export class PathMapper {
|
|
6
3
|
constructor(mappings) {
|
|
7
4
|
this.mappings = mappings;
|
|
8
5
|
}
|
|
@@ -20,5 +17,4 @@ class PathMapper {
|
|
|
20
17
|
return words.join(" ");
|
|
21
18
|
}
|
|
22
19
|
}
|
|
23
|
-
exports.PathMapper = PathMapper;
|
|
24
20
|
//# sourceMappingURL=path-mapper.js.map
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.trimDollar = void 0;
|
|
4
1
|
/** trims the leading dollar from the given command */
|
|
5
|
-
function trimDollar(text) {
|
|
2
|
+
export function trimDollar(text) {
|
|
6
3
|
return text.replace(/^\$?\s*/, "");
|
|
7
4
|
}
|
|
8
|
-
exports.trimDollar = trimDollar;
|
|
9
5
|
//# sourceMappingURL=trim-dollar.js.map
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
serverOutput: server_output_1.serverOutput,
|
|
15
|
-
server: server_1.server,
|
|
16
|
-
stopServer: stop_server_1.stopServer,
|
|
1
|
+
import { command } from "./actions/command.js";
|
|
2
|
+
import { commandOutput } from "./actions/command-output.js";
|
|
3
|
+
import { commandWithInput } from "./actions/command-with-input.js";
|
|
4
|
+
import { server } from "./actions/server.js";
|
|
5
|
+
import { serverOutput } from "./actions/server-output.js";
|
|
6
|
+
import { stopServer } from "./actions/stop-server.js";
|
|
7
|
+
export const textrunActions = {
|
|
8
|
+
command,
|
|
9
|
+
commandOutput,
|
|
10
|
+
commandWithInput,
|
|
11
|
+
serverOutput,
|
|
12
|
+
server,
|
|
13
|
+
stopServer,
|
|
17
14
|
};
|
|
18
15
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,26 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "textrun-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "ISC",
|
|
5
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": "./dist/index.js",
|
|
6
7
|
"files": [
|
|
7
8
|
"dist/**/*.js"
|
|
8
9
|
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -p tsconfig-build.json",
|
|
12
|
+
"clean": "rm -rf dist",
|
|
13
|
+
"cuke": "cucumber-js --format=progress",
|
|
14
|
+
"doc": "text-run static --format=summary && text-run dynamic --format=progress",
|
|
15
|
+
"fix": "eslint . --fix --ext=.ts --ignore-path=../.eslintignore && prettier --write .",
|
|
16
|
+
"lint": "prettier -l . && eslint . --ext=.ts --ignore-path=../.eslintignore && depcheck --config=../.depcheckrc",
|
|
17
|
+
"unit": "env NODE_NO_WARNINGS=1 mocha --reporter=dot 'src/**/*.test.ts'"
|
|
18
|
+
},
|
|
9
19
|
"dependencies": {
|
|
10
20
|
"assert-no-diff": "3.0.6",
|
|
11
21
|
"colorette": "2.0.19",
|
|
12
22
|
"end-child-processes": "1.0.3",
|
|
13
23
|
"observable-process": "8.0.0-pre4",
|
|
14
|
-
"strip-ansi": "
|
|
15
|
-
"text-runner-core": "
|
|
16
|
-
"textrun-extension": "
|
|
24
|
+
"strip-ansi": "7.0.1",
|
|
25
|
+
"text-runner-core": "6.0.0",
|
|
26
|
+
"textrun-extension": "0.2.0"
|
|
17
27
|
},
|
|
18
28
|
"devDependencies": {
|
|
19
|
-
"shared-cucumber-steps": "
|
|
20
|
-
"text-runner": "
|
|
21
|
-
"textrun-action": "
|
|
22
|
-
"textrun-extension": "0.
|
|
23
|
-
"textrun-workspace": "
|
|
29
|
+
"shared-cucumber-steps": "*",
|
|
30
|
+
"text-runner": "6.0.0",
|
|
31
|
+
"textrun-action": "0.2.0",
|
|
32
|
+
"textrun-extension": "0.2.0",
|
|
33
|
+
"textrun-workspace": "0.2.0",
|
|
34
|
+
"ts-node": "10.9.1"
|
|
24
35
|
},
|
|
25
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "5434976346f2e02bc08c0a6ea9f7cbfa67d68c4e"
|
|
26
37
|
}
|