@cplieger/deadset-ts 8.0.0-dev.12 → 8.0.0-dev.14
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 +2 -0
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/src/build-scripts.js +6 -13
- package/dist/src/commands/read.js +156 -0
- package/dist/src/commands/shell.js +75 -0
- package/dist/src/commands/tools.js +460 -0
- package/dist/src/configuration-files.js +11 -25
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/dependencies.js +67 -115
- package/dist/src/load/synthesize.js +12 -5
- package/dist/src/manifest.js +27 -14
- package/dist/src/roots.js +18 -11
- package/dist/src/text/named-files.js +24 -3
- package/dist/src/text/yaml.js +464 -173
- package/dist/src/vendor/unbash/ansi-c.js +132 -0
- package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
- package/dist/src/vendor/unbash/arithmetic.js +591 -0
- package/dist/src/vendor/unbash/assignment.js +131 -0
- package/dist/src/vendor/unbash/chars.js +48 -0
- package/dist/src/vendor/unbash/command.js +41 -0
- package/dist/src/vendor/unbash/expansion.js +80 -0
- package/dist/src/vendor/unbash/glob.js +268 -0
- package/dist/src/vendor/unbash/heredoc.js +27 -0
- package/dist/src/vendor/unbash/internal-types.js +1 -0
- package/dist/src/vendor/unbash/lexer.js +4274 -0
- package/dist/src/vendor/unbash/limits.js +3 -0
- package/dist/src/vendor/unbash/parser.js +1366 -0
- package/dist/src/vendor/unbash/parts.js +57 -0
- package/dist/src/vendor/unbash/substitution-context.js +8 -0
- package/dist/src/vendor/unbash/traversal.js +212 -0
- package/dist/src/vendor/unbash/types.js +1 -0
- package/dist/src/vendor/unbash/word-value.js +61 -0
- package/dist/src/vendor/unbash/word.js +40 -0
- package/dist/src/workflow-steps.js +111 -133
- package/jsr.json +2 -1
- package/package.json +4 -2
- package/src/build-scripts.ts +6 -13
- package/src/commands/read.ts +230 -0
- package/src/commands/shell.ts +126 -0
- package/src/commands/tools.ts +618 -0
- package/src/configuration-files.ts +10 -26
- package/src/conformance-record.ts +1 -1
- package/src/dependencies.ts +99 -123
- package/src/load/synthesize.ts +18 -5
- package/src/manifest.ts +43 -25
- package/src/roots.ts +20 -13
- package/src/text/named-files.ts +26 -3
- package/src/text/yaml.ts +503 -179
- package/src/vendor/unbash/LICENSE +15 -0
- package/src/vendor/unbash/VENDORED.md +16 -0
- package/src/vendor/unbash/ansi-c.ts +132 -0
- package/src/vendor/unbash/arithmetic-parts.ts +53 -0
- package/src/vendor/unbash/arithmetic.ts +641 -0
- package/src/vendor/unbash/assignment.ts +163 -0
- package/src/vendor/unbash/chars.ts +48 -0
- package/src/vendor/unbash/command.ts +47 -0
- package/src/vendor/unbash/expansion.ts +144 -0
- package/src/vendor/unbash/glob.ts +284 -0
- package/src/vendor/unbash/heredoc.ts +34 -0
- package/src/vendor/unbash/internal-types.ts +94 -0
- package/src/vendor/unbash/lexer.ts +4352 -0
- package/src/vendor/unbash/limits.ts +3 -0
- package/src/vendor/unbash/parser.ts +1612 -0
- package/src/vendor/unbash/parts.ts +96 -0
- package/src/vendor/unbash/substitution-context.ts +20 -0
- package/src/vendor/unbash/traversal.ts +182 -0
- package/src/vendor/unbash/types.ts +660 -0
- package/src/vendor/unbash/word-value.ts +64 -0
- package/src/vendor/unbash/word.ts +50 -0
- package/src/workflow-steps.ts +153 -154
- package/dist/src/text/shell.js +0 -159
- package/src/text/named-files.inputs.json +0 -1522
- package/src/text/shell.ts +0 -161
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 1 of the command reader: one command line, parsed by the vendored shell parser, as
|
|
3
|
+
* its and-or lists, their pipelines and the words of each simple command. Nothing here
|
|
4
|
+
* tokenizes, unquotes or splits text.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
parse,
|
|
9
|
+
type CommandNode,
|
|
10
|
+
type PipelineNode,
|
|
11
|
+
type Word as ShellWord,
|
|
12
|
+
type WordPart,
|
|
13
|
+
} from "../vendor/unbash/parser.ts";
|
|
14
|
+
|
|
15
|
+
/** One word of a simple command: its value, or `undefined` where the shell computes it. */
|
|
16
|
+
export interface Word {
|
|
17
|
+
readonly value: string | undefined;
|
|
18
|
+
/** The word as the line writes it. */
|
|
19
|
+
readonly text: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** One pipeline of an and-or list. */
|
|
23
|
+
export interface Pipeline {
|
|
24
|
+
/** The operator that joins it to the pipeline before it, `undefined` for a list's first. */
|
|
25
|
+
readonly operator: "&&" | "||" | undefined;
|
|
26
|
+
/** Whether a `!` inverts its status. */
|
|
27
|
+
readonly negated: boolean;
|
|
28
|
+
/** The words of each member that is a simple command with a program word. */
|
|
29
|
+
readonly commands: readonly (readonly Word[])[];
|
|
30
|
+
/**
|
|
31
|
+
* Whether it has one member, which runs in the line's own shell; with several, each member
|
|
32
|
+
* runs in a subshell of its own, whatever it is.
|
|
33
|
+
*/
|
|
34
|
+
readonly alone: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Whether its one member is no simple command but a compound command, whose commands may
|
|
37
|
+
* change the line's shell's directory, or a function definition, whose later calls may.
|
|
38
|
+
*/
|
|
39
|
+
readonly opaque: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** One and-or list: its pipelines, run in a subshell where `&` sends it to the background. */
|
|
43
|
+
interface List {
|
|
44
|
+
readonly background: boolean;
|
|
45
|
+
readonly pipelines: readonly Pipeline[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Whether one part of a word has a value the line states: a literal, quoted or escaped text. */
|
|
49
|
+
function isStatic(part: WordPart): boolean {
|
|
50
|
+
switch (part.type) {
|
|
51
|
+
case "Literal":
|
|
52
|
+
case "SingleQuoted":
|
|
53
|
+
case "AnsiCQuoted":
|
|
54
|
+
return true;
|
|
55
|
+
case "DoubleQuoted":
|
|
56
|
+
return part.parts.every((child) => child.type === "Literal");
|
|
57
|
+
default:
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* One word as layer 1 reads it. A tilde that starts the word unquoted is the parser's literal
|
|
64
|
+
* text but the shell's home directory, so it makes the word dynamic too.
|
|
65
|
+
*/
|
|
66
|
+
function wordOf(word: ShellWord): Word {
|
|
67
|
+
const [first] = word.parts ?? [];
|
|
68
|
+
const lead = word.parts === undefined ? word.text : first?.type === "Literal" ? first.text : "";
|
|
69
|
+
const known = (word.parts ?? []).every(isStatic) && !lead.startsWith("~");
|
|
70
|
+
return { value: known ? word.value : undefined, text: word.text };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Whether one member of a pipeline, run in the line's own shell, may change that shell's
|
|
75
|
+
* directory without being a simple command: POSIX XCU 2.9.4 runs every compound command but
|
|
76
|
+
* `( )` in the current environment, and a function body runs there when called.
|
|
77
|
+
*/
|
|
78
|
+
function isOpaque(node: CommandNode): boolean {
|
|
79
|
+
switch (node.type) {
|
|
80
|
+
case "Command":
|
|
81
|
+
case "Subshell":
|
|
82
|
+
case "Coproc":
|
|
83
|
+
case "TestCommand":
|
|
84
|
+
case "ArithmeticCommand":
|
|
85
|
+
return false;
|
|
86
|
+
case "Redirected":
|
|
87
|
+
return isOpaque(node.command);
|
|
88
|
+
default:
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function pipelineOf(node: PipelineNode, operator: Pipeline["operator"]): Pipeline {
|
|
94
|
+
const members = node.type === "Pipeline" ? node.commands : [node];
|
|
95
|
+
const negated =
|
|
96
|
+
node.type === "Pipeline" && node.prefixes.some((prefix) => prefix.type === "Negation");
|
|
97
|
+
const commands = members.flatMap((member) =>
|
|
98
|
+
member.type === "Command" && member.name !== undefined
|
|
99
|
+
? [[member.name, ...member.suffix.filter((part) => part.type === "Word")].map(wordOf)]
|
|
100
|
+
: [],
|
|
101
|
+
);
|
|
102
|
+
const alone = members.length === 1;
|
|
103
|
+
return { operator, negated, commands, alone, opaque: alone && members.some(isOpaque) };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The and-or lists one command line runs, or none where any of it does not parse. A simple
|
|
108
|
+
* command's assignments and redirections are no words; a part that is no simple command
|
|
109
|
+
* gives no words, and marks its pipeline where it may change the line's directory.
|
|
110
|
+
*/
|
|
111
|
+
export function shellLine(source: string): readonly List[] {
|
|
112
|
+
const script = parse(source);
|
|
113
|
+
if ((script.errors ?? []).length > 0) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
return script.commands.map((statement) => {
|
|
117
|
+
const { command } = statement;
|
|
118
|
+
const pipelines =
|
|
119
|
+
command.type === "AndOr"
|
|
120
|
+
? command.commands.map((one, at) =>
|
|
121
|
+
pipelineOf(one, at === 0 ? undefined : command.operators[at - 1]),
|
|
122
|
+
)
|
|
123
|
+
: [pipelineOf(command, undefined)];
|
|
124
|
+
return { background: statement.background === true, pipelines };
|
|
125
|
+
});
|
|
126
|
+
}
|