@datatruck/cli 0.34.4 → 0.35.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/config.schema.json +57 -0
- package/lib/actions/BackupAction.js +123 -38
- package/lib/actions/CopyAction.js +40 -18
- package/lib/actions/InitAction.js +1 -1
- package/lib/actions/RestoreAction.d.ts +0 -2
- package/lib/actions/RestoreAction.js +128 -60
- package/lib/repositories/DatatruckRepository.d.ts +1 -1
- package/lib/repositories/DatatruckRepository.js +25 -15
- package/lib/repositories/GitRepository.js +11 -3
- package/lib/repositories/RepositoryAbstract.d.ts +2 -1
- package/lib/repositories/RepositoryAbstract.js +3 -1
- package/lib/tasks/MongoDumpTask.d.ts +21 -0
- package/lib/tasks/MongoDumpTask.js +48 -0
- package/lib/tasks/PostgresqlDumpTask.js +14 -2
- package/lib/utils/datatruck/client.d.ts +7 -3
- package/lib/utils/datatruck/client.js +9 -2
- package/lib/utils/datatruck/config-task-type.d.ts +6 -1
- package/lib/utils/datatruck/config.js +2 -2
- package/lib/utils/datatruck/repository.d.ts +3 -3
- package/lib/utils/datatruck/repository.js +3 -3
- package/lib/utils/datatruck/task.js +4 -0
- package/lib/utils/fs.d.ts +2 -1
- package/lib/utils/fs.js +18 -0
- package/lib/utils/git.d.ts +5 -0
- package/lib/utils/git.js +10 -0
- package/lib/utils/list.d.ts +3 -1
- package/lib/utils/list.js +2 -3
- package/lib/utils/mysql.js +3 -2
- package/lib/utils/progress.d.ts +8 -1
- package/lib/utils/progress.js +38 -5
- package/lib/utils/temp.d.ts +13 -10
- package/lib/utils/temp.js +47 -40
- package/package.json +1 -1
|
@@ -45,15 +45,15 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
45
45
|
return this.config.backend;
|
|
46
46
|
}
|
|
47
47
|
fetchDiskStats(config) {
|
|
48
|
-
const fs = (0, client_1.createFs)(config.backend);
|
|
48
|
+
const fs = (0, client_1.createFs)(config.backend, this.verbose);
|
|
49
49
|
return fs.fetchDiskStats(".");
|
|
50
50
|
}
|
|
51
51
|
async init(data) {
|
|
52
|
-
const fs = (0, client_1.createFs)(this.config.backend);
|
|
52
|
+
const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
|
|
53
53
|
await fs.mkdir(".");
|
|
54
54
|
}
|
|
55
55
|
async prune(data) {
|
|
56
|
-
const fs = (0, client_1.createFs)(this.config.backend);
|
|
56
|
+
const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
|
|
57
57
|
const snapshotName = DatatruckRepository.buildSnapshotName(data.snapshot, {
|
|
58
58
|
name: data.snapshot.packageName,
|
|
59
59
|
});
|
|
@@ -63,7 +63,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
63
63
|
await fs.rmAll(snapshotName);
|
|
64
64
|
}
|
|
65
65
|
async fetchSnapshots(data) {
|
|
66
|
-
const fs = (0, client_1.createFs)(this.config.backend);
|
|
66
|
+
const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
|
|
67
67
|
if (!(await fs.existsDir(".")))
|
|
68
68
|
throw new error_1.AppError(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
|
|
69
69
|
const snapshots = [];
|
|
@@ -105,7 +105,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
105
105
|
return snapshots;
|
|
106
106
|
}
|
|
107
107
|
async backup(data) {
|
|
108
|
-
const fs = (0, client_1.createFs)(this.config.backend);
|
|
108
|
+
const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
|
|
109
109
|
const snapshotName = DatatruckRepository.buildSnapshotName(data.snapshot, data.package);
|
|
110
110
|
const outPath = fs.isLocal()
|
|
111
111
|
? fs.resolvePath(snapshotName)
|
|
@@ -177,11 +177,11 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
177
177
|
.join("-") + (pack.compress ? `.tar.gz` : `.tar`);
|
|
178
178
|
const includeList = stream.path(packIndex);
|
|
179
179
|
if (includeList) {
|
|
180
|
-
tarStats[packBasename] = {
|
|
180
|
+
const stats = (tarStats[packBasename] = {
|
|
181
181
|
files: stream.lines(packIndex),
|
|
182
182
|
size: 0,
|
|
183
183
|
checksum: "",
|
|
184
|
-
};
|
|
184
|
+
});
|
|
185
185
|
const tarPath = (0, path_1.join)(outPath, packBasename);
|
|
186
186
|
await (0, tar_1.createTar)({
|
|
187
187
|
compress: pack.compress,
|
|
@@ -192,8 +192,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
192
192
|
onEntry: async (data) => scanner.progress(pack.compress ? "Compressing" : "Packing", data.path),
|
|
193
193
|
});
|
|
194
194
|
scanner.progress("Fetching tar stats", (0, path_1.basename)(tarPath), false);
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
stats.checksum = await (0, crypto_1.calcFileHash)(tarPath, "sha1");
|
|
196
|
+
stats.size = (await (0, promises_1.stat)(tarPath)).size;
|
|
197
197
|
if (!fs.isLocal()) {
|
|
198
198
|
scanner.progress("Uploading tar", (0, path_1.basename)(tarPath), false);
|
|
199
199
|
await fs.upload(tarPath, `${snapshotName}/${packBasename}`);
|
|
@@ -204,7 +204,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
204
204
|
}
|
|
205
205
|
scanner.end();
|
|
206
206
|
// Meta
|
|
207
|
-
const size = Object.values(tarStats).reduce((total,
|
|
207
|
+
const size = Object.values(tarStats).reduce((total, stat) => total + stat.size, 0);
|
|
208
208
|
const metaPath = `${snapshotName}/meta.json`;
|
|
209
209
|
const nodePkg = (0, fs_1.parsePackageFile)();
|
|
210
210
|
const meta = {
|
|
@@ -225,8 +225,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
225
225
|
};
|
|
226
226
|
}
|
|
227
227
|
async copy(data) {
|
|
228
|
-
const sourceFs = (0, client_1.createFs)(this.config.backend);
|
|
229
|
-
const targetFs = (0, client_1.createFs)(data.mirrorRepositoryConfig.backend);
|
|
228
|
+
const sourceFs = (0, client_1.createFs)(this.config.backend, this.verbose);
|
|
229
|
+
const targetFs = (0, client_1.createFs)(data.mirrorRepositoryConfig.backend, this.verbose);
|
|
230
230
|
const snapshotName = DatatruckRepository.buildSnapshotName(data.snapshot, data.package);
|
|
231
231
|
if (data.options.verbose)
|
|
232
232
|
(0, cli_1.logExec)(`Copying backup files to ${data.mirrorRepositoryConfig.backend}`);
|
|
@@ -296,7 +296,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
296
296
|
return { bytes };
|
|
297
297
|
}
|
|
298
298
|
async restore(data) {
|
|
299
|
-
const fs = (0, client_1.createFs)(this.config.backend);
|
|
299
|
+
const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
|
|
300
300
|
const relRestorePath = data.snapshotPath;
|
|
301
301
|
(0, assert_1.ok)(relRestorePath);
|
|
302
302
|
const restorePath = (0, path_1.resolve)(relRestorePath);
|
|
@@ -325,10 +325,20 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
325
325
|
if (!fs.isLocal()) {
|
|
326
326
|
const tempDir = await (0, temp_1.mkTmpDir)(exports.datatruckRepositoryName, "repo", "restore", "remote-fs", entry);
|
|
327
327
|
tempEntry = `${tempDir}/${entry}`;
|
|
328
|
-
await fs.download(sourceEntry, tempEntry
|
|
328
|
+
await fs.download(sourceEntry, tempEntry, {
|
|
329
|
+
onProgress: (stats) => {
|
|
330
|
+
progress.updateRelative("Downloading", entry, {
|
|
331
|
+
...stats,
|
|
332
|
+
format: "size",
|
|
333
|
+
});
|
|
334
|
+
},
|
|
335
|
+
});
|
|
329
336
|
}
|
|
337
|
+
const stats = tarStats[entry];
|
|
338
|
+
if (data.options.verbose)
|
|
339
|
+
(0, cli_1.logExec)(`Stats of '${entry}' is not available`);
|
|
330
340
|
await (0, tar_1.extractTar)({
|
|
331
|
-
total:
|
|
341
|
+
total: stats?.files,
|
|
332
342
|
input: tempEntry ?? fs.resolvePath(sourceEntry),
|
|
333
343
|
output: restorePath,
|
|
334
344
|
decompress: entry.endsWith(".tar.gz"),
|
|
@@ -68,7 +68,11 @@ class GitRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
68
68
|
branchName,
|
|
69
69
|
orphan: true,
|
|
70
70
|
});
|
|
71
|
-
await git.
|
|
71
|
+
await git.commit("Initial commit", {
|
|
72
|
+
allowEmpty: true,
|
|
73
|
+
userName: "datatruck",
|
|
74
|
+
userEmail: "datatruck@localhost",
|
|
75
|
+
});
|
|
72
76
|
await git.push({ branchName });
|
|
73
77
|
}
|
|
74
78
|
}
|
|
@@ -184,8 +188,12 @@ class GitRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
184
188
|
if (data.options.verbose)
|
|
185
189
|
console.info(`Copied ${files} files`);
|
|
186
190
|
await git.exec(["add", "--verbose", "."]);
|
|
187
|
-
if (await git.haveChanges())
|
|
188
|
-
await git.
|
|
191
|
+
if (await git.haveChanges()) {
|
|
192
|
+
await git.commit(data.snapshot.id, {
|
|
193
|
+
userName: "datatruck",
|
|
194
|
+
userEmail: "datatruck@localhost",
|
|
195
|
+
});
|
|
196
|
+
}
|
|
189
197
|
const nodePkg = (0, fs_1.parsePackageFile)();
|
|
190
198
|
const size = (await (0, fs_1.fastFolderSizeAsync)(tmpPath)) -
|
|
191
199
|
(await (0, fs_1.fastFolderSizeAsync)((0, path_1.join)(tmpPath, ".git")));
|
|
@@ -75,8 +75,9 @@ export type SnapshotTagObject = {
|
|
|
75
75
|
};
|
|
76
76
|
export declare abstract class RepositoryAbstract<TConfig> {
|
|
77
77
|
readonly repository: RepositoryConfig;
|
|
78
|
+
readonly verbose: boolean;
|
|
78
79
|
readonly config: TConfig;
|
|
79
|
-
constructor(repository: RepositoryConfig);
|
|
80
|
+
constructor(repository: RepositoryConfig, verbose: boolean);
|
|
80
81
|
abstract getSource(): string;
|
|
81
82
|
abstract fetchDiskStats(config: TConfig): Promise<DiskStats | undefined>;
|
|
82
83
|
ensureFreeDiskSpace(config: TConfig, minFreeDiskSpace: number | string): Promise<void>;
|
|
@@ -15,9 +15,11 @@ var SnapshotTagEnum;
|
|
|
15
15
|
})(SnapshotTagEnum || (exports.SnapshotTagEnum = SnapshotTagEnum = {}));
|
|
16
16
|
class RepositoryAbstract {
|
|
17
17
|
repository;
|
|
18
|
+
verbose;
|
|
18
19
|
config;
|
|
19
|
-
constructor(repository) {
|
|
20
|
+
constructor(repository, verbose) {
|
|
20
21
|
this.repository = repository;
|
|
22
|
+
this.verbose = verbose;
|
|
21
23
|
this.config = repository.config;
|
|
22
24
|
}
|
|
23
25
|
async ensureFreeDiskSpace(config, minFreeDiskSpace) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { TaskBackupData, TaskRestoreData, TaskAbstract } from "./TaskAbstract";
|
|
2
|
+
export type MongoDumpTaskConfig = {
|
|
3
|
+
command?: string;
|
|
4
|
+
hostname?: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
username?: string;
|
|
7
|
+
password?: string | {
|
|
8
|
+
path: string;
|
|
9
|
+
};
|
|
10
|
+
compress?: boolean;
|
|
11
|
+
concurrency?: number;
|
|
12
|
+
};
|
|
13
|
+
export declare const mongodumpTaskName = "mongo-dump";
|
|
14
|
+
export declare class MongoDumpTask extends TaskAbstract<MongoDumpTaskConfig> {
|
|
15
|
+
protected verbose?: boolean;
|
|
16
|
+
private get command();
|
|
17
|
+
backup(data: TaskBackupData): Promise<{
|
|
18
|
+
snapshotPath: string;
|
|
19
|
+
}>;
|
|
20
|
+
restore(data: TaskRestoreData): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoDumpTask = exports.mongodumpTaskName = void 0;
|
|
4
|
+
const async_process_1 = require("../utils/async-process");
|
|
5
|
+
const fs_1 = require("../utils/fs");
|
|
6
|
+
const temp_1 = require("../utils/temp");
|
|
7
|
+
const TaskAbstract_1 = require("./TaskAbstract");
|
|
8
|
+
exports.mongodumpTaskName = "mongo-dump";
|
|
9
|
+
class MongoDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
10
|
+
verbose;
|
|
11
|
+
get command() {
|
|
12
|
+
return this.config.command ?? "mongodump";
|
|
13
|
+
}
|
|
14
|
+
async backup(data) {
|
|
15
|
+
this.verbose = data.options.verbose;
|
|
16
|
+
const snapshotPath = data.package.path ??
|
|
17
|
+
(await (0, temp_1.mkTmpDir)(exports.mongodumpTaskName, "task", "backup", "snapshot"));
|
|
18
|
+
await (0, fs_1.mkdirIfNotExists)(snapshotPath);
|
|
19
|
+
await (0, fs_1.ensureEmptyDir)(snapshotPath);
|
|
20
|
+
const p = new async_process_1.AsyncProcess(this.command, [
|
|
21
|
+
...(this.config.hostname ? ["/h", this.config.hostname] : []),
|
|
22
|
+
...(this.config.port ? ["/p", this.config.port] : []),
|
|
23
|
+
...(this.config.username ? ["/u", this.config.username] : []),
|
|
24
|
+
...(this.config.compress ? ["/gzip"] : []),
|
|
25
|
+
...(this.config.concurrency ? ["/j", this.config.concurrency] : []),
|
|
26
|
+
"/o",
|
|
27
|
+
snapshotPath,
|
|
28
|
+
], {
|
|
29
|
+
$log: this.verbose,
|
|
30
|
+
});
|
|
31
|
+
const password = this.config.password !== undefined
|
|
32
|
+
? (await (0, fs_1.fetchData)(this.config.password, (p) => p.path)) ?? ""
|
|
33
|
+
: "";
|
|
34
|
+
p.stdin.writable.write(`${password}\n`);
|
|
35
|
+
await p.stderr.parseLines((line) => {
|
|
36
|
+
data.onProgress({
|
|
37
|
+
absolute: {
|
|
38
|
+
description: line.slice(0, 255),
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return { snapshotPath };
|
|
43
|
+
}
|
|
44
|
+
async restore(data) {
|
|
45
|
+
throw new Error("Not implemented");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.MongoDumpTask = MongoDumpTask;
|
|
@@ -64,14 +64,26 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
64
64
|
const dumpProcess = new async_process_1.AsyncProcess("pg_dump", [
|
|
65
65
|
...(await this.buildConnectionArgs(this.config.database)),
|
|
66
66
|
...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
|
|
67
|
-
], {
|
|
67
|
+
], {
|
|
68
|
+
$log: {
|
|
69
|
+
exec: this.verbose,
|
|
70
|
+
stderr: this.verbose,
|
|
71
|
+
allToStderr: true,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
68
74
|
await dumpProcess.stdout.pipe(output, onProgress);
|
|
69
75
|
}
|
|
70
76
|
async onExportStoredPrograms() {
|
|
71
77
|
throw new Error(`Method not implemented: onExportStoredPrograms`);
|
|
72
78
|
}
|
|
73
79
|
async onImport(path, database) {
|
|
74
|
-
await async_process_1.AsyncProcess.exec("psql", [...(await this.buildConnectionArgs(database)), "-f", (0, path_1.normalize)(path)], {
|
|
80
|
+
await async_process_1.AsyncProcess.exec("psql", [...(await this.buildConnectionArgs(database)), "-f", (0, path_1.normalize)(path)], {
|
|
81
|
+
$log: {
|
|
82
|
+
exec: this.verbose,
|
|
83
|
+
stderr: this.verbose,
|
|
84
|
+
allToStderr: true,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
75
87
|
}
|
|
76
88
|
}
|
|
77
89
|
exports.PostgresqlDumpTask = PostgresqlDumpTask;
|
|
@@ -2,10 +2,14 @@ import { DiskStats } from "../fs";
|
|
|
2
2
|
import { BasicProgress } from "../progress";
|
|
3
3
|
import { AbstractFs, FsOptions } from "../virtual-fs";
|
|
4
4
|
export declare class RemoteFs extends AbstractFs {
|
|
5
|
-
readonly options: FsOptions
|
|
5
|
+
readonly options: FsOptions & {
|
|
6
|
+
verbose?: boolean;
|
|
7
|
+
};
|
|
6
8
|
protected url: string;
|
|
7
9
|
protected headers: Record<string, string>;
|
|
8
|
-
constructor(options: FsOptions
|
|
10
|
+
constructor(options: FsOptions & {
|
|
11
|
+
verbose?: boolean;
|
|
12
|
+
});
|
|
9
13
|
isLocal(): boolean;
|
|
10
14
|
protected fetchJson(name: string, params: any[]): Promise<any>;
|
|
11
15
|
protected post(name: string, params: any[], data: string): Promise<void>;
|
|
@@ -28,4 +32,4 @@ export declare class RemoteFs extends AbstractFs {
|
|
|
28
32
|
}>;
|
|
29
33
|
}
|
|
30
34
|
export declare function isRemoteBackend(backend: string): boolean;
|
|
31
|
-
export declare function createFs(backend: string): AbstractFs;
|
|
35
|
+
export declare function createFs(backend: string, verbose: boolean | undefined): AbstractFs;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createFs = exports.isRemoteBackend = exports.RemoteFs = void 0;
|
|
4
|
+
const cli_1 = require("../cli");
|
|
4
5
|
const http_1 = require("../http");
|
|
5
6
|
const virtual_fs_1 = require("../virtual-fs");
|
|
6
7
|
const repository_server_1 = require("./repository-server");
|
|
@@ -69,9 +70,13 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
|
|
|
69
70
|
await this.fetchJson("rmAll", [path]);
|
|
70
71
|
}
|
|
71
72
|
async fetchDiskStats(path) {
|
|
73
|
+
if (this.options.verbose)
|
|
74
|
+
(0, cli_1.logExec)("fs.fetchDiskStats", [path]);
|
|
72
75
|
return await this.fetchJson("fetchDiskStats", [path]);
|
|
73
76
|
}
|
|
74
77
|
async upload(source, target) {
|
|
78
|
+
if (this.options.verbose)
|
|
79
|
+
(0, cli_1.logExec)("fs.upload", [source, target]);
|
|
75
80
|
await (0, http_1.uploadFile)(`${this.url}/upload`, source, {
|
|
76
81
|
headers: this.headers,
|
|
77
82
|
query: {
|
|
@@ -80,6 +85,8 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
|
|
|
80
85
|
});
|
|
81
86
|
}
|
|
82
87
|
async download(source, target, options = {}) {
|
|
88
|
+
if (this.options.verbose)
|
|
89
|
+
(0, cli_1.logExec)("fs.download", [source, target]);
|
|
83
90
|
return await (0, http_1.downloadFile)(`${this.url}/download`, target, {
|
|
84
91
|
...options,
|
|
85
92
|
headers: this.headers,
|
|
@@ -92,9 +99,9 @@ function isRemoteBackend(backend) {
|
|
|
92
99
|
return backend.startsWith("http:") || backend.startsWith("https:");
|
|
93
100
|
}
|
|
94
101
|
exports.isRemoteBackend = isRemoteBackend;
|
|
95
|
-
function createFs(backend) {
|
|
102
|
+
function createFs(backend, verbose) {
|
|
96
103
|
return isRemoteBackend(backend)
|
|
97
|
-
? new RemoteFs({ backend })
|
|
104
|
+
? new RemoteFs({ backend, verbose })
|
|
98
105
|
: new virtual_fs_1.LocalFs({ backend });
|
|
99
106
|
}
|
|
100
107
|
exports.createFs = createFs;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { GitTaskConfig, gitTaskName } from "../../tasks/GitTask";
|
|
2
2
|
import type { MariadbTaskConfig, mariadbTaskName } from "../../tasks/MariadbTask";
|
|
3
|
+
import { MongoDumpTaskConfig, mongodumpTaskName } from "../../tasks/MongoDumpTask";
|
|
3
4
|
import type { MssqlTaskConfig, mssqlTaskName } from "../../tasks/MssqlTask";
|
|
4
5
|
import type { MysqlDumpTaskConfig, mysqlDumpTaskName } from "../../tasks/MysqlDumpTask";
|
|
5
6
|
import type { PostgresqlDumpTaskConfig, postgresqlDumpTaskName } from "../../tasks/PostgresqlDumpTask";
|
|
@@ -24,8 +25,12 @@ export type PostgresqlDumpTaskConfigItem = {
|
|
|
24
25
|
name: typeof postgresqlDumpTaskName;
|
|
25
26
|
config: PostgresqlDumpTaskConfig;
|
|
26
27
|
};
|
|
28
|
+
export type MongodumpTaskConfigItem = {
|
|
29
|
+
name: typeof mongodumpTaskName;
|
|
30
|
+
config: MongoDumpTaskConfig;
|
|
31
|
+
};
|
|
27
32
|
export type ScriptTaskConfigItem = {
|
|
28
33
|
name: typeof scriptTaskName;
|
|
29
34
|
config: ScriptTaskConfig;
|
|
30
35
|
};
|
|
31
|
-
export type TaskConfig = GitTaskConfigItem | MariadbTaskConfigItem | MssqlTaskConfigItem | MysqlDumpTaskConfigItem | PostgresqlDumpTaskConfigItem | ScriptTaskConfigItem;
|
|
36
|
+
export type TaskConfig = GitTaskConfigItem | MariadbTaskConfigItem | MssqlTaskConfigItem | MysqlDumpTaskConfigItem | PostgresqlDumpTaskConfigItem | MongodumpTaskConfigItem | ScriptTaskConfigItem;
|
|
@@ -8,14 +8,14 @@ const micromatch_1 = require("micromatch");
|
|
|
8
8
|
function findRepositoryOrFail(config, repositoryName) {
|
|
9
9
|
const repo = config.repositories.find((v) => v.name === repositoryName);
|
|
10
10
|
if (!repo)
|
|
11
|
-
throw new error_1.AppError(`Repository '${repositoryName}' not found`);
|
|
11
|
+
throw new error_1.AppError(`Repository '${repositoryName}' not found in the config`);
|
|
12
12
|
return repo;
|
|
13
13
|
}
|
|
14
14
|
exports.findRepositoryOrFail = findRepositoryOrFail;
|
|
15
15
|
function findPackageOrFail(config, packageName) {
|
|
16
16
|
const pkg = config.packages.find((v) => v.name === packageName);
|
|
17
17
|
if (!pkg)
|
|
18
|
-
throw new error_1.AppError(`Package '${packageName}' not found`);
|
|
18
|
+
throw new error_1.AppError(`Package '${packageName}' not found in the config`);
|
|
19
19
|
return pkg;
|
|
20
20
|
}
|
|
21
21
|
exports.findPackageOrFail = findPackageOrFail;
|
|
@@ -9,8 +9,8 @@ declare const repoMap: {
|
|
|
9
9
|
datatruck: typeof DatatruckRepository;
|
|
10
10
|
};
|
|
11
11
|
export declare function getRepoConstructor(type: keyof typeof repoMap): {
|
|
12
|
-
new (config: RepositoryConfig): RepositoryAbstract<any>;
|
|
12
|
+
new (config: RepositoryConfig, verbose?: boolean): RepositoryAbstract<any>;
|
|
13
13
|
};
|
|
14
|
-
export declare function createRepo(repository: RepositoryConfig): RepositoryAbstract<any>;
|
|
15
|
-
export declare function createAndInitRepo(repository: RepositoryConfig, verbose
|
|
14
|
+
export declare function createRepo(repository: RepositoryConfig, verbose: boolean | undefined): RepositoryAbstract<any>;
|
|
15
|
+
export declare function createAndInitRepo(repository: RepositoryConfig, verbose: boolean | undefined): Promise<RepositoryAbstract<any>>;
|
|
16
16
|
export {};
|
|
@@ -17,13 +17,13 @@ function getRepoConstructor(type) {
|
|
|
17
17
|
return Constructor;
|
|
18
18
|
}
|
|
19
19
|
exports.getRepoConstructor = getRepoConstructor;
|
|
20
|
-
function createRepo(repository) {
|
|
20
|
+
function createRepo(repository, verbose) {
|
|
21
21
|
const Constructor = getRepoConstructor(repository.type);
|
|
22
|
-
return new Constructor(repository);
|
|
22
|
+
return new Constructor(repository, verbose);
|
|
23
23
|
}
|
|
24
24
|
exports.createRepo = createRepo;
|
|
25
25
|
async function createAndInitRepo(repository, verbose) {
|
|
26
|
-
const repo = createRepo(repository);
|
|
26
|
+
const repo = createRepo(repository, verbose);
|
|
27
27
|
await repo.init({ options: { verbose } });
|
|
28
28
|
return repo;
|
|
29
29
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createTask = void 0;
|
|
4
4
|
const GitTask_1 = require("../../tasks/GitTask");
|
|
5
5
|
const MariadbTask_1 = require("../../tasks/MariadbTask");
|
|
6
|
+
const MongoDumpTask_1 = require("../../tasks/MongoDumpTask");
|
|
6
7
|
const MssqlTask_1 = require("../../tasks/MssqlTask");
|
|
7
8
|
const MysqlDumpTask_1 = require("../../tasks/MysqlDumpTask");
|
|
8
9
|
const PostgresqlDumpTask_1 = require("../../tasks/PostgresqlDumpTask");
|
|
@@ -24,6 +25,9 @@ function createTask(task) {
|
|
|
24
25
|
else if (task.name === MssqlTask_1.mssqlTaskName) {
|
|
25
26
|
return new MssqlTask_1.MssqlTask(task.config ?? {});
|
|
26
27
|
}
|
|
28
|
+
else if (task.name === MongoDumpTask_1.mongodumpTaskName) {
|
|
29
|
+
return new MongoDumpTask_1.MongoDumpTask(task.config ?? {});
|
|
30
|
+
}
|
|
27
31
|
else if (task.name === ScriptTask_1.scriptTaskName) {
|
|
28
32
|
return new ScriptTask_1.ScriptTask(task.config ?? {});
|
|
29
33
|
}
|
package/lib/utils/fs.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
/// <reference types="node" />
|
|
4
|
-
import { Progress } from "./progress";
|
|
4
|
+
import { Progress, ProgressStats } from "./progress";
|
|
5
5
|
import { Entry, Options } from "fast-glob";
|
|
6
6
|
import { Stats } from "fs";
|
|
7
7
|
import { WriteStream } from "fs";
|
|
@@ -90,6 +90,7 @@ type ProgressObject = {
|
|
|
90
90
|
total: number;
|
|
91
91
|
current: number;
|
|
92
92
|
update: (description: string, path?: string, increment?: boolean) => void;
|
|
93
|
+
updateRelative: (description: string, path: string, stats: ProgressStats) => void;
|
|
93
94
|
};
|
|
94
95
|
export declare function createProgress(options: {
|
|
95
96
|
onProgress: (data: Progress) => void;
|
package/lib/utils/fs.js
CHANGED
|
@@ -400,11 +400,29 @@ function createProgress(options) {
|
|
|
400
400
|
disposed: false,
|
|
401
401
|
total: 0,
|
|
402
402
|
current: 0,
|
|
403
|
+
updateRelative(description, path, stats) {
|
|
404
|
+
if (progress.disposed)
|
|
405
|
+
return;
|
|
406
|
+
options.onProgress({
|
|
407
|
+
relative: {
|
|
408
|
+
...stats,
|
|
409
|
+
description,
|
|
410
|
+
payload: path,
|
|
411
|
+
},
|
|
412
|
+
absolute: {
|
|
413
|
+
total: progress.total,
|
|
414
|
+
current: progress.current,
|
|
415
|
+
percent: (0, math_1.progressPercent)(progress.total, progress.current),
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
},
|
|
403
419
|
update: (description, path, increment = true) => {
|
|
404
420
|
if (progress.disposed)
|
|
405
421
|
return;
|
|
406
422
|
if (path && increment)
|
|
407
423
|
progress.current++;
|
|
424
|
+
if (path === "." || path === "./")
|
|
425
|
+
return;
|
|
408
426
|
options.onProgress({
|
|
409
427
|
relative: {
|
|
410
428
|
description,
|
package/lib/utils/git.d.ts
CHANGED
|
@@ -28,6 +28,11 @@ export declare class Git {
|
|
|
28
28
|
removeAll(): Promise<void>;
|
|
29
29
|
haveChanges(): Promise<boolean>;
|
|
30
30
|
fetchCommitId(tag: string): Promise<string>;
|
|
31
|
+
commit(description: string, options?: {
|
|
32
|
+
allowEmpty?: boolean;
|
|
33
|
+
userName?: string;
|
|
34
|
+
userEmail?: string;
|
|
35
|
+
}): Promise<void>;
|
|
31
36
|
getTags(names?: string[]): Promise<{
|
|
32
37
|
name: string;
|
|
33
38
|
message?: string | undefined;
|
package/lib/utils/git.js
CHANGED
|
@@ -70,6 +70,16 @@ class Git {
|
|
|
70
70
|
async fetchCommitId(tag) {
|
|
71
71
|
return (await this.stdout(["rev-list", "-n", "1", tag])).trim();
|
|
72
72
|
}
|
|
73
|
+
async commit(description, options = {}) {
|
|
74
|
+
await this.exec([
|
|
75
|
+
...(options.userName ? ["-c", `user.name='${options.userName}'`] : []),
|
|
76
|
+
...(options.userEmail ? ["-c", `user.email='${options.userEmail}'`] : []),
|
|
77
|
+
"commit",
|
|
78
|
+
"-m",
|
|
79
|
+
description,
|
|
80
|
+
...(options.allowEmpty ? ["--allow-empty"] : []),
|
|
81
|
+
]);
|
|
82
|
+
}
|
|
73
83
|
async getTags(names) {
|
|
74
84
|
const stdout = await this.stdout(["tag", "-n", ...(names ?? [])]);
|
|
75
85
|
return stdout.split(/\r?\n/).reduce((result, value) => {
|
package/lib/utils/list.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Timer } from "./date";
|
|
2
2
|
import { ProgressManager } from "./progress";
|
|
3
3
|
import { StdStreams } from "./stream";
|
|
4
|
+
import { GargabeCollector } from "./temp";
|
|
4
5
|
import { Listr, ListrGetRendererClassFromValue, ListrLogger, ListrTask, ListrTaskWrapper } from "listr2";
|
|
5
6
|
export declare class List3Logger<Levels extends string = string> extends ListrLogger<Levels> {
|
|
6
7
|
constructor(options?: {
|
|
@@ -19,7 +20,6 @@ type Listr3Task<T extends Listr3Context, K extends keyof T> = {
|
|
|
19
20
|
failed?: string;
|
|
20
21
|
completed?: string;
|
|
21
22
|
};
|
|
22
|
-
runWrapper?: (cb: () => any) => any;
|
|
23
23
|
run: (task: ListrTaskWrapper<any, any, any>, data: T[K]) => Promise<void | ListrTask[] | Listr | undefined> | void | undefined | ListrTask[] | Listr;
|
|
24
24
|
exitOnError?: boolean;
|
|
25
25
|
enabled?: boolean;
|
|
@@ -43,6 +43,7 @@ export declare class Listr3<T extends Listr3Context> extends Listr<void, "defaul
|
|
|
43
43
|
readonly $options: {
|
|
44
44
|
streams?: StdStreams;
|
|
45
45
|
progressManager?: ProgressManager;
|
|
46
|
+
gargabeCollector?: GargabeCollector;
|
|
46
47
|
};
|
|
47
48
|
readonly resultMap: Record<string, Listr3TaskResult<T>>;
|
|
48
49
|
readonly resultList: Listr3TaskResult<T>[];
|
|
@@ -51,6 +52,7 @@ export declare class Listr3<T extends Listr3Context> extends Listr<void, "defaul
|
|
|
51
52
|
constructor($options: {
|
|
52
53
|
streams?: StdStreams;
|
|
53
54
|
progressManager?: ProgressManager;
|
|
55
|
+
gargabeCollector?: GargabeCollector;
|
|
54
56
|
});
|
|
55
57
|
private serializeKeyIndex;
|
|
56
58
|
private createResultIndex;
|
package/lib/utils/list.js
CHANGED
|
@@ -89,9 +89,7 @@ class Listr3 extends listr2_1.Listr {
|
|
|
89
89
|
const timer = (0, date_1.createTimer)();
|
|
90
90
|
if (title)
|
|
91
91
|
try {
|
|
92
|
-
const runResult = item.
|
|
93
|
-
? await item.runWrapper(async () => await item.run(task, result.data))
|
|
94
|
-
: await item.run(task, result.data);
|
|
92
|
+
const runResult = await item.run(task, result.data);
|
|
95
93
|
if (title.completed)
|
|
96
94
|
task.title = title.completed;
|
|
97
95
|
return Array.isArray(runResult)
|
|
@@ -153,6 +151,7 @@ class Listr3 extends listr2_1.Listr {
|
|
|
153
151
|
throw error;
|
|
154
152
|
}
|
|
155
153
|
finally {
|
|
154
|
+
await this.$options.gargabeCollector?.dispose();
|
|
156
155
|
dispose();
|
|
157
156
|
}
|
|
158
157
|
}
|
package/lib/utils/mysql.js
CHANGED
|
@@ -62,8 +62,9 @@ async function createMysqlCli(options) {
|
|
|
62
62
|
`user = "${options.username}"`,
|
|
63
63
|
`password = "${password}"`,
|
|
64
64
|
];
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
const path = (0, path_1.join)(dir, "mysql.conf");
|
|
66
|
+
await (0, promises_1.writeFile)(path, data.join("\n"));
|
|
67
|
+
return (sqlConfigPath = path);
|
|
67
68
|
}
|
|
68
69
|
async function args() {
|
|
69
70
|
return [`--defaults-file=${await createSqlConfig()}`];
|
package/lib/utils/progress.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import { Timer } from "./date";
|
|
3
4
|
export type BasicProgress = {
|
|
4
5
|
percent: number;
|
|
@@ -35,6 +36,7 @@ export declare class ProgressManager {
|
|
|
35
36
|
protected interval: Timer | undefined;
|
|
36
37
|
protected intervalMs: number;
|
|
37
38
|
protected keydownListener: ((data: Buffer | undefined) => void) | undefined;
|
|
39
|
+
protected pendingProgress: Progress | undefined;
|
|
38
40
|
readonly tty: Exclude<ProgressTty, "auto">;
|
|
39
41
|
readonly mode: Exclude<ProgressMode, "auto" | `interval:${number}`>;
|
|
40
42
|
constructor(options: {
|
|
@@ -51,7 +53,12 @@ export declare class ProgressManager {
|
|
|
51
53
|
elapsed(): number;
|
|
52
54
|
start(): void;
|
|
53
55
|
dispose(): void;
|
|
54
|
-
|
|
56
|
+
create(input: ((text: string) => void) | {
|
|
57
|
+
output: string;
|
|
58
|
+
}, delay?: number): Disposable & {
|
|
59
|
+
update: (progress: Progress) => void;
|
|
60
|
+
};
|
|
61
|
+
renderProgress(progress: Progress, force?: boolean): string | undefined;
|
|
55
62
|
}
|
|
56
63
|
export declare function renderProgress(progress: Progress, bar?: boolean): string[];
|
|
57
64
|
export declare function renderProgressStats(stats: ProgressStats, progressBar?: boolean): string;
|