textrun-shell 0.3.1 → 0.4.1

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 CHANGED
@@ -3,55 +3,79 @@
3
3
  This package provides [Text-Runner](https://github.com/kevgo/text-runner)
4
4
  actions for documenting console commands to be executed by the reader.
5
5
 
6
- ### Setup
6
+ ## Setup
7
7
 
8
- To add this package as a Text-Runner plugin, run <code type="npm/install">npm i
9
- -D textrun-shell</code>.
8
+ To add this package as a Text-Runner plugin:
9
+
10
+ <pre type="npm/install">
11
+ npm i -D textrun-shell
12
+ </pre>
10
13
 
11
14
  <!-- TODO: verify this somehow -->
12
15
 
13
- You can define the absolute path of documented binaries in a
14
- **textrun-shell.js** file in the root directory of your documentation. Here is
15
- an example:
16
+ You can define the absolute path of binaries that your documentation tests call
17
+ by creating a file **textrun-shell.js** file in the root directory of your
18
+ documentation. Here is an example:
16
19
 
17
20
  ```js
21
+ import * as path from "path"
22
+ import * as url from "url"
23
+
24
+ const __dirname = url.fileURLToPath(new URL(".", import.meta.url))
25
+ const foo_path = path.join(__dirname, "bin", "foo")
26
+ // console.log(`calling "foo" in the documentation now runs ${foo_path}`)
27
+
18
28
  export default {
19
- binaries: {
20
- "text-runner": path.join(__dirname, "node_modules", ".bin", "text-runner")
29
+ globals: {
30
+ "foo": foo_path
21
31
  }
22
32
  }
23
33
  ```
24
34
 
25
- ### Run shell commands
35
+ ## shell/command
26
36
 
27
37
  The <b type="action/name-full">shell/command</b> action runs a shell command and
28
- waits until it finishes. As an example, here is a little hypothetical Shell
29
- tutorial:
30
-
31
- > The "echo" command prints text on the command line. For example, let's run:
32
- >
33
- > ```
34
- > $ echo Hello world!
35
- > ```
36
- >
37
- > It welcomes us with a nice greeting:
38
- >
39
- > ```
40
- > Hello world!
41
- > ```
42
-
43
- The source code of this Shell tutorial when executed and verified by Text-Runner
44
- looks like this:
38
+ waits until it finishes. The <b type="action/name-full">shell/command-output</b>
39
+ action verifies the output of the most recently executed shell command.
40
+
41
+ As an example, here is a hypothetical tutorial for how to use the Linux shell:
45
42
 
46
43
  <a type="extension/runnable-region">
47
44
 
48
- ```md
45
+ ```html
49
46
  The "echo" command prints text on the command line. For example, let's run:
50
47
 
51
48
  <pre type="shell/command">
52
49
  echo Hello world!
53
50
  </pre>
51
+ ```
52
+
53
+ </a>
54
+
55
+ Some tutorials print a dollar sign at the beginning of the command to execute,
56
+ indicating an interactive command prompt. These dollar signs are ignored.
57
+
58
+ ### allow-error attribute
59
+
60
+ By default, this step fails if the subshell command exits with a non-zero exit
61
+ code. To allow errors, add the `allow-error` attribute, like so:
62
+
63
+ ```html
64
+ <pre type="shell/command" allow-error>
65
+ echo Hello world!
66
+ </pre>
67
+ ```
68
+
69
+ ## shell/command-output
70
+
71
+ The <b type="action/name-full">shell/command-output</b> action verifies the
72
+ output of the most recently executed shell command.
73
+
74
+ Here is the next paragraph of our hypothetical tutorial for the Linux shell:
75
+
76
+ <a type="extension/runnable-region">
54
77
 
78
+ ```md
55
79
  It welcomes us with a nice greeting:
56
80
 
57
81
  <pre type="shell/command-output">
@@ -61,11 +85,10 @@ Hello world!
61
85
 
62
86
  </a>
63
87
 
64
- Dollar signs at the beginning of lines indicate a shell prompt and are ignored.
65
- The <b type="action/name-full">shell/command-output</b> action documents output
66
- of the last shell command run.
88
+ Some tutorials print a dollar sign at the beginning of the command to execute,
89
+ indicating an interactive command prompt. These dollar signs are ignored.
67
90
 
68
- ### User input
91
+ ## shell/command-with-input
69
92
 
70
93
  You can run a shell command and enter text into it with the
71
94
  <b type="action/name-full">shell/command-with-input</b> action.
@@ -115,7 +138,7 @@ and provide user input with an HTML table:
115
138
  </tr>
116
139
  <tr>
117
140
  <td>which day is today</td>
118
- <td>Friday</td>
141
+ <td>Monday</td>
119
142
  </tr>
120
143
  </table>
121
144
 
@@ -124,22 +147,23 @@ and provide user input with an HTML table:
124
147
  It prints:
125
148
 
126
149
  <pre type="shell/command-output">
127
- Hello Text-Runner, happy Friday!
128
- </pre>.
150
+ Hello Text-Runner, happy Monday!
151
+ </pre>
129
152
 
130
153
  If the table contains multiple columns, the first column contains output to wait
131
154
  for, and the last one text to enter once the output from the first column has
132
155
  appeared. Middle columns are ignored. `<th>` elements are considered
133
156
  descriptions and are also ignored.
134
157
 
135
- ### Long-running processes
158
+ ## shell/server
136
159
 
137
160
  Long-running processes, for example web or database servers, keep running while
138
161
  Text-Runner continues executing other actions.
139
162
 
140
163
  <a type="workspace/new-file">
141
164
 
142
- As an example, let's say we have a server called **server.js**:
165
+ As an example, let's say we write a tutorial about developing a web server, have
166
+ just created an implementation in file **server.js**:
143
167
 
144
168
  ```js
145
169
  console.log("server is running")
@@ -148,11 +172,9 @@ setTimeout(() => {}, 100_000)
148
172
 
149
173
  </a>
150
174
 
151
- Start this long-running server to run in parallel with Text-Runner with the
152
- <b type="action/name-full">shell/server</b> action. Wait for output using the
153
- <b type="action/name-full">shell/server-output</b> action. Stop the server with
154
- the <b type="action/name-full">shell/stop-server</b> action. Here is an example
155
- that shows them in action:
175
+ Our tutorial instructs the user to start this long-running server to run in
176
+ parallel with Text-Runner with the
177
+ <b type="action/name-full">shell/server</b> action:
156
178
 
157
179
  <a type="extension/runnable-region">
158
180
 
@@ -162,16 +184,46 @@ Start the server:
162
184
  <pre type="shell/server">
163
185
  node server.js
164
186
  </pre>
187
+ ```
188
+
189
+ </a>
190
+
191
+ ## shell/server-output
165
192
 
166
- Wait until it is fully booted up:
193
+ After we started a long-running server through
194
+ <em type="action/name-full">shell/server</em> above, we can await specific
195
+ output from it using the
196
+ <b type="action/name-full">shell/server-output</b> action.
197
+
198
+ Here is the next paragraph of our hypothetic server tutorial:
199
+
200
+ <a type="extension/runnable-region">
201
+
202
+ ```html
203
+ Wait until the server is fully booted up:
167
204
 
168
205
  <pre type="shell/server-output">
169
206
  server is running
170
207
  </pre>
171
-
172
- Now you can interact with the server. When you are done, stop the server:
173
- <a type="shell/stop-server">shell/stop-server</a>
174
208
  ```
175
209
 
176
210
  </a>
211
+
212
+ ## shell/stop-server
213
+
214
+ Stop a long-running process with the
215
+ <b type="action/name-full">shell/stop-server</b> action.
216
+
217
+ Here is the final part of our hypothetical server tutorial:
218
+
219
+ <a type="extension/runnable-region">
220
+
221
+ ```html
222
+ When you are done, stop the server:
223
+
224
+ <pre type="shell/stop-server">
225
+ killall node
226
+ </pre>
177
227
  ```
228
+
229
+ </a>
@@ -1,4 +1,4 @@
1
- import * as color from "colorette";
1
+ import { styleText } from "node:util";
2
2
  import * as observableProcess from "observable-process";
3
3
  import { callArgs } from "textrun-extension";
4
4
  import { CurrentCommand } from "../helpers/current-command.js";
@@ -18,7 +18,7 @@ export async function commandWithInput(action) {
18
18
  if (commandsToRun === "") {
19
19
  throw new Error(`the <${action.region[0].tag} ${action.configuration.regionMarker}="exec-with-input"> region contains no commands to run`);
20
20
  }
21
- action.name(`running console command: ${color.cyan(commandsToRun)}`);
21
+ action.name(`running console command: ${styleText("cyan", commandsToRun)}`);
22
22
  let input = [];
23
23
  if (action.region.hasNodeOfType("table")) {
24
24
  input = getInput(action.region);
@@ -1,4 +1,4 @@
1
- import * as color from "colorette";
1
+ import { styleText } from "node:util";
2
2
  import * as observableProcess from "observable-process";
3
3
  import * as trExt from "textrun-extension";
4
4
  import { Configuration } from "../helpers/configuration.js";
@@ -6,6 +6,7 @@ import { CurrentCommand } from "../helpers/current-command.js";
6
6
  import { trimDollar } from "../helpers/trim-dollar.js";
7
7
  /** Runs the given commands synchronously on the console. */
8
8
  export async function command(action) {
9
+ action.name("run shell command");
9
10
  const configPath = action.configuration.sourceDir.joinStr("textrun-shell.js");
10
11
  const config = await Configuration.load(configPath);
11
12
  const commandsToRun = action.region
@@ -19,7 +20,8 @@ export async function command(action) {
19
20
  if (commandsToRun === "") {
20
21
  throw new Error(`the <${action.region[0].tag} ${action.configuration.regionMarker}="shell/command"> region contains no commands to run`);
21
22
  }
22
- action.name(`running console command: ${color.cyan(commandsToRun)}`);
23
+ const allowError = action.region[0].attributes["allow-error"] !== undefined;
24
+ action.name(`running console command: ${styleText("cyan", commandsToRun)}`);
23
25
  const processor = observableProcess.start(trExt.callArgs(commandsToRun, process.platform), {
24
26
  cwd: action.configuration.workspace.platformified()
25
27
  });
@@ -27,7 +29,7 @@ export async function command(action) {
27
29
  const finished = (await processor.waitForEnd());
28
30
  action.log(finished.combinedText);
29
31
  CurrentCommand.set(finished);
30
- if (finished.exitCode !== 0) {
32
+ if (finished.exitCode !== 0 && !allowError) {
31
33
  throw new Error(`command "${commandsToRun}" failed with exit code ${finished.exitCode}`);
32
34
  }
33
35
  }
@@ -1,4 +1,4 @@
1
- import * as color from "colorette";
1
+ import { styleText } from "node:util";
2
2
  import * as observableProcess from "observable-process";
3
3
  import * as trExt from "textrun-extension";
4
4
  import { CurrentServer } from "../helpers/current-server.js";
@@ -15,7 +15,7 @@ export function server(action) {
15
15
  .filter((line) => line.length > 0)
16
16
  .map(trimDollar)
17
17
  .join(" && ");
18
- action.name(`starting a server process: ${color.bold(color.cyan(commandsToRun))}`);
18
+ action.name(`starting a server process: ${styleText(["bold", "cyan"], commandsToRun)}`);
19
19
  CurrentServer.instance().set(observableProcess.start(trExt.callArgs(commandsToRun, process.platform), {
20
20
  cwd: action.configuration.workspace.platformified()
21
21
  }));
@@ -1,4 +1,6 @@
1
+ import Debug from "debug";
1
2
  import { PathMapper } from "./path-mapper.js";
3
+ const debug = Debug("shell");
2
4
  /** Configuration represents the configuration options for the textrun-shell library. */
3
5
  export class Configuration {
4
6
  constructor(file) {
@@ -13,10 +15,12 @@ export class Configuration {
13
15
  static async load(filePath) {
14
16
  try {
15
17
  const content = await import(filePath);
18
+ debug(`found path mapping in ${filePath}`);
16
19
  const config = content.default;
17
20
  return new Configuration(config);
18
21
  }
19
22
  catch (e) {
23
+ debug(`found no path mapping in ${filePath}`);
20
24
  return Configuration.default();
21
25
  }
22
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "textrun-shell",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -11,27 +11,27 @@
11
11
  "build": "tsc -p tsconfig-build.json",
12
12
  "cuke": "cucumber-js --format=progress",
13
13
  "doc": "text-runner",
14
- "fix": "eslint --fix --ignore-pattern=dist/ . && dprint fmt && sort-package-json --quiet",
14
+ "fix": "eslint --fix --ignore-pattern=dist/ . && dprint fmt && sort-package-json --quiet && ../tools/rta ghokin fmt replace features",
15
15
  "lint": "dprint check && sort-package-json --check --quiet && eslint --ignore-pattern=dist/ . && depcheck --config=../.depcheckrc",
16
16
  "reset": "rm -rf dist && yarn run build",
17
17
  "unit": "node --test --import tsx 'src/**/*.test.ts'"
18
18
  },
19
19
  "dependencies": {
20
20
  "assert-no-diff": "4.1.0",
21
- "colorette": "2.0.20",
21
+ "debug": "4.4.3",
22
22
  "end-child-processes": "2.0.3",
23
23
  "observable-process": "8.0.0",
24
- "strip-ansi": "7.1.0",
25
- "text-runner-engine": "7.1.2",
26
- "textrun-extension": "0.3.1"
24
+ "strip-ansi": "7.1.2",
25
+ "text-runner-engine": "7.2.1",
26
+ "textrun-extension": "0.4.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "shared-cucumber-steps": "*",
30
- "text-runner": "7.1.2",
31
- "textrun-action": "0.3.1",
32
- "textrun-extension": "0.3.1",
33
- "textrun-workspace": "0.3.1",
34
- "tsx": "4.19.3"
30
+ "text-runner": "7.2.1",
31
+ "textrun-action": "0.4.1",
32
+ "textrun-extension": "0.4.1",
33
+ "textrun-workspace": "0.4.1",
34
+ "tsx": "4.20.6"
35
35
  },
36
- "gitHead": "8aa3f5d9fbf24776eae6516b96ebde4863ad33a2"
36
+ "gitHead": "d407abf5515e7fe37f886dc8d51014588fb929ad"
37
37
  }