depflow 3.0.0-dev.11 → 3.0.0-dev.12
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 +493 -162
- package/dist/cli/Actions.d.ts +187 -0
- package/dist/cli/Actions.js +793 -0
- package/dist/cli/Actions.js.map +1 -0
- package/dist/cli/CLI.d.ts +15 -2
- package/dist/cli/CLI.js +19 -2
- package/dist/cli/CLI.js.map +1 -1
- package/dist/cli/DepflowCLI.d.ts +62 -0
- package/dist/cli/DepflowCLI.js +229 -0
- package/dist/cli/DepflowCLI.js.map +1 -0
- package/dist/cli/bin.js +27 -32
- package/dist/cli/bin.js.map +1 -1
- package/dist/config/Config.d.ts +1 -1
- package/dist/dependency/DepUtils.d.ts +35 -7
- package/dist/dependency/DepUtils.js +64 -13
- package/dist/dependency/DepUtils.js.map +1 -1
- package/dist/schema/Config/Config.d.ts +1 -1
- package/dist/schema/Config/Dependency.d.ts +3 -3
- package/dist/schema/Config/Dependency.js +3 -3
- package/dist/schema/Config/Dependency.js.map +1 -1
- package/package.json +3 -2
- package/dist/cli/DepFLowCLI.d.ts +0 -93
- package/dist/cli/DepFLowCLI.js +0 -413
- package/dist/cli/DepFLowCLI.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,236 +1,567 @@
|
|
|
1
|
-
# DepFlow
|
|
1
|
+
# DepFlow
|
|
2
2
|
|
|
3
|
-
DepFlow
|
|
3
|
+
DepFlow turns Git repositories and NPM packages into managed dependencies of a project: it fetches
|
|
4
|
+
them into a single `.depflow` folder, runs a build pipeline over each one, and wires the resulting
|
|
5
|
+
artifacts into the project through path aliases. Those aliases are then written into a TypeScript
|
|
6
|
+
`tsconfig` and a browser `importmap`, and the built files can be rewritten to point either at the
|
|
7
|
+
local artifacts or at their CDN counterparts.
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- Provide automatic path/importmap resolution for browser and TypeScript workflows.
|
|
8
|
-
- Support lightweight builder pipelines for extracted artifacts.
|
|
9
|
+
The configuration is a single **YAML** file, `depflow.yml` by default. JSON is supported as a
|
|
10
|
+
secondary format for tooling, and the two can be converted into each other from the CLI.
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
12
14
|
## Features
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
15
|
+
|
|
16
|
+
- Git dependencies cloned at a pinned revision and rebuilt on demand.
|
|
17
|
+
- NPM dependencies installed into the flow folder and built the same way.
|
|
18
|
+
- Ordered build pipelines per dependency: run shell commands, extract files, transform content.
|
|
19
|
+
- A resolver that maps aliases to local and CDN targets.
|
|
20
|
+
- `tsconfig` `paths` and browser `importmap` generated from those aliases.
|
|
21
|
+
- Import rewriting of the built files, with a watch mode.
|
|
22
|
+
- Three run modes (`default`, `--verbose`, `--silent`) and optional decoration.
|
|
23
|
+
- An evidence trail: the complete output of every command is written under `.logs` in every mode.
|
|
24
|
+
- Named actions runnable with `dep run`.
|
|
25
|
+
- Configuration conversion between YAML and JSON.
|
|
18
26
|
|
|
19
27
|
---
|
|
20
28
|
|
|
21
29
|
## Installation
|
|
22
30
|
|
|
23
|
-
Install globally with npm to use the CLI system-wide:
|
|
24
|
-
|
|
25
31
|
```bash
|
|
26
|
-
npm install -g
|
|
32
|
+
npm install -g depflow
|
|
27
33
|
```
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
Or add it as a project dev-dependency and invoke the `dep` binary from there.
|
|
30
36
|
|
|
31
37
|
---
|
|
32
38
|
|
|
33
39
|
## Quick Start
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
2. Run `dep install` to fetch and build all configured dependencies.
|
|
37
|
-
3. Run `dep sync` to update `tsconfig` paths and `importmap` (if configured).
|
|
41
|
+
### Requirements
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
DepFlow is an ESM-only Node.js package (`"type": "module"`) and needs an LTS Node.js with native
|
|
44
|
+
ECMAScript module support. There is no CommonJS build. `git` and `npm` are used directly, so both
|
|
45
|
+
must be on `PATH` to install the corresponding kinds of dependency.
|
|
40
46
|
|
|
41
47
|
```bash
|
|
42
|
-
#
|
|
48
|
+
# 1. Create a configuration file (default name: depflow.yml)
|
|
49
|
+
# `dep add` creates it from the defaults and registers the first dependency.
|
|
50
|
+
dep add NetFeez/vizui
|
|
51
|
+
|
|
52
|
+
# 2. Fetch, build and extract every dependency, then synchronize the aliases
|
|
43
53
|
dep install
|
|
44
|
-
# --flow <file> to use a specific config instead
|
|
45
54
|
|
|
46
|
-
#
|
|
47
|
-
dep
|
|
55
|
+
# 3. Inspect what is declared and whether its files are in place
|
|
56
|
+
dep list
|
|
48
57
|
```
|
|
49
58
|
|
|
59
|
+
`dep install` runs `dep sync` on its own after fetching, so step 2 already writes the `tsconfig`
|
|
60
|
+
paths and the `importmap` when those files are configured.
|
|
61
|
+
|
|
50
62
|
---
|
|
51
63
|
|
|
52
64
|
## Configuration
|
|
53
65
|
|
|
54
|
-
DepFlow
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
The
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
66
|
+
DepFlow reads a single configuration file. Its format is chosen by extension:
|
|
67
|
+
|
|
68
|
+
| Extension | Format | Notes |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `.yml`, `.yaml` | YAML | The default. The document is preserved across saves. |
|
|
71
|
+
| `.json` | JSON | Secondary format, read and written just as well. |
|
|
72
|
+
|
|
73
|
+
Without `--flow`, the CLI reads `depflow.yml` from the current working directory. The directory that
|
|
74
|
+
holds the configuration file is the **project root**: every relative path of the configuration is
|
|
75
|
+
resolved against it.
|
|
76
|
+
|
|
77
|
+
A YAML config is handled as a document, so key order, indentation and the comments of keys a save
|
|
78
|
+
does not touch survive a round trip. A config created from scratch is written in block style with the
|
|
79
|
+
file header and one comment per key, taken from the schema descriptions, so a generated file
|
|
80
|
+
documents itself.
|
|
81
|
+
|
|
82
|
+
The YAML dialect DepFlow reads is block style: non-empty flow collections (`[ ... ]` and `{ ... }`)
|
|
83
|
+
are not supported and are reported as an error when the file is loaded. Write lists and maps as
|
|
84
|
+
indented blocks; the empty `{}` and `[]` the generated file uses are fine. Use JSON if a
|
|
85
|
+
flow-style document is a hard requirement, or let `dep yaml-to-json` produce one.
|
|
86
|
+
|
|
87
|
+
Whenever the config is saved, DepFlow also refreshes the editor JSON Schema at `.depflow/schema.json`
|
|
88
|
+
and points `$schema` at it, which gives validation and autocompletion in editors that understand JSON
|
|
89
|
+
Schema.
|
|
90
|
+
|
|
91
|
+
### Generated configuration
|
|
92
|
+
|
|
93
|
+
A freshly generated `depflow.yml` looks like this:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
# Depflow Configuration File
|
|
97
|
+
# You can use the Red Hat extension for JSON schema validation in VSCode: "$schema: .depflow/schema.json"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Path to the JSON Schema describing the configuration. Used by editors and tools to provide validation, autocompletion and other features.
|
|
101
|
+
$schema: .depflow/schema.json
|
|
102
|
+
# Output directory for built files. Can be relative or absolute. Defaults to "dist".
|
|
103
|
+
outDir: dist
|
|
104
|
+
# Path to the tsconfig.json file. Can be relative or absolute. Defaults to "tsconfig.json".
|
|
105
|
+
tsconfig: null
|
|
106
|
+
# Path to the importmap.json file. Can be relative or absolute. Defaults to "importmap.json".
|
|
107
|
+
importmap: null
|
|
108
|
+
# Named build actions. Each action runs a pipeline of run, extract and transform steps.
|
|
109
|
+
actions: {}
|
|
110
|
+
# Mapping of dependency names to their resolution targets (local file or CDN). Paths are resolved relative to this folder.
|
|
111
|
+
resolver: {}
|
|
112
|
+
# Git dependencies to clone and build, each an object with a name and a repo.
|
|
113
|
+
dependencies: []
|
|
114
|
+
# NPM dependencies to install and build, each an object with a name and a version.
|
|
115
|
+
npmDependencies: []
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Top-level keys
|
|
119
|
+
|
|
120
|
+
| Key | Type | Default | Meaning |
|
|
121
|
+
|---|---|---|---|
|
|
122
|
+
| `$schema` | string | `.depflow/schema.json` | Path to the JSON Schema used by editors. Refreshed on every save. |
|
|
123
|
+
| `outDir` | string | `dist` | Output root scanned by `rewrite-paths` and its watcher. Relative or absolute. |
|
|
124
|
+
| `tsconfig` | string \| null | `null` | Path to a `tsconfig.json` whose `compilerOptions.paths` `sync` updates. When `null`, synchronization of the tsconfig is skipped. |
|
|
125
|
+
| `importmap` | string \| null | `null` | Path to an `importmap.json` that `sync` writes. When `null`, synchronization of the import map is skipped. |
|
|
126
|
+
| `actions` | object | `{}` | Named build pipelines runnable with `dep run <action>`. |
|
|
127
|
+
| `resolver` | object | `{}` | Aliases shared by the whole project, merged with each dependency's own `resolver`. |
|
|
128
|
+
| `dependencies` | array | `[]` | Git dependencies. |
|
|
129
|
+
| `npmDependencies` | array | `[]` | NPM dependencies. |
|
|
130
|
+
|
|
131
|
+
Streaming collections default to a fresh empty value on every load, so a processed document never
|
|
132
|
+
shares state with the schema.
|
|
133
|
+
|
|
134
|
+
### Dependencies
|
|
135
|
+
|
|
136
|
+
A **git dependency** is cloned into `.depflow/<user>/<repo>` and rebuilt from its `tag` on every install:
|
|
137
|
+
|
|
138
|
+
```yaml
|
|
139
|
+
dependencies:
|
|
140
|
+
- name: NetFeez/vizui
|
|
141
|
+
repo: https://github.com/NetFeez/vizui.git
|
|
142
|
+
tag: main
|
|
143
|
+
builder: []
|
|
144
|
+
resolver: {}
|
|
119
145
|
```
|
|
120
146
|
|
|
147
|
+
| Key | Type | Default | Meaning |
|
|
148
|
+
|---|---|---|---|
|
|
149
|
+
| `name` | string | — (required) | Identity of the dependency. See [Dependency identity](#dependency-identity). |
|
|
150
|
+
| `repo` | string | — (required) | Any value `git clone` accepts, always ending in `.git`. |
|
|
151
|
+
| `tag` | string | `main` | Tag, branch or commit the checkout is left on. |
|
|
152
|
+
| `builder` | array | `[]` | Build pipeline applied after cloning. |
|
|
153
|
+
| `resolver` | object | `{}` | Aliases contributed by this dependency. |
|
|
154
|
+
|
|
155
|
+
An **NPM dependency** is installed into `.depflow/node_modules/<name>` and built the same way:
|
|
156
|
+
|
|
157
|
+
```yaml
|
|
158
|
+
npmDependencies:
|
|
159
|
+
- name: "@netfeez/common"
|
|
160
|
+
version: latest
|
|
161
|
+
builder: []
|
|
162
|
+
resolver: {}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
| Key | Type | Default | Meaning |
|
|
166
|
+
|---|---|---|---|
|
|
167
|
+
| `name` | string | — (required) | Package name, optionally scoped. |
|
|
168
|
+
| `version` | string | — (required) | Version or semver range to install. |
|
|
169
|
+
| `builder` | array | `[]` | Build pipeline applied after installing. |
|
|
170
|
+
| `resolver` | object | `{}` | Aliases contributed by this dependency. |
|
|
171
|
+
|
|
172
|
+
Git dependencies are installed before NPM dependencies.
|
|
173
|
+
|
|
121
174
|
### Dependency identity
|
|
122
175
|
|
|
123
|
-
The `name` of a dependency is
|
|
124
|
-
|
|
125
|
-
|
|
176
|
+
The `name` of a dependency is an identity, not an arbitrary path:
|
|
177
|
+
|
|
178
|
+
- A git name is a `<user>/<repo>` pair or a **single path segment** (letters, digits, `.`, `_`, `-`),
|
|
179
|
+
and it is also the path of its checkout folder inside `.depflow`. It may not lead with
|
|
180
|
+
`schema.json` or `node_modules`, the two names the flow folder reserves for itself, and it is at
|
|
181
|
+
most one `/`.
|
|
182
|
+
- An NPM name is a package name, optionally scoped (`@scope/name`).
|
|
126
183
|
|
|
127
|
-
The
|
|
128
|
-
|
|
129
|
-
|
|
184
|
+
The name of a git dependency can be derived from its repository only when that repository is a GitHub
|
|
185
|
+
one, where it becomes `<user>/<repo>` (for example `NetFeez/vizui`). For any other repository the
|
|
186
|
+
name has to be given explicitly to `dep add`.
|
|
130
187
|
|
|
131
|
-
|
|
188
|
+
`dep add` accepts a GitHub repository written in any of its usual forms, canonicalizes it to the
|
|
189
|
+
repository git clones from, always ending in `.git`, and derives the name from it when no name is
|
|
190
|
+
given:
|
|
132
191
|
|
|
133
|
-
|
|
192
|
+
```bash
|
|
193
|
+
dep add netfeez/vizui # https://github.com/netfeez/vizui.git, name netfeez/vizui
|
|
194
|
+
dep add https://github.com/netfeez/vizui # https://github.com/netfeez/vizui.git, name netfeez/vizui
|
|
195
|
+
dep add https://github.com/netfeez/vizui.git # https://github.com/netfeez/vizui.git, name netfeez/vizui
|
|
196
|
+
dep add git@github.com:/netfeez/vizui # git@github.com:netfeez/vizui.git, name netfeez/vizui
|
|
197
|
+
```
|
|
134
198
|
|
|
135
|
-
|
|
136
|
-
`maxTimeMs` (deadline in milliseconds, `-1` for no deadline, defaults to `60000`) and `allowFails`
|
|
137
|
-
(whether a failed command is tolerated, defaults to `false`).
|
|
138
|
-
- `extract`: a mapping of source globs to extraction entries, or a destination folder as a shorthand for
|
|
139
|
-
`**/*` → that folder. The globs are matched against the folder the pipeline works in (the dependency
|
|
140
|
-
checkout, or the project itself for a `dep run` action) and an entry is a destination (`to`) plus,
|
|
141
|
-
optionally, a `map` transformation applied to the destination path and a `transform` transformation
|
|
142
|
-
applied to the content of the files. A relative `to` is resolved against the project root and an
|
|
143
|
-
absolute one is used as it stands, so a pipeline reads from the dependency and deposits into the
|
|
144
|
-
project. `map` runs against the *relative* path of the matched file, inside the destination.
|
|
145
|
-
- `transform`: a `glob` plus a `search`/`replace` transformation applied in place to the matched files.
|
|
199
|
+
### Build pipelines
|
|
146
200
|
|
|
147
|
-
|
|
148
|
-
|
|
201
|
+
The `builder` of a dependency, and each entry of a named `action`, is an ordered list of steps. Every
|
|
202
|
+
step is an object carrying exactly one of `run`, `extract` or `transform`. A step that fails without
|
|
203
|
+
tolerating its failures stops the pipeline, and the steps after it are reported as steps that never
|
|
204
|
+
ran.
|
|
149
205
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
206
|
+
**`run`** executes one shell command, or a list of them, in the pipeline's working directory, which is
|
|
207
|
+
the dependency checkout for an install and the project root for a `dep run` action:
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
builder:
|
|
211
|
+
- run: npm run build
|
|
212
|
+
- run:
|
|
213
|
+
- npm ci
|
|
214
|
+
- npm run compile
|
|
215
|
+
maxTimeMs: 120000
|
|
216
|
+
allowFails: false
|
|
217
|
+
```
|
|
154
218
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
219
|
+
| Key | Type | Default | Meaning |
|
|
220
|
+
|---|---|---|---|
|
|
221
|
+
| `run` | string \| string[] | — (required) | Command or commands to execute, in order. |
|
|
222
|
+
| `maxTimeMs` | number | `60000` | Deadline for the whole step in milliseconds. `-1` disables the limit. |
|
|
223
|
+
| `allowFails` | boolean | `false` | Whether a failed command is tolerated, so the step completes anyway. |
|
|
224
|
+
|
|
225
|
+
**`extract`** copies files matched by source globs from the working directory into a destination:
|
|
226
|
+
|
|
227
|
+
```yaml
|
|
228
|
+
builder:
|
|
229
|
+
- extract:
|
|
230
|
+
"build/**/*.js":
|
|
231
|
+
to: dist/vizui
|
|
232
|
+
map: "^build/"
|
|
233
|
+
"build/**/*.d.ts":
|
|
234
|
+
to: dist/vizui
|
|
235
|
+
map: "^build/"
|
|
158
236
|
```
|
|
159
237
|
|
|
160
|
-
|
|
238
|
+
The `extract` value is either a mapping of glob → entry, or a single string used as a shorthand for
|
|
239
|
+
extracting every file (`**/*`) into that folder. Each entry is:
|
|
240
|
+
|
|
241
|
+
| Key | Type | Meaning |
|
|
242
|
+
|---|---|---|
|
|
243
|
+
| `to` | string — required | Destination folder. A relative path is resolved against the project root; an absolute one is used as it stands. |
|
|
244
|
+
| `map` | transform | Transformation applied to the destination path of each file, relative to the working directory. |
|
|
245
|
+
| `transform` | transform | Transformation applied to the content of each file. |
|
|
246
|
+
|
|
247
|
+
**`transform`** applies a search/replace transformation in place to every file matched by a glob:
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
builder:
|
|
251
|
+
- transform:
|
|
252
|
+
glob: "build/**/*.js"
|
|
253
|
+
search: "process\\.env\\.NODE_ENV"
|
|
254
|
+
replace: "\"production\""
|
|
255
|
+
flags: g
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Transformations
|
|
259
|
+
|
|
260
|
+
`map`, the `transform` of an extraction entry and the in-place `transform` step all accept one of two
|
|
261
|
+
forms, and they do not mean the same thing:
|
|
262
|
+
|
|
263
|
+
- a **string** is a pattern whose matches are **removed**. `"^build/"` strips that prefix from every
|
|
264
|
+
matched path.
|
|
265
|
+
- an **object** is the only form that **substitutes**: `search` is the pattern, `replace` what takes
|
|
266
|
+
its place, and `flags` (default `g`) is applied to the regular expression. An object with an empty
|
|
267
|
+
or absent `replace` removes the matches, exactly as the string form does.
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
map: "^build/"
|
|
271
|
+
transform:
|
|
272
|
+
search: "^\\.\\/(.*)$"
|
|
273
|
+
replace: "$1"
|
|
274
|
+
flags: g
|
|
275
|
+
```
|
|
161
276
|
|
|
162
277
|
### Resolver entries
|
|
163
278
|
|
|
164
|
-
The `resolver` of
|
|
165
|
-
target. The target is either a string path or an object
|
|
279
|
+
The `resolver` of the project and the `resolver` of a dependency are mappings of an alias to its
|
|
280
|
+
target. The target is either a plain string path or an object:
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
resolver:
|
|
284
|
+
"@utils": src/utils
|
|
285
|
+
"@app/*": src/app
|
|
286
|
+
"@vizui":
|
|
287
|
+
local: dist/vizui/index.js
|
|
288
|
+
type: /abs/path/types/vizui.d.ts
|
|
289
|
+
cdn: https://cdn.example.com/vizui/index.js
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
| Key | Type | Meaning |
|
|
293
|
+
|---|---|---|
|
|
294
|
+
| `local` | string — required | The path the alias resolves to, resolved against the project root. `sync` turns it into the `tsconfig` `paths` entry and the `importmap` entry, and `rewrite-paths` rewrites imports that point at it. With `--cdn`, an alias that also declares a `cdn` target uses it instead. |
|
|
295
|
+
| `type` | string | The target holding the type declarations. It becomes the **first** entry of the generated `paths` array, so the editor finds the `.d.ts`. Unlike `local`, it is not resolved against the project root, so it has to be an absolute path. |
|
|
296
|
+
| `cdn` | string | The URL that replaces `local` when `--cdn` is given. |
|
|
297
|
+
|
|
298
|
+
An alias ending in `/` or `/*` is a **wildcard** alias: `@app/*` also covers `@app/Button`. Dependency
|
|
299
|
+
resolvers are compiled before the project resolver, so a project entry with the same alias wins.
|
|
300
|
+
|
|
301
|
+
### Named actions
|
|
302
|
+
|
|
303
|
+
`actions` maps a name to a list of `run`, `extract` and `transform` steps, run in the project root by
|
|
304
|
+
`dep run <name>`:
|
|
305
|
+
|
|
306
|
+
```yaml
|
|
307
|
+
actions:
|
|
308
|
+
build:
|
|
309
|
+
- run: npm run build
|
|
310
|
+
- extract:
|
|
311
|
+
"dist/**/*.js":
|
|
312
|
+
to: public/lib
|
|
313
|
+
map: "^dist/"
|
|
314
|
+
lint:
|
|
315
|
+
- run: npm run lint
|
|
316
|
+
- run: npm run typecheck
|
|
317
|
+
```
|
|
166
318
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
319
|
+
### Full example
|
|
320
|
+
|
|
321
|
+
```yaml
|
|
322
|
+
$schema: .depflow/schema.json
|
|
323
|
+
outDir: dist
|
|
324
|
+
tsconfig: tsconfig.json
|
|
325
|
+
importmap: public/importmap.json
|
|
326
|
+
|
|
327
|
+
resolver:
|
|
328
|
+
"@app/*": src/app
|
|
329
|
+
|
|
330
|
+
actions:
|
|
331
|
+
build:
|
|
332
|
+
- run: npm run build
|
|
333
|
+
|
|
334
|
+
dependencies:
|
|
335
|
+
- name: NetFeez/vizui
|
|
336
|
+
repo: https://github.com/NetFeez/vizui.git
|
|
337
|
+
tag: v1.2.0
|
|
338
|
+
builder:
|
|
339
|
+
- run:
|
|
340
|
+
- npm ci
|
|
341
|
+
- npm run compile
|
|
342
|
+
- extract:
|
|
343
|
+
"build/**/*.js":
|
|
344
|
+
to: public/lib/vizui
|
|
345
|
+
map: "^build/"
|
|
346
|
+
"build/**/*.d.ts":
|
|
347
|
+
to: public/lib/vizui
|
|
348
|
+
map: "^build/"
|
|
349
|
+
resolver:
|
|
350
|
+
"@vizui": public/lib/vizui/vizui.js
|
|
351
|
+
"@vizui/*": public/lib/vizui
|
|
352
|
+
|
|
353
|
+
npmDependencies:
|
|
354
|
+
- name: "@netfeez/common"
|
|
355
|
+
version: latest
|
|
356
|
+
builder:
|
|
357
|
+
- extract:
|
|
358
|
+
"build/**/*.js":
|
|
359
|
+
to: public/lib/common
|
|
360
|
+
map: "^build/"
|
|
361
|
+
resolver:
|
|
362
|
+
"@netfeez/common": public/lib/common/index.js
|
|
363
|
+
"@netfeez/common/*": public/lib/common
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The same configuration can be kept as JSON when the file is named `.json`. The command reads the
|
|
367
|
+
config named by `--flow` (default `depflow.yml`) and writes a sibling file; its optional positional
|
|
368
|
+
argument is the **output** path, not the input:
|
|
174
369
|
|
|
175
|
-
|
|
370
|
+
```bash
|
|
371
|
+
dep yaml-to-json # reads depflow.yml, writes depflow.json
|
|
372
|
+
dep json-to-yaml --flow depflow.json # reads depflow.json, writes depflow.yaml
|
|
373
|
+
dep yaml-to-json build/depflow.json # reads depflow.yml, writes build/depflow.json
|
|
374
|
+
```
|
|
176
375
|
|
|
177
376
|
---
|
|
178
377
|
|
|
179
378
|
## CLI Reference
|
|
180
379
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- `sync`: Generate/update `tsconfig` paths and browser `importmap` according to `resolver` entries.
|
|
185
|
-
- `list`: Show configured dependencies and whether each one is installed.
|
|
380
|
+
```
|
|
381
|
+
dep <command> [arguments] [flags]
|
|
382
|
+
```
|
|
186
383
|
|
|
187
|
-
|
|
384
|
+
The **first token is always the command name**; global flags are parsed from the tokens that follow
|
|
385
|
+
it. `dep --flow x install` is read as the command `--flow`, so flags belong after the command:
|
|
386
|
+
`dep install --flow x`.
|
|
188
387
|
|
|
189
388
|
### Commands
|
|
190
389
|
|
|
191
|
-
The CLI exposes the following commands (all commands accept the global `--flow <file>` flag to specify a custom configuration file):
|
|
192
|
-
|
|
193
390
|
| Command | Usage | Description |
|
|
194
391
|
|---|---|---|
|
|
195
|
-
| `add` | `dep add <
|
|
196
|
-
| `remove` | `dep remove <name\|repo_url
|
|
197
|
-
| `install` | `dep install [
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
392
|
+
| `add` | `dep add <repo> [name] [--tag <ref>]` or `dep add --npm <name>[@<version>]` | Add a dependency to the configuration, creating the file from the defaults if it does not exist. A git repository may be given as `user/repo`, as an HTTP(S) URL or as an ssh address, with or without the `.git` suffix; it is canonicalized to the URL git clones from, and its name is derived from it when omitted, which only a GitHub repository allows. `--tag` sets the tag, branch or commit it is checked out at (default `main`). With `--npm` the argument is an npm package `<name>[@<version>]`, defaulting to `latest`, registered under `npmDependencies`. A name already taken is refused. |
|
|
393
|
+
| `remove` | `dep remove <name\|repo_url>` | Remove a dependency by name (git or npm) or by git repository URL, and uninstall its local files. An identifier no dependency declares is an error. |
|
|
394
|
+
| `install` | `dep install [name...]` | Fetch, build and extract every dependency, or only the named ones. A checkout already in place is updated to its `tag` instead of cloned again. Runs `sync` afterwards. |
|
|
395
|
+
| `run` | `dep run <action>` | Run a named action from `actions`, in the project root. |
|
|
396
|
+
| `list` | `dep list` | List the declared dependencies, marking each one `installed` or `missing`. |
|
|
397
|
+
| `rewrite-paths` | `dep rewrite-paths [--watch] [--cdn]` | Rewrite import specifiers in the built files of `outDir` according to the resolver. A file that cannot be rewritten fails the command. |
|
|
398
|
+
| `sync` | `dep sync [--cdn]` | Write the resolver aliases into the configured `tsconfig` and `importmap`. |
|
|
399
|
+
| `resolver` | `dep resolver add <alias> <local> [--type <t>] [--cdn-url <url>] [--force] \| remove <alias> \| list \| clear` | Edit the resolver aliases. Without `--dep` the project resolver is edited; with it, the named dependency's own resolver. `add` refuses an alias already taken unless `--force` is given. |
|
|
400
|
+
| `builder` | `dep builder add <run\|extract\|transform> ... \| remove <index> \| move <from> <to> \| list \| clear` | Edit the build pipeline of the dependency named by `--dep` or of the action named by `--action`. `add run` takes one or more commands (`--max-time`, `--allow-fails`); `add extract` takes a glob (`--to`, `--map`); `add transform` takes a glob (`--search`, `--replace`, `--flags`). `--index` chooses where the step is inserted. |
|
|
401
|
+
| `action` | `dep action create <name> \| remove <name> \| list` | Create, remove or list the named actions of the configuration. A new action starts empty and is filled through `builder --action`. |
|
|
402
|
+
| `config` | `dep config get [key] \| set <key> <value> \| unset <key>` | Read and edit the top-level settings `outDir`, `tsconfig` and `importmap`. `set` accepts `null` for the nullable ones; `outDir` cannot be unset. |
|
|
403
|
+
| `json-to-yaml` | `dep json-to-yaml [output.yaml]` | Convert the config to YAML. The output name is derived from the input name when omitted. |
|
|
404
|
+
| `yaml-to-json` | `dep yaml-to-json [output.json]` | Convert the config to JSON. The output name is derived from the input name when omitted. |
|
|
405
|
+
|
|
406
|
+
### Console commands
|
|
407
|
+
|
|
408
|
+
The CLI is built on a small console interface that also carries two commands:
|
|
409
|
+
|
|
410
|
+
| Command | Description |
|
|
411
|
+
|---|---|
|
|
412
|
+
| `dep help` | Print the global flags and every command, with its usage, description and arguments. The help is written by the terminal and is left untouched by `--silent` and `--decorate=false`. |
|
|
413
|
+
| `dep exit` | Leave the process. |
|
|
414
|
+
|
|
415
|
+
This build does not drive that interface interactively: the first token of an invocation is always
|
|
416
|
+
taken as the command name, so an empty invocation is reported as an unknown command and the help is
|
|
417
|
+
printed rather than a prompt being opened.
|
|
201
418
|
|
|
202
419
|
### Flags
|
|
203
420
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
421
|
+
These are the global flags: every command accepts all of them.
|
|
422
|
+
|
|
423
|
+
| Flag | Aliases | Default | Description |
|
|
424
|
+
|---|---|---|---|
|
|
425
|
+
| `--flow <file>` | `-p`, `-f` | `depflow.yml` | Configuration file the command operates on. |
|
|
426
|
+
| `--cdn` | — | `false` | Resolve to CDN targets instead of local ones (for `sync` and `rewrite-paths`). |
|
|
427
|
+
| `--watch` | `-w` | `false` | Keep watching the built files and rewriting their paths on every change (`rewrite-paths`). |
|
|
428
|
+
| `--verbose` | `-v` | `false` | Stream the output of every command as it runs, attributed to the command that wrote it. |
|
|
429
|
+
| `--silent` | — | `false` | Say only what failed, one line per failed command. |
|
|
430
|
+
| `--decorate` | — | `true` | Draw boxes, indentation, timestamps, levels and names. Use `--decorate=false` to leave the content alone. |
|
|
431
|
+
|
|
432
|
+
Beside the global ones, an editing command declares the flags it owns. A flag is only accepted by the
|
|
433
|
+
command that declares it: `dep install --to x` is answered with `Unknown flag: --to`, and the help
|
|
434
|
+
lists the owned flags under their command.
|
|
435
|
+
|
|
436
|
+
| Command | Flag | Aliases | Default | Description |
|
|
437
|
+
|---|---|---|---|---|
|
|
438
|
+
| `add` | `--npm` | — | `false` | Add an npm dependency instead of a git one. |
|
|
439
|
+
| `add` | `--tag <ref>` | — | `main` | Tag, branch or commit the added git dependency is checked out at. |
|
|
440
|
+
| `resolver` | `--dep <name>` | — | — | Dependency whose resolver is edited. Omitted, the project resolver is edited. |
|
|
441
|
+
| `resolver` | `--type <type>` | — | — | Type identifier of a resolver target, set alongside its local path. |
|
|
442
|
+
| `resolver` | `--cdnUrl <url>` | `--cdn-url` | — | CDN URL of a resolver target, set alongside its local path. |
|
|
443
|
+
| `resolver` | `--force` | — | `false` | Overwrite an existing resolver alias instead of failing. |
|
|
444
|
+
| `builder` | `--dep <name>` | — | — | Dependency whose build pipeline is edited. |
|
|
445
|
+
| `builder` | `--action <name>` | — | — | Action whose build pipeline is edited. |
|
|
446
|
+
| `builder` | `--to <dir>` | — | — | Destination folder of an extract build step. |
|
|
447
|
+
| `builder` | `--map <pattern>` | — | — | Pattern applied to the destination path of an extract build step. |
|
|
448
|
+
| `builder` | `--search <regex>` | — | — | Regular expression a transform build step searches for. |
|
|
449
|
+
| `builder` | `--replace <text>` | — | — | Replacement string of a transform build step. |
|
|
450
|
+
| `builder` | `--flags <flags>` | — | `g` | Flags of the regular expression of a transform build step. |
|
|
451
|
+
| `builder` | `--maxTime <ms>` | `--max-time` | `60000` | Maximum execution time of a run build step; `-1` disables the limit. |
|
|
452
|
+
| `builder` | `--allowFails` | `--allow-fails` | `false` | Whether the commands of a run build step may fail. |
|
|
453
|
+
| `builder` | `--index <n>` | — | end | Position at which a build step is inserted. |
|
|
454
|
+
|
|
455
|
+
Flag parsing rules:
|
|
456
|
+
|
|
457
|
+
- A flag is the whole token; short clusters are not expanded (`-abc` is the single flag `-abc`).
|
|
458
|
+
- Names are matched with or without their dash prefix, so `-f` and `--flow` reach the same flag.
|
|
459
|
+
- A value flag takes the next token as its value when that token is not a flag, or an inline value as
|
|
460
|
+
`--flag=value`. A boolean flag never consumes the next token and only accepts `=true` or `=false`,
|
|
461
|
+
so the undecorated form is `--decorate=false`.
|
|
462
|
+
- The last occurrence of a flag wins, `--` ends the flags and turns every remaining token into a
|
|
463
|
+
positional argument, and an undeclared flag is an error.
|
|
207
464
|
|
|
208
|
-
|
|
465
|
+
```bash
|
|
466
|
+
dep install --flow .df.yml
|
|
467
|
+
dep sync --flow .df.yml --cdn
|
|
468
|
+
dep rewrite-paths --flow .df.yml --watch
|
|
469
|
+
dep run build --decorate=false
|
|
470
|
+
```
|
|
209
471
|
|
|
210
|
-
|
|
472
|
+
---
|
|
211
473
|
|
|
212
|
-
|
|
213
|
-
# install using custom flow file
|
|
214
|
-
dep install --flow .df.json
|
|
474
|
+
## Run Modes and the Evidence Trail
|
|
215
475
|
|
|
216
|
-
|
|
217
|
-
dep sync --flow .df.json --cdn
|
|
476
|
+
Every command a run executes writes its **complete** output to
|
|
218
477
|
|
|
219
|
-
|
|
220
|
-
|
|
478
|
+
```
|
|
479
|
+
.logs/{YYYY}.{MM}.{DD}/[name] {HH}.{mm}.{ss}.{ms}.vlog
|
|
221
480
|
```
|
|
222
481
|
|
|
482
|
+
under the working directory, whatever the mode. The file keeps the format tokens of the logger, so it
|
|
483
|
+
is a complete transcript of the run. What a mode changes is how much of that output reaches the
|
|
484
|
+
screen:
|
|
485
|
+
|
|
486
|
+
| Mode | Flags | What it shows |
|
|
487
|
+
|---|---|---|
|
|
488
|
+
| Default | *(none)* | One result line per command, and the complete output of a command that failed, under its diagnostic. |
|
|
489
|
+
| Verbose | `--verbose` / `-v` | Every line of every command as it comes, each attributed to the command that wrote it. The buffer is not repeated. |
|
|
490
|
+
| Silent | `--silent` | One line per failed command, and nothing else. |
|
|
491
|
+
|
|
492
|
+
`--silent` wins over `--verbose` when both are given. `--decorate=false` combines with any mode to
|
|
493
|
+
drop the boxes, indentation, timestamps, levels and names, keeping the color of the markers and the
|
|
494
|
+
diagnostics, which carry information.
|
|
495
|
+
|
|
496
|
+
Commands that are not part of a pipeline (the git and npm acquisition of a dependency) are reported
|
|
497
|
+
as `C<M>`; the commands inside a pipeline with more than one `run` step are qualified as
|
|
498
|
+
`S<N> · C<M>`, so a command identity is never ambiguous.
|
|
499
|
+
|
|
223
500
|
---
|
|
224
501
|
|
|
225
|
-
##
|
|
502
|
+
## How `sync` and `rewrite-paths` Work
|
|
503
|
+
|
|
504
|
+
`sync` compiles the resolver into aliases and writes them to the configured files:
|
|
505
|
+
|
|
506
|
+
- the **tsconfig** `compilerOptions.paths` receives one entry per alias, always pointing at the local
|
|
507
|
+
target. A wildcard alias becomes `<alias>/*`. When a target declares a `type`, the type path is the
|
|
508
|
+
first element of the array and the local path the second.
|
|
509
|
+
- the **importmap** `imports` receives one entry per alias. A wildcard alias's key keeps a trailing
|
|
510
|
+
`/`. Local targets are written relative to the directory of the importmap file. With `--cdn`, an
|
|
511
|
+
alias that declares a `cdn` target uses it; the others keep their local path. Existing `scopes` are
|
|
512
|
+
preserved.
|
|
513
|
+
|
|
514
|
+
`rewrite-paths` scans `outDir` for files ending in `.js`, `.ts`, `.jsx`, `.tsx`, `.cjs` or `.mjs`
|
|
515
|
+
and rewrites every `from '...'` specifier whose module path matches an alias:
|
|
226
516
|
|
|
227
|
-
|
|
228
|
-
|
|
517
|
+
- in **local** mode the specifier becomes a path relative to the file, written with `/` separators.
|
|
518
|
+
- in **cdn** mode an alias that declares a `cdn` target resolves to that URL; the rest keep their
|
|
519
|
+
local relative path.
|
|
520
|
+
|
|
521
|
+
Only `from '...'` specifiers are rewritten; a bare side-effect import such as `import './x'` is not
|
|
522
|
+
touched. `--watch` rewrites once and then keeps rewriting as files change.
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## Project Layout
|
|
527
|
+
|
|
528
|
+
```text
|
|
529
|
+
<project root>/
|
|
530
|
+
├── depflow.yml # the configuration (any name, passed with --flow)
|
|
531
|
+
├── .depflow/ # the flow folder, owned by DepFlow
|
|
532
|
+
│ ├── <user>/<repo>/ # one checkout per git dependency
|
|
533
|
+
│ ├── node_modules/ # npm dependencies, installed here and not in the project's
|
|
534
|
+
│ └── schema.json # the editor JSON Schema, refreshed on every config save
|
|
535
|
+
├── <outDir>/ # the built files rewrite-paths scans (default: dist)
|
|
536
|
+
└── .logs/ # the evidence trail, under the working directory
|
|
537
|
+
└── {YYYY}.{MM}.{DD}/
|
|
538
|
+
└── [name] {HH}.{mm}.{ss}.{ms}.vlog
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
The project root is the directory of the configuration file. The flow folder is reserved for
|
|
542
|
+
DepFlow: a dependency name may not lead with `schema.json` or `node_modules`, may not start with a
|
|
543
|
+
dot, and is at most one `/` (a `<user>/<repo>` pair), so no dependency folder can escape `.depflow`.
|
|
544
|
+
|
|
545
|
+
---
|
|
546
|
+
|
|
547
|
+
## Development
|
|
548
|
+
|
|
549
|
+
The project is ESM-only TypeScript, compiled with `tsc` and exercised by a bundled test runner; no
|
|
550
|
+
test framework is installed.
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
npm install # install the dependencies
|
|
554
|
+
npm run build # clean and compile src/ into dist/
|
|
555
|
+
npm run dev # recompile on change (tsc --watch)
|
|
556
|
+
npm test # compile the tests and run the whole suite
|
|
557
|
+
npm run clean # remove dist/, dist-test/ and the .tsbuildinfo files
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
The suite is offline: the git and npm fixtures are local, so the tests need no network. The test
|
|
561
|
+
entry point is `dist-test/tests/index.js`, and `npm test` exits non-zero on any failure.
|
|
562
|
+
|
|
563
|
+
---
|
|
229
564
|
|
|
230
|
-
|
|
231
|
-
- `allowFails: true` turns a failed command into information: the step completes and the build continues;
|
|
232
|
-
- `maxTimeMs` is a deadline for the whole step, not per command, and a deadline that is reached fails the
|
|
233
|
-
step even when `allowFails` is set: the work never finished, so the result is not the one that was asked for.
|
|
565
|
+
## License
|
|
234
566
|
|
|
235
|
-
|
|
236
|
-
do fails, and the failure travels up to whoever asked for the build.
|
|
567
|
+
Apache-2.0. See [LICENCE](LICENCE).
|