d3ployer 0.0.10 → 0.0.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 +46 -30
- package/dist/bin.js +0 -0
- package/dist/cli.js +9 -4
- package/dist/config.d.ts +0 -1
- package/dist/config.js +27 -35
- package/dist/def.d.ts +26 -20
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/renderer.d.ts +23 -0
- package/dist/renderer.js +153 -0
- package/dist/runner.d.ts +8 -4
- package/dist/runner.js +36 -28
- package/dist/tasks/clearTarget.d.ts +2 -0
- package/dist/tasks/clearTarget.js +15 -0
- package/dist/tasks/download.d.ts +3 -0
- package/dist/tasks/download.js +27 -0
- package/dist/tasks/index.d.ts +6 -0
- package/dist/tasks/index.js +76 -0
- package/dist/tasks/installPackages.d.ts +3 -0
- package/dist/tasks/installPackages.js +38 -0
- package/dist/tasks/printDeployment.d.ts +2 -0
- package/dist/tasks/printDeployment.js +8 -0
- package/dist/tasks/printLogs.d.ts +5 -0
- package/dist/tasks/printLogs.js +69 -0
- package/dist/tasks/setupDocker.d.ts +4 -0
- package/dist/tasks/setupDocker.js +33 -0
- package/dist/tasks/setupPm2.d.ts +3 -0
- package/dist/tasks/setupPm2.js +14 -0
- package/dist/tasks/symlinks.d.ts +3 -0
- package/dist/tasks/symlinks.js +18 -0
- package/dist/tasks/upload.d.ts +7 -0
- package/dist/tasks/upload.js +54 -0
- package/package.json +4 -4
- package/dist/defaultTasks.d.ts +0 -9
- package/dist/defaultTasks.js +0 -303
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ export default defineConfig({
|
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
scenarios: {
|
|
40
|
-
deploy: ['upload', 'symlinks', '
|
|
40
|
+
deploy: ['upload', 'symlinks', 'install:packages', 'restart'],
|
|
41
41
|
},
|
|
42
42
|
});
|
|
43
43
|
```
|
|
@@ -45,10 +45,11 @@ export default defineConfig({
|
|
|
45
45
|
Then deploy:
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
dpl deploy
|
|
49
|
-
dpl deploy prod
|
|
50
|
-
dpl upload
|
|
51
|
-
dpl
|
|
48
|
+
dpl deploy # run "deploy" scenario on all servers
|
|
49
|
+
dpl deploy prod # run on specific server(s)
|
|
50
|
+
dpl upload # run a single task
|
|
51
|
+
dpl deploy --skip install:packages # skip specific tasks (comma-separated)
|
|
52
|
+
dpl list # list available scenarios, tasks, and servers
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
## CLI
|
|
@@ -59,6 +60,7 @@ dpl list List scenarios, tasks, and servers
|
|
|
59
60
|
|
|
60
61
|
Options:
|
|
61
62
|
-c, --config <path> Path to deployer.config.ts
|
|
63
|
+
--skip <tasks> Comma-separated list of tasks to skip
|
|
62
64
|
```
|
|
63
65
|
|
|
64
66
|
If `<name>` matches a scenario, it runs all tasks in that scenario sequentially. Otherwise it runs the matching task directly.
|
|
@@ -119,20 +121,33 @@ packageManager: {
|
|
|
119
121
|
|
|
120
122
|
### `pm2`
|
|
121
123
|
|
|
122
|
-
Set to `false` to disable
|
|
124
|
+
Configure PM2 integration. Set to `false` to disable entirely. The `setup:pm2` task auto-detects `pm2.config.*` files. Post-deploy log streaming is configured via `pm2.logs`.
|
|
123
125
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
```ts
|
|
127
|
+
pm2: {
|
|
128
|
+
logs: {
|
|
129
|
+
time: 5, // seconds to stream (default: 3)
|
|
130
|
+
lines: 50, // log lines to show (default: 25)
|
|
131
|
+
},
|
|
132
|
+
// logs: false — disable log streaming only
|
|
133
|
+
}
|
|
134
|
+
// pm2: false — disable PM2 entirely
|
|
135
|
+
```
|
|
127
136
|
|
|
128
|
-
### `
|
|
137
|
+
### `dockerCompose`
|
|
129
138
|
|
|
130
|
-
Configure
|
|
139
|
+
Configure Docker Compose integration. Set to `false` to disable entirely. The `setup:docker` task auto-detects compose files. Specify custom compose files via `configFiles`.
|
|
131
140
|
|
|
132
141
|
```ts
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
dockerCompose: {
|
|
143
|
+
configFiles: ['docker-compose.prod.yml'], // optional, defaults to auto-detect
|
|
144
|
+
logs: {
|
|
145
|
+
time: 5, // seconds to stream (default: 3)
|
|
146
|
+
lines: 50, // log lines to show (default: 25)
|
|
147
|
+
},
|
|
148
|
+
// logs: false — disable log streaming only
|
|
135
149
|
}
|
|
150
|
+
// dockerCompose: false — disable Docker Compose entirely
|
|
136
151
|
```
|
|
137
152
|
|
|
138
153
|
### `tasks`
|
|
@@ -141,7 +156,7 @@ Custom task functions receive a `TaskContext` and `Placeholders`:
|
|
|
141
156
|
|
|
142
157
|
```ts
|
|
143
158
|
tasks: {
|
|
144
|
-
migrate: async (ctx, ph) => {
|
|
159
|
+
migrate: async (ctx, ph, task) => {
|
|
145
160
|
await ctx.run('npm run migrate');
|
|
146
161
|
},
|
|
147
162
|
}
|
|
@@ -154,7 +169,7 @@ tasks: {
|
|
|
154
169
|
myTask: {
|
|
155
170
|
name: 'My Task',
|
|
156
171
|
skip: async (ctx) => !someCondition ? 'Reason to skip' : false,
|
|
157
|
-
task: async (ctx, ph) => { /* ... */ },
|
|
172
|
+
task: async (ctx, ph, task) => { /* ... */ },
|
|
158
173
|
config: { /* passed as ctx.taskConfig */ },
|
|
159
174
|
},
|
|
160
175
|
}
|
|
@@ -187,7 +202,7 @@ Named sequences of tasks:
|
|
|
187
202
|
|
|
188
203
|
```ts
|
|
189
204
|
scenarios: {
|
|
190
|
-
deploy: ['upload', 'symlinks', '
|
|
205
|
+
deploy: ['upload', 'symlinks', 'install:packages', 'restart'],
|
|
191
206
|
}
|
|
192
207
|
```
|
|
193
208
|
|
|
@@ -197,30 +212,31 @@ Or as objects with a custom name:
|
|
|
197
212
|
scenarios: {
|
|
198
213
|
deploy: {
|
|
199
214
|
name: 'Deploy',
|
|
200
|
-
tasks: ['upload', 'symlinks', '
|
|
215
|
+
tasks: ['upload', 'symlinks', 'install:packages', 'restart'],
|
|
201
216
|
},
|
|
202
217
|
}
|
|
203
218
|
```
|
|
204
219
|
|
|
205
220
|
## Built-in tasks
|
|
206
221
|
|
|
207
|
-
| Task
|
|
208
|
-
|
|
|
209
|
-
| `upload`
|
|
210
|
-
| `download`
|
|
211
|
-
| `symlinks`
|
|
212
|
-
| `
|
|
213
|
-
| `pm2
|
|
214
|
-
| `docker
|
|
215
|
-
| `clear:target`
|
|
216
|
-
| `print:deployment`
|
|
217
|
-
| `
|
|
222
|
+
| Task | Description |
|
|
223
|
+
| ------------------- | -------------------------------------------------------- |
|
|
224
|
+
| `upload` | Rsync files to the remote server |
|
|
225
|
+
| `download` | Rsync files from the remote server (uses task config) |
|
|
226
|
+
| `symlinks` | Create configured symlinks on the remote server |
|
|
227
|
+
| `install:packages` | Install dependencies via npm/yarn/pnpm |
|
|
228
|
+
| `setup:pm2` | Start/restart PM2 processes (auto-detects pm2.config.*) |
|
|
229
|
+
| `setup:docker` | Run docker compose up (auto-detects compose files) |
|
|
230
|
+
| `clear:target` | Remove the entire deploy path (with confirmation prompt) |
|
|
231
|
+
| `print:deployment` | Print deployment info (date, files, disk usage) |
|
|
232
|
+
| `print:logs:pm2` | Stream PM2 logs for a configured duration |
|
|
233
|
+
| `print:logs:docker` | Stream Docker Compose logs for a configured duration |
|
|
218
234
|
|
|
219
235
|
### Default `deploy` scenario
|
|
220
236
|
|
|
221
|
-
The built-in `deploy` scenario runs: `upload` → `symlinks` → `
|
|
237
|
+
The built-in `deploy` scenario runs: `upload` → `symlinks` → `install:packages` → `setup:pm2` → `setup:docker` → `print:deployment` → `print:logs:pm2` → `print:logs:docker`
|
|
222
238
|
|
|
223
|
-
Tasks with skip conditions will be automatically skipped when not applicable (e.g. `pm2
|
|
239
|
+
Tasks with skip conditions will be automatically skipped when not applicable (e.g. `setup:pm2` skips if no PM2 config file exists).
|
|
224
240
|
|
|
225
241
|
## Requirements
|
|
226
242
|
|
package/dist/bin.js
CHANGED
|
File without changes
|
package/dist/cli.js
CHANGED
|
@@ -6,19 +6,24 @@ import { runScenario, runTask } from './runner.js';
|
|
|
6
6
|
const program = new Command()
|
|
7
7
|
.name('deployer')
|
|
8
8
|
.description('TypeScript deployment tool')
|
|
9
|
-
.option('-c, --config <path>', 'path to deployer.config.ts')
|
|
9
|
+
.option('-c, --config <path>', 'path to deployer.config.ts')
|
|
10
|
+
.option('--skip <tasks>', 'comma-separated list of tasks to skip');
|
|
10
11
|
program
|
|
11
12
|
.argument('<name>', 'scenario or task name')
|
|
12
13
|
.argument('[servers...]', 'target server(s)')
|
|
13
14
|
.action(async (name, servers) => {
|
|
14
15
|
try {
|
|
15
|
-
const
|
|
16
|
+
const opts = program.opts();
|
|
17
|
+
const config = await loadConfig(opts.config);
|
|
16
18
|
const serverList = servers.length > 0 ? servers : undefined;
|
|
19
|
+
const skipTasks = opts.skip
|
|
20
|
+
? opts.skip.split(',').map((s) => s.trim()).filter(Boolean)
|
|
21
|
+
: [];
|
|
17
22
|
if (config.scenarios?.[name]) {
|
|
18
|
-
await runScenario(config, name, serverList);
|
|
23
|
+
await runScenario(config, name, serverList, { skip: skipTasks });
|
|
19
24
|
}
|
|
20
25
|
else {
|
|
21
|
-
await runTask(config, name, serverList);
|
|
26
|
+
await runTask(config, name, serverList, { skip: skipTasks });
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
catch (err) {
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defaultsDeep } from 'lodash-es';
|
|
2
2
|
import os from 'node:os';
|
|
3
|
-
import { defaultScenarios, defaultTasks } from './
|
|
3
|
+
import { defaultScenarios, defaultTasks } from './tasks/index.js';
|
|
4
4
|
const SERVER_DEFAULTS = {
|
|
5
5
|
port: 22,
|
|
6
6
|
username: os.userInfo().username,
|
|
@@ -35,9 +35,6 @@ function normalizeScenario(key, input) {
|
|
|
35
35
|
tasks: input.tasks,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
export function camelToColonCase(str) {
|
|
39
|
-
return str.replace(/([a-z0-9])([A-Z])/g, '$1:$2').toLowerCase();
|
|
40
|
-
}
|
|
41
38
|
export function defineConfig(input) {
|
|
42
39
|
const servers = {};
|
|
43
40
|
for (const [name, serverInput] of Object.entries(input.servers)) {
|
|
@@ -45,57 +42,52 @@ export function defineConfig(input) {
|
|
|
45
42
|
}
|
|
46
43
|
const tasks = {};
|
|
47
44
|
for (const [key, taskDef] of Object.entries(defaultTasks)) {
|
|
48
|
-
tasks[
|
|
45
|
+
tasks[key] = taskDef;
|
|
49
46
|
}
|
|
50
47
|
if (input.tasks) {
|
|
51
48
|
for (const [key, taskInput] of Object.entries(input.tasks)) {
|
|
52
|
-
tasks[
|
|
49
|
+
tasks[key] = normalizeTask(key, taskInput);
|
|
53
50
|
}
|
|
54
51
|
}
|
|
55
52
|
const scenarios = {};
|
|
56
53
|
for (const [key, scenarioDef] of Object.entries(defaultScenarios)) {
|
|
57
|
-
scenarios[
|
|
54
|
+
scenarios[key] = {
|
|
58
55
|
...scenarioDef,
|
|
59
|
-
tasks: scenarioDef.tasks
|
|
56
|
+
tasks: scenarioDef.tasks,
|
|
60
57
|
};
|
|
61
58
|
}
|
|
62
59
|
if (input.scenarios) {
|
|
63
60
|
for (const [key, scenarioInput] of Object.entries(input.scenarios)) {
|
|
64
61
|
const normalized = normalizeScenario(key, scenarioInput);
|
|
65
|
-
scenarios[
|
|
62
|
+
scenarios[key] = {
|
|
66
63
|
...normalized,
|
|
67
|
-
tasks: normalized.tasks
|
|
64
|
+
tasks: normalized.tasks,
|
|
68
65
|
};
|
|
69
66
|
}
|
|
70
67
|
}
|
|
71
|
-
|
|
72
|
-
if (input.packageManager === false) {
|
|
73
|
-
packageManager = false;
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
packageManager = {
|
|
77
|
-
manager: 'npm',
|
|
78
|
-
productionOnly: true,
|
|
79
|
-
...input.packageManager,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
let dockerCompose;
|
|
83
|
-
if (input.dockerCompose === false) {
|
|
84
|
-
dockerCompose = false;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
dockerCompose = {
|
|
88
|
-
configFiles: undefined,
|
|
89
|
-
...input.dockerCompose,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
68
|
+
return defaultsDeep({
|
|
93
69
|
rootDir: '',
|
|
94
70
|
...input,
|
|
95
|
-
packageManager,
|
|
96
|
-
dockerCompose,
|
|
97
71
|
servers,
|
|
98
72
|
tasks,
|
|
99
73
|
scenarios,
|
|
100
|
-
}
|
|
74
|
+
}, {
|
|
75
|
+
packageManager: {
|
|
76
|
+
manager: 'npm',
|
|
77
|
+
productionOnly: true,
|
|
78
|
+
},
|
|
79
|
+
pm2: {
|
|
80
|
+
logs: {
|
|
81
|
+
lines: 25,
|
|
82
|
+
time: 3,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
dockerCompose: {
|
|
86
|
+
configFiles: undefined,
|
|
87
|
+
logs: {
|
|
88
|
+
lines: 25,
|
|
89
|
+
time: 3,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
});
|
|
101
93
|
}
|
package/dist/def.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ListrTaskWrapper } from 'listr2';
|
|
1
2
|
import type SSH2Promise from 'ssh2-promise';
|
|
2
3
|
export type AuthMethod = 'key' | 'password' | 'agent';
|
|
3
4
|
export type PackageManager = 'npm' | 'yarn' | 'pnpm';
|
|
@@ -27,12 +28,34 @@ export interface SymlinkConfig {
|
|
|
27
28
|
path: string;
|
|
28
29
|
target: string;
|
|
29
30
|
}
|
|
31
|
+
export type ConfigOrDisable<T> = T | false;
|
|
32
|
+
export interface LogsConfig {
|
|
33
|
+
time?: number;
|
|
34
|
+
lines?: number;
|
|
35
|
+
}
|
|
36
|
+
export type Pm2Config = {
|
|
37
|
+
logs: ConfigOrDisable<LogsConfig>;
|
|
38
|
+
};
|
|
30
39
|
export type DockerComposeConfig = {
|
|
31
40
|
configFiles: string[];
|
|
41
|
+
logs: ConfigOrDisable<LogsConfig>;
|
|
32
42
|
};
|
|
33
|
-
export interface
|
|
34
|
-
|
|
43
|
+
export interface DeployerConfig {
|
|
44
|
+
rootDir: string;
|
|
45
|
+
servers: Record<string, ServerConfig>;
|
|
46
|
+
files?: FilesConfig;
|
|
47
|
+
symlinks?: SymlinkConfig[];
|
|
48
|
+
packageManager?: ConfigOrDisable<PackageManagerConfig>;
|
|
49
|
+
pm2?: ConfigOrDisable<Pm2Config>;
|
|
50
|
+
dockerCompose?: ConfigOrDisable<DockerComposeConfig>;
|
|
51
|
+
tasks?: Record<string, TaskDef>;
|
|
52
|
+
scenarios?: Record<string, ScenarioDef>;
|
|
35
53
|
}
|
|
54
|
+
export type DeployerConfigInput = Omit<DeployerConfig, 'servers' | 'rootDir' | 'tasks' | 'scenarios'> & {
|
|
55
|
+
servers: Record<string, ServerConfigInput>;
|
|
56
|
+
tasks?: Record<string, TaskInput>;
|
|
57
|
+
scenarios?: Record<string, ScenarioInput>;
|
|
58
|
+
};
|
|
36
59
|
export interface Placeholders {
|
|
37
60
|
serverName: string;
|
|
38
61
|
deployPath: string;
|
|
@@ -60,7 +83,7 @@ export interface TaskContext {
|
|
|
60
83
|
test: (cmd: string) => Promise<boolean>;
|
|
61
84
|
taskConfig?: any;
|
|
62
85
|
}
|
|
63
|
-
export type TaskFn = (ctx: TaskContext, ph: Placeholders) => Promise<void>;
|
|
86
|
+
export type TaskFn = (ctx: TaskContext, ph: Placeholders, task: ListrTaskWrapper<any, any, any>) => Promise<void>;
|
|
64
87
|
export type TaskSkipFn = (ctx: TaskContext, ph: Placeholders) => Promise<boolean | string> | boolean | string;
|
|
65
88
|
export interface TaskDef {
|
|
66
89
|
name: string;
|
|
@@ -82,20 +105,3 @@ export type ScenarioInput = string[] | {
|
|
|
82
105
|
name: string;
|
|
83
106
|
tasks: string[];
|
|
84
107
|
};
|
|
85
|
-
export interface DeployerConfig {
|
|
86
|
-
rootDir: string;
|
|
87
|
-
servers: Record<string, ServerConfig>;
|
|
88
|
-
files?: FilesConfig;
|
|
89
|
-
symlinks?: SymlinkConfig[];
|
|
90
|
-
packageManager?: PackageManagerConfig | false;
|
|
91
|
-
pm2?: boolean;
|
|
92
|
-
dockerCompose?: DockerComposeConfig | false;
|
|
93
|
-
logs?: LogsConfig | false;
|
|
94
|
-
tasks?: Record<string, TaskDef>;
|
|
95
|
-
scenarios?: Record<string, ScenarioDef>;
|
|
96
|
-
}
|
|
97
|
-
export type DeployerConfigInput = Omit<DeployerConfig, 'servers' | 'rootDir' | 'tasks' | 'scenarios'> & {
|
|
98
|
-
servers: Record<string, ServerConfigInput>;
|
|
99
|
-
tasks?: Record<string, TaskInput>;
|
|
100
|
-
scenarios?: Record<string, ScenarioInput>;
|
|
101
|
-
};
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export type { AuthMethod, DeployerConfig, DeployerConfigInput, FilesConfig, Logs
|
|
|
2
2
|
export { defineConfig } from './config.js';
|
|
3
3
|
export { runScenario, runTask } from './runner.js';
|
|
4
4
|
export { loadConfig, findConfigFile } from './configLoader.js';
|
|
5
|
-
export { buildRsyncCommand, downloadSkip, downloadTask } from './
|
|
6
|
-
export type { RsyncOptions } from './
|
|
5
|
+
export { buildRsyncCommand, downloadSkip, downloadTask } from './tasks/index.js';
|
|
6
|
+
export type { RsyncOptions } from './tasks/upload.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { defineConfig } from './config.js';
|
|
2
2
|
export { runScenario, runTask } from './runner.js';
|
|
3
3
|
export { loadConfig, findConfigFile } from './configLoader.js';
|
|
4
|
-
export { buildRsyncCommand, downloadSkip, downloadTask } from './
|
|
4
|
+
export { buildRsyncCommand, downloadSkip, downloadTask } from './tasks/index.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare class CustomRenderer {
|
|
2
|
+
static nonTTY: boolean;
|
|
3
|
+
static rendererOptions: {
|
|
4
|
+
pausedTimer: {
|
|
5
|
+
field: (time: any) => string;
|
|
6
|
+
format: () => (text: string | number) => string;
|
|
7
|
+
condition?: boolean | ((args_0: number) => boolean);
|
|
8
|
+
args?: [number];
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
static rendererTaskOptions: {};
|
|
12
|
+
private tasks;
|
|
13
|
+
private options;
|
|
14
|
+
private logger;
|
|
15
|
+
private cache;
|
|
16
|
+
constructor(tasks: any, options: any);
|
|
17
|
+
end(): void;
|
|
18
|
+
render(): void;
|
|
19
|
+
private formatTitle;
|
|
20
|
+
renderer(tasks: any[]): void;
|
|
21
|
+
calculate(task: any): void;
|
|
22
|
+
reset(task: any): void;
|
|
23
|
+
}
|
package/dist/renderer.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { color, LISTR_LOGGER_STDERR_LEVELS, LISTR_LOGGER_STYLE, ListrLogger, ListrLogLevels, ListrTaskEventType, ListrTaskState, PRESET_TIMER, } from 'listr2';
|
|
3
|
+
export class CustomRenderer {
|
|
4
|
+
static nonTTY = true;
|
|
5
|
+
static rendererOptions = {
|
|
6
|
+
pausedTimer: {
|
|
7
|
+
...PRESET_TIMER,
|
|
8
|
+
field: (time) => `${ListrLogLevels.PAUSED}:${time}`,
|
|
9
|
+
format: () => color.yellowBright,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
static rendererTaskOptions = {};
|
|
13
|
+
tasks;
|
|
14
|
+
options;
|
|
15
|
+
logger;
|
|
16
|
+
cache = {
|
|
17
|
+
rendererOptions: new Map(),
|
|
18
|
+
rendererTaskOptions: new Map(),
|
|
19
|
+
};
|
|
20
|
+
constructor(tasks, options) {
|
|
21
|
+
this.tasks = tasks;
|
|
22
|
+
this.options = {
|
|
23
|
+
...CustomRenderer.rendererOptions,
|
|
24
|
+
...options,
|
|
25
|
+
icon: {
|
|
26
|
+
...LISTR_LOGGER_STYLE.icon,
|
|
27
|
+
...options?.icon ?? {},
|
|
28
|
+
},
|
|
29
|
+
color: {
|
|
30
|
+
...LISTR_LOGGER_STYLE.color,
|
|
31
|
+
...options?.color ?? {},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
this.logger = this.options.logger ?? new ListrLogger({
|
|
35
|
+
useIcons: true,
|
|
36
|
+
toStderr: LISTR_LOGGER_STDERR_LEVELS,
|
|
37
|
+
});
|
|
38
|
+
this.logger.options.icon = this.options.icon;
|
|
39
|
+
this.logger.options.color = this.options.color;
|
|
40
|
+
if (this.options.timestamp) {
|
|
41
|
+
this.logger.options.fields.prefix.unshift(this.options.timestamp);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
end() { }
|
|
45
|
+
render() {
|
|
46
|
+
this.renderer(this.tasks);
|
|
47
|
+
}
|
|
48
|
+
formatTitle(title) {
|
|
49
|
+
return chalk.bgCyan.black(` ${title} `);
|
|
50
|
+
}
|
|
51
|
+
renderer(tasks) {
|
|
52
|
+
tasks.forEach((task) => {
|
|
53
|
+
this.calculate(task);
|
|
54
|
+
task.once(ListrTaskEventType.CLOSED, () => {
|
|
55
|
+
this.reset(task);
|
|
56
|
+
});
|
|
57
|
+
const rendererTaskOptions = this.cache.rendererTaskOptions.get(task.id);
|
|
58
|
+
task.on(ListrTaskEventType.SUBTASK, (subtasks) => {
|
|
59
|
+
this.renderer(subtasks);
|
|
60
|
+
});
|
|
61
|
+
task.on(ListrTaskEventType.STATE, (state) => {
|
|
62
|
+
if (!task.hasTitle())
|
|
63
|
+
return;
|
|
64
|
+
const title = this.formatTitle(task.title);
|
|
65
|
+
if (state === ListrTaskState.STARTED) {
|
|
66
|
+
this.logger.log(ListrLogLevels.STARTED, title);
|
|
67
|
+
}
|
|
68
|
+
// else if (state === ListrTaskState.COMPLETED) {
|
|
69
|
+
// const timer = rendererTaskOptions?.timer;
|
|
70
|
+
// this.logger.log(ListrLogLevels.COMPLETED, title, timer && {
|
|
71
|
+
// suffix: {
|
|
72
|
+
// ...timer,
|
|
73
|
+
// condition: !!task.message?.duration && timer.condition,
|
|
74
|
+
// args: [ task.message.duration ],
|
|
75
|
+
// },
|
|
76
|
+
// });
|
|
77
|
+
// }
|
|
78
|
+
else if (state === ListrTaskState.PROMPT) {
|
|
79
|
+
this.logger.process.hijack();
|
|
80
|
+
task.on(ListrTaskEventType.PROMPT, (prompt) => {
|
|
81
|
+
this.logger.process.toStderr(prompt, false);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (state === ListrTaskState.PROMPT_COMPLETED) {
|
|
85
|
+
task.off(ListrTaskEventType.PROMPT);
|
|
86
|
+
this.logger.process.release();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
task.on(ListrTaskEventType.OUTPUT, (output) => {
|
|
90
|
+
this.logger.log(ListrLogLevels.OUTPUT, output);
|
|
91
|
+
});
|
|
92
|
+
task.on(ListrTaskEventType.MESSAGE, (message) => {
|
|
93
|
+
const title = this.formatTitle(task.title);
|
|
94
|
+
if (message.error) {
|
|
95
|
+
this.logger.log(ListrLogLevels.FAILED, title, {
|
|
96
|
+
suffix: {
|
|
97
|
+
field: `${ListrLogLevels.FAILED}: ${message.error}`,
|
|
98
|
+
format: () => color.red,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else if (message.skip) {
|
|
103
|
+
process.stdout.write(chalk.gray(`Skipped: ${message.skip}\n`));
|
|
104
|
+
}
|
|
105
|
+
else if (message.rollback) {
|
|
106
|
+
this.logger.log(ListrLogLevels.ROLLBACK, title, {
|
|
107
|
+
suffix: {
|
|
108
|
+
field: `${ListrLogLevels.ROLLBACK}: ${message.rollback}`,
|
|
109
|
+
format: () => color.red,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
else if (message.retry) {
|
|
114
|
+
this.logger.log(ListrLogLevels.RETRY, title, {
|
|
115
|
+
suffix: {
|
|
116
|
+
field: `${ListrLogLevels.RETRY}:${message.retry.count}`,
|
|
117
|
+
format: () => color.red,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else if (message.paused) {
|
|
122
|
+
const rendererOptions = this.cache.rendererOptions.get(task.id);
|
|
123
|
+
const timer = rendererOptions?.pausedTimer;
|
|
124
|
+
this.logger.log(ListrLogLevels.PAUSED, title, timer && {
|
|
125
|
+
suffix: {
|
|
126
|
+
...timer,
|
|
127
|
+
condition: !!message?.paused && timer.condition,
|
|
128
|
+
args: [message.paused - Date.now()],
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
calculate(task) {
|
|
136
|
+
if (this.cache.rendererOptions.has(task.id) && this.cache.rendererTaskOptions.has(task.id))
|
|
137
|
+
return;
|
|
138
|
+
const rendererOptions = {
|
|
139
|
+
...this.options,
|
|
140
|
+
...task.rendererOptions,
|
|
141
|
+
};
|
|
142
|
+
this.cache.rendererOptions.set(task.id, rendererOptions);
|
|
143
|
+
this.cache.rendererTaskOptions.set(task.id, {
|
|
144
|
+
...CustomRenderer.rendererTaskOptions,
|
|
145
|
+
timer: rendererOptions.timer,
|
|
146
|
+
...task.rendererTaskOptions,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
reset(task) {
|
|
150
|
+
this.cache.rendererOptions.delete(task.id);
|
|
151
|
+
this.cache.rendererTaskOptions.delete(task.id);
|
|
152
|
+
}
|
|
153
|
+
}
|
package/dist/runner.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { DeployerConfig, ServerConfig, TaskDef } from './def.js';
|
|
2
|
-
export declare function resolveServers(config: DeployerConfig, serverNames?: string[]):
|
|
3
|
-
export declare function resolveTaskDefs(taskNames: string[], allTasks: Record<string, TaskDef>):
|
|
4
|
-
export declare function runScenario(config: DeployerConfig, scenarioName: string, serverNames?: string[]
|
|
5
|
-
|
|
2
|
+
export declare function resolveServers(config: DeployerConfig, serverNames?: string[]): Record<string, ServerConfig>;
|
|
3
|
+
export declare function resolveTaskDefs(taskNames: string[], allTasks: Record<string, TaskDef>): Record<string, TaskDef>;
|
|
4
|
+
export declare function runScenario(config: DeployerConfig, scenarioName: string, serverNames?: string[], options?: {
|
|
5
|
+
skip?: string[];
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
export declare function runTask(config: DeployerConfig, taskName: string, serverNames?: string[], options?: {
|
|
8
|
+
skip?: string[];
|
|
9
|
+
}): Promise<void>;
|