@datatruck/cli 0.34.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/repositories/ResticRepository.js +1 -1
- package/lib/tasks/GitTask.js +32 -50
- package/lib/tasks/MariadbTask.js +43 -56
- package/lib/tasks/MssqlTask.js +5 -11
- package/lib/tasks/MysqlDumpTask.js +4 -4
- package/lib/tasks/PostgresqlDumpTask.d.ts +1 -1
- package/lib/tasks/PostgresqlDumpTask.js +9 -32
- package/lib/tasks/SqlDumpTaskAbstract.d.ts +1 -2
- package/lib/tasks/SqlDumpTaskAbstract.js +1 -1
- package/lib/utils/Git.d.ts +9 -7
- package/lib/utils/Git.js +30 -29
- package/lib/utils/Restic.d.ts +10 -9
- package/lib/utils/Restic.js +72 -82
- package/lib/utils/async-process.d.ts +66 -0
- package/lib/utils/async-process.js +237 -0
- package/lib/utils/async.d.ts +3 -5
- package/lib/utils/async.js +2 -2
- package/lib/utils/datatruck/cron-server.js +2 -2
- package/lib/utils/fs.d.ts +7 -2
- package/lib/utils/fs.js +0 -1
- package/lib/utils/mysql.d.ts +8 -10
- package/lib/utils/mysql.js +60 -79
- package/lib/utils/process.d.ts +3 -92
- package/lib/utils/process.js +7 -311
- package/lib/utils/spawnSteps.js +9 -10
- package/lib/utils/tar.js +29 -49
- package/package.json +1 -1
|
@@ -316,7 +316,7 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
316
316
|
await restic.restore({
|
|
317
317
|
id: snapshot.originalId,
|
|
318
318
|
target: restorePath,
|
|
319
|
-
onStream:
|
|
319
|
+
onStream: (streamData) => {
|
|
320
320
|
if (streamData.message_type === "restore-status") {
|
|
321
321
|
const current = Math.min(streamData.total_bytes, snapshot.size);
|
|
322
322
|
data.onProgress({
|
package/lib/tasks/GitTask.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GitTask = exports.gitTaskName = void 0;
|
|
4
|
+
const async_process_1 = require("../utils/async-process");
|
|
4
5
|
const cli_1 = require("../utils/cli");
|
|
5
6
|
const fs_1 = require("../utils/fs");
|
|
6
7
|
const math_1 = require("../utils/math");
|
|
7
|
-
const process_1 = require("../utils/process");
|
|
8
8
|
const temp_1 = require("../utils/temp");
|
|
9
9
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
10
10
|
const assert_1 = require("assert");
|
|
@@ -12,7 +12,6 @@ const fs_2 = require("fs");
|
|
|
12
12
|
const promises_1 = require("fs/promises");
|
|
13
13
|
const micromatch_1 = require("micromatch");
|
|
14
14
|
const path_1 = require("path");
|
|
15
|
-
const readline_1 = require("readline");
|
|
16
15
|
exports.gitTaskName = "git";
|
|
17
16
|
class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
18
17
|
verbose;
|
|
@@ -34,10 +33,9 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
34
33
|
description: "Creating bundle",
|
|
35
34
|
},
|
|
36
35
|
});
|
|
37
|
-
await
|
|
36
|
+
await async_process_1.AsyncProcess.exec(this.command, ["bundle", "create", bundlePath, "--all"], {
|
|
38
37
|
cwd: path,
|
|
39
|
-
|
|
40
|
-
log: this.verbose,
|
|
38
|
+
$log: this.verbose,
|
|
41
39
|
});
|
|
42
40
|
// Config
|
|
43
41
|
if (this.config.includeConfig ?? true) {
|
|
@@ -70,48 +68,33 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
70
68
|
continue;
|
|
71
69
|
option.pathsPath = (0, path_1.join)(snapshotPath, `repo.${option.name}-paths.txt`);
|
|
72
70
|
const stream = (0, fs_2.createWriteStream)(option.pathsPath);
|
|
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
|
-
found = (0, micromatch_1.isMatch)(path, option.include);
|
|
101
|
-
}
|
|
102
|
-
if (found) {
|
|
103
|
-
total++;
|
|
104
|
-
stream.write(`${path}\n`);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
await new Promise((resolve) => stream.end(resolve));
|
|
112
|
-
if (streamError)
|
|
113
|
-
throw streamError;
|
|
114
|
-
}
|
|
71
|
+
const p = new async_process_1.AsyncProcess(this.command, [
|
|
72
|
+
"-c",
|
|
73
|
+
"core.quotepath=off",
|
|
74
|
+
"ls-files",
|
|
75
|
+
...option.argv,
|
|
76
|
+
"--exclude-standard",
|
|
77
|
+
], {
|
|
78
|
+
cwd: data.package.path,
|
|
79
|
+
$log: this.verbose,
|
|
80
|
+
});
|
|
81
|
+
await Promise.all([
|
|
82
|
+
p.stdout.parseLines((path) => {
|
|
83
|
+
let found = false;
|
|
84
|
+
if (option.include === true) {
|
|
85
|
+
found = true;
|
|
86
|
+
}
|
|
87
|
+
else if (option.include) {
|
|
88
|
+
found = (0, micromatch_1.isMatch)(path, option.include);
|
|
89
|
+
}
|
|
90
|
+
if (found) {
|
|
91
|
+
total++;
|
|
92
|
+
stream.write(`${path}\n`);
|
|
93
|
+
}
|
|
94
|
+
}),
|
|
95
|
+
p.child.on("close", () => stream.end()),
|
|
96
|
+
(0, fs_1.waitForClose)(stream),
|
|
97
|
+
]);
|
|
115
98
|
}
|
|
116
99
|
// Copy
|
|
117
100
|
for (const option of lsFilesConfig) {
|
|
@@ -176,10 +159,9 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
176
159
|
};
|
|
177
160
|
// Bundle
|
|
178
161
|
const bundlePath = (0, path_1.join)(snapshotPath, "repo.bundle");
|
|
179
|
-
await
|
|
162
|
+
await async_process_1.AsyncProcess.exec(this.command, ["clone", bundlePath, "."], {
|
|
180
163
|
cwd: restorePath,
|
|
181
|
-
|
|
182
|
-
log: this.verbose,
|
|
164
|
+
$log: this.verbose,
|
|
183
165
|
});
|
|
184
166
|
await incrementProgress();
|
|
185
167
|
// Config
|
package/lib/tasks/MariadbTask.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MariadbTask = exports.mariadbTaskName = void 0;
|
|
4
|
+
const async_process_1 = require("../utils/async-process");
|
|
4
5
|
const cli_1 = require("../utils/cli");
|
|
5
6
|
const fs_1 = require("../utils/fs");
|
|
6
7
|
const math_1 = require("../utils/math");
|
|
7
|
-
const process_1 = require("../utils/process");
|
|
8
8
|
const tar_1 = require("../utils/tar");
|
|
9
9
|
const temp_1 = require("../utils/temp");
|
|
10
10
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
@@ -92,15 +92,15 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
92
92
|
await (0, fs_1.forEachFile)(sourcePath, () => {
|
|
93
93
|
total++;
|
|
94
94
|
});
|
|
95
|
-
let p1;
|
|
96
95
|
let lastLineText;
|
|
96
|
+
const controller = new AbortController();
|
|
97
97
|
const pathRegex = /((Copying|Streaming) .+) to/;
|
|
98
98
|
const onData = async (line) => {
|
|
99
99
|
const { text } = parseLine(line);
|
|
100
100
|
lastLineText = text;
|
|
101
101
|
if (line.includes("[ERROR] InnoDB: Unsupported redo log format.") ||
|
|
102
102
|
line.includes("Error: cannot read redo log header")) {
|
|
103
|
-
|
|
103
|
+
controller.abort();
|
|
104
104
|
}
|
|
105
105
|
else {
|
|
106
106
|
const matches = pathRegex.exec(text);
|
|
@@ -121,41 +121,34 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
121
121
|
const stats = { xbFiles: total };
|
|
122
122
|
await (0, promises_1.writeFile)((0, path_1.join)(snapshotPath, "stats.dtt.json"), JSON.stringify(stats));
|
|
123
123
|
if (compress) {
|
|
124
|
-
const
|
|
125
|
-
|
|
124
|
+
const fileStream = (0, fs_2.createWriteStream)((0, path_1.join)(snapshotPath, "db.xb.gz"));
|
|
125
|
+
const dumpProcess = new async_process_1.AsyncProcess(command, args, {
|
|
126
126
|
$log: {
|
|
127
127
|
exec: this.verbose,
|
|
128
128
|
stderr: this.verbose,
|
|
129
129
|
},
|
|
130
|
-
$
|
|
131
|
-
|
|
132
|
-
onData,
|
|
133
|
-
},
|
|
134
|
-
$onExitCode: (code) => `Exit code: ${code} - ${lastLineText}`,
|
|
130
|
+
$controller: controller,
|
|
131
|
+
$exitCode: (code) => `Exit code: ${code} - ${lastLineText}`,
|
|
135
132
|
});
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
const compressProcess = new async_process_1.AsyncProcess(compress.command, compress.args);
|
|
134
|
+
await Promise.all([
|
|
135
|
+
dumpProcess.stdout.pipe(compressProcess.stdin),
|
|
136
|
+
dumpProcess.stderr.parseLines(onData),
|
|
137
|
+
compressProcess.stdout.pipe(fileStream),
|
|
138
|
+
]);
|
|
140
139
|
}
|
|
141
140
|
else {
|
|
142
|
-
|
|
141
|
+
const dumpProcess = new async_process_1.AsyncProcess(command, args, {
|
|
143
142
|
$log: this.verbose,
|
|
144
|
-
$
|
|
145
|
-
|
|
146
|
-
onData,
|
|
147
|
-
},
|
|
148
|
-
$stderr: {
|
|
149
|
-
parseLines: true,
|
|
150
|
-
onData,
|
|
151
|
-
},
|
|
152
|
-
$onExitCode: (code) => `Exit code: ${code} - ${lastLineText}`,
|
|
153
|
-
});
|
|
154
|
-
await p1;
|
|
155
|
-
await (0, process_1.exec)(command, [`--prepare`, `--target-dir=${snapshotPath}`], undefined, {
|
|
156
|
-
log: this.verbose,
|
|
157
|
-
stderr: { onData: () => { } },
|
|
143
|
+
$controller: controller,
|
|
144
|
+
$exitCode: (code) => `Exit code: ${code} - ${lastLineText}`,
|
|
158
145
|
});
|
|
146
|
+
await Promise.all([
|
|
147
|
+
dumpProcess.stdout.parseLines(onData),
|
|
148
|
+
dumpProcess.stderr.parseLines(onData),
|
|
149
|
+
]);
|
|
150
|
+
const prepareProcess = new async_process_1.AsyncProcess(command, [`--prepare`, `--target-dir=${snapshotPath}`], { $log: this.verbose });
|
|
151
|
+
await prepareProcess.waitForClose();
|
|
159
152
|
}
|
|
160
153
|
return { snapshotPath };
|
|
161
154
|
}
|
|
@@ -230,29 +223,25 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
230
223
|
});
|
|
231
224
|
let currentXbFiles = 0;
|
|
232
225
|
const { parallel } = normalizeConfig({ parallel: this.config.parallel });
|
|
233
|
-
const p1 =
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
},
|
|
253
|
-
});
|
|
254
|
-
xbStream.pipe(p1.stdin, { end: true });
|
|
255
|
-
await Promise.all([(0, fs_1.waitForClose)(xbStream), p1]);
|
|
226
|
+
const p1 = new async_process_1.AsyncProcess("mbstream", ["-x", "-C", snapshotPath, "-v", "-p", parallel], { $log: this.verbose });
|
|
227
|
+
await Promise.all([
|
|
228
|
+
p1.stdin.pipe(xbStream),
|
|
229
|
+
p1.stderr.parseLines((line) => {
|
|
230
|
+
const { text: path } = parseLine(line);
|
|
231
|
+
data.onProgress({
|
|
232
|
+
absolute,
|
|
233
|
+
relative: {
|
|
234
|
+
payload: path,
|
|
235
|
+
format: "amount",
|
|
236
|
+
current: ++currentXbFiles,
|
|
237
|
+
total: stats?.xbFiles,
|
|
238
|
+
percent: stats?.xbFiles
|
|
239
|
+
? (0, math_1.progressPercent)(stats.xbFiles, currentXbFiles)
|
|
240
|
+
: undefined,
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
}),
|
|
244
|
+
]);
|
|
256
245
|
}
|
|
257
246
|
// Prepare
|
|
258
247
|
absolute.current++;
|
|
@@ -262,10 +251,8 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
262
251
|
data.onProgress({
|
|
263
252
|
absolute,
|
|
264
253
|
});
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
stderr: { onData: () => { } },
|
|
268
|
-
});
|
|
254
|
+
const p = new async_process_1.AsyncProcess(this.command, [`--prepare`, `--target-dir=${snapshotPath}`], { $log: this.verbose });
|
|
255
|
+
await p.waitForClose();
|
|
269
256
|
}
|
|
270
257
|
await reloadFiles();
|
|
271
258
|
removeFiles.push(...files.filter((file) => file.startsWith("ib_logfile")));
|
package/lib/tasks/MssqlTask.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MssqlTask = exports.mssqlTaskName = void 0;
|
|
4
|
+
const async_process_1 = require("../utils/async-process");
|
|
4
5
|
const config_1 = require("../utils/datatruck/config");
|
|
5
6
|
const error_1 = require("../utils/datatruck/error");
|
|
6
7
|
const fs_1 = require("../utils/fs");
|
|
7
|
-
const process_1 = require("../utils/process");
|
|
8
8
|
const temp_1 = require("../utils/temp");
|
|
9
9
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
10
10
|
const promises_1 = require("fs/promises");
|
|
@@ -18,7 +18,7 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
|
18
18
|
return this.config.command ?? "sqlcmd";
|
|
19
19
|
}
|
|
20
20
|
async exec(query) {
|
|
21
|
-
const
|
|
21
|
+
const stdout = await async_process_1.AsyncProcess.stdout(this.command, [
|
|
22
22
|
...(this.config.hostname ? ["-S", this.config.hostname] : []),
|
|
23
23
|
...(this.config.username ? ["-U", this.config.username] : []),
|
|
24
24
|
...(this.config.passwordFile
|
|
@@ -32,16 +32,10 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
|
32
32
|
"999",
|
|
33
33
|
"-Q",
|
|
34
34
|
`SET nocount ON; ${query.replace(/[\n\t]/g, " ")}`,
|
|
35
|
-
],
|
|
36
|
-
log: this.verbose,
|
|
37
|
-
stderr: {
|
|
38
|
-
toExitCode: true,
|
|
39
|
-
},
|
|
40
|
-
stdout: {
|
|
41
|
-
save: true,
|
|
42
|
-
},
|
|
35
|
+
], {
|
|
36
|
+
$log: this.verbose,
|
|
43
37
|
});
|
|
44
|
-
return
|
|
38
|
+
return stdout
|
|
45
39
|
.split(/\n/g)
|
|
46
40
|
.map((row) => row.split(","))
|
|
47
41
|
.filter((row) => row.length);
|
|
@@ -80,7 +80,7 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
80
80
|
sharedPath: tableSharedPath,
|
|
81
81
|
items: [tableName],
|
|
82
82
|
database: this.config.database,
|
|
83
|
-
|
|
83
|
+
controller,
|
|
84
84
|
});
|
|
85
85
|
const files = await (0, promises_1.readdir)(tableSharedPath);
|
|
86
86
|
const schemaFile = `${tableName}.sql`;
|
|
@@ -106,7 +106,7 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
106
106
|
output: outPath,
|
|
107
107
|
items: [tableName],
|
|
108
108
|
database: this.config.database,
|
|
109
|
-
|
|
109
|
+
controller,
|
|
110
110
|
...(concurrency === 1 && {
|
|
111
111
|
onProgress(progress) {
|
|
112
112
|
data.onProgress({
|
|
@@ -256,7 +256,7 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
256
256
|
await sql.importFile({
|
|
257
257
|
path,
|
|
258
258
|
database: database.name,
|
|
259
|
-
|
|
259
|
+
controller,
|
|
260
260
|
});
|
|
261
261
|
}
|
|
262
262
|
finally {
|
|
@@ -306,7 +306,7 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
306
306
|
path: csvFile,
|
|
307
307
|
database: database.name,
|
|
308
308
|
table: tableName,
|
|
309
|
-
|
|
309
|
+
controller,
|
|
310
310
|
});
|
|
311
311
|
}
|
|
312
312
|
finally {
|
|
@@ -5,7 +5,7 @@ export declare class PostgresqlDumpTask extends SqlDumpTaskAbstract<PostgresqlDu
|
|
|
5
5
|
buildConnectionArgs(database?: string): Promise<string[]>;
|
|
6
6
|
onDatabaseIsEmpty(name: string): Promise<boolean>;
|
|
7
7
|
onCreateDatabase(database: TargetDatabase): Promise<void>;
|
|
8
|
-
onExecQuery(query: string): Promise<
|
|
8
|
+
onExecQuery(query: string): Promise<string>;
|
|
9
9
|
onFetchTableNames(database: string): Promise<string[]>;
|
|
10
10
|
onExportTables(tableNames: string[], output: string, onProgress: (progress: {
|
|
11
11
|
totalBytes: number;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PostgresqlDumpTask = exports.postgresqlDumpTaskName = void 0;
|
|
4
|
-
const
|
|
4
|
+
const async_process_1 = require("../utils/async-process");
|
|
5
5
|
const SqlDumpTaskAbstract_1 = require("./SqlDumpTaskAbstract");
|
|
6
|
-
const fs_1 = require("fs");
|
|
7
6
|
const path_1 = require("path");
|
|
8
7
|
exports.postgresqlDumpTaskName = "postgresql-dump";
|
|
9
8
|
class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
@@ -41,20 +40,12 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
41
40
|
await this.onExecQuery(query);
|
|
42
41
|
}
|
|
43
42
|
async onExecQuery(query) {
|
|
44
|
-
return await
|
|
43
|
+
return await async_process_1.AsyncProcess.stdout("psql", [
|
|
45
44
|
...(await this.buildConnectionArgs()),
|
|
46
45
|
"-t",
|
|
47
46
|
"-c",
|
|
48
47
|
query.replace(/\s{1,}/g, " "),
|
|
49
|
-
],
|
|
50
|
-
log: this.verbose,
|
|
51
|
-
stderr: {
|
|
52
|
-
toExitCode: true,
|
|
53
|
-
},
|
|
54
|
-
stdout: {
|
|
55
|
-
save: true,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
48
|
+
], { $log: this.verbose });
|
|
58
49
|
}
|
|
59
50
|
async onFetchTableNames(database) {
|
|
60
51
|
return await this.fetchValues(`
|
|
@@ -70,31 +61,17 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
70
61
|
`);
|
|
71
62
|
}
|
|
72
63
|
async onExportTables(tableNames, output, onProgress) {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}),
|
|
79
|
-
(0, process_1.exec)("pg_dump", [
|
|
80
|
-
...(await this.buildConnectionArgs(this.config.database)),
|
|
81
|
-
...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
|
|
82
|
-
], null, {
|
|
83
|
-
pipe: { stream, onWriteProgress: onProgress },
|
|
84
|
-
stderr: {
|
|
85
|
-
toExitCode: true,
|
|
86
|
-
},
|
|
87
|
-
log: this.verbose,
|
|
88
|
-
}),
|
|
89
|
-
]);
|
|
64
|
+
const dumpProcess = new async_process_1.AsyncProcess("pg_dump", [
|
|
65
|
+
...(await this.buildConnectionArgs(this.config.database)),
|
|
66
|
+
...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
|
|
67
|
+
], { $log: this.verbose });
|
|
68
|
+
await dumpProcess.stdout.pipe(output, onProgress);
|
|
90
69
|
}
|
|
91
70
|
async onExportStoredPrograms() {
|
|
92
71
|
throw new Error(`Method not implemented: onExportStoredPrograms`);
|
|
93
72
|
}
|
|
94
73
|
async onImport(path, database) {
|
|
95
|
-
await
|
|
96
|
-
log: this.verbose,
|
|
97
|
-
});
|
|
74
|
+
await async_process_1.AsyncProcess.exec("psql", [...(await this.buildConnectionArgs(database)), "-f", (0, path_1.normalize)(path)], { $log: this.verbose });
|
|
98
75
|
}
|
|
99
76
|
}
|
|
100
77
|
exports.PostgresqlDumpTask = PostgresqlDumpTask;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { exec } from "../utils/process";
|
|
2
1
|
import { TaskBackupData, TaskPrepareRestoreData, TaskRestoreData, TaskAbstract } from "./TaskAbstract";
|
|
3
2
|
export type TargetDatabase = {
|
|
4
3
|
name: string;
|
|
@@ -29,7 +28,7 @@ export declare abstract class SqlDumpTaskAbstract<TConfig extends SqlDumpTaskCon
|
|
|
29
28
|
abstract onCreateDatabase(database: TargetDatabase): Promise<void>;
|
|
30
29
|
abstract onDatabaseIsEmpty(databaseName: string): Promise<boolean>;
|
|
31
30
|
abstract onFetchTableNames(database: string): Promise<string[]>;
|
|
32
|
-
abstract onExecQuery(query: string):
|
|
31
|
+
abstract onExecQuery(query: string): Promise<string>;
|
|
33
32
|
abstract onExportTables(tableNames: string[], output: string, onProgress: (data: {
|
|
34
33
|
totalBytes: number;
|
|
35
34
|
}) => void): Promise<void>;
|
|
@@ -56,7 +56,7 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
56
56
|
}
|
|
57
57
|
async fetchValues(query) {
|
|
58
58
|
const result = await this.onExecQuery(query);
|
|
59
|
-
return result.
|
|
59
|
+
return result.split(/\r?\n/).reduce((result, value) => {
|
|
60
60
|
value = value.trim();
|
|
61
61
|
if (value.length)
|
|
62
62
|
result.push(value);
|
package/lib/utils/Git.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AsyncProcessOptions } from "./async-process";
|
|
2
2
|
export declare class Git {
|
|
3
3
|
readonly options: {
|
|
4
4
|
dir: string;
|
|
@@ -8,22 +8,24 @@ export declare class Git {
|
|
|
8
8
|
dir: string;
|
|
9
9
|
log?: boolean;
|
|
10
10
|
});
|
|
11
|
-
|
|
11
|
+
private createProcess;
|
|
12
|
+
exec(args: string[], options?: AsyncProcessOptions): Promise<number>;
|
|
13
|
+
private stdout;
|
|
12
14
|
canBeInit(repo: string): Promise<boolean>;
|
|
13
15
|
clone(options: {
|
|
14
16
|
repo: string;
|
|
15
17
|
branch?: string;
|
|
16
18
|
orphan?: boolean;
|
|
17
|
-
}): Promise<
|
|
19
|
+
}): Promise<void>;
|
|
18
20
|
checkout(options: {
|
|
19
21
|
branchName: string;
|
|
20
22
|
orphan?: boolean;
|
|
21
|
-
}): Promise<
|
|
23
|
+
}): Promise<void>;
|
|
22
24
|
checkBranch(options: {
|
|
23
25
|
name: string;
|
|
24
26
|
repo?: string;
|
|
25
27
|
}): Promise<boolean>;
|
|
26
|
-
removeAll(): Promise<
|
|
28
|
+
removeAll(): Promise<void>;
|
|
27
29
|
haveChanges(): Promise<boolean>;
|
|
28
30
|
fetchCommitId(tag: string): Promise<string>;
|
|
29
31
|
getTags(names?: string[]): Promise<{
|
|
@@ -31,8 +33,8 @@ export declare class Git {
|
|
|
31
33
|
message?: string | undefined;
|
|
32
34
|
}[]>;
|
|
33
35
|
addTag(name: string, message?: string): Promise<void>;
|
|
34
|
-
pushTags(): Promise<
|
|
36
|
+
pushTags(): Promise<void>;
|
|
35
37
|
push(options: {
|
|
36
38
|
branchName: string;
|
|
37
|
-
}): Promise<
|
|
39
|
+
}): Promise<void>;
|
|
38
40
|
}
|
package/lib/utils/Git.js
CHANGED
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Git = void 0;
|
|
4
|
+
const async_process_1 = require("./async-process");
|
|
4
5
|
const fs_1 = require("./fs");
|
|
5
|
-
const process_1 = require("./process");
|
|
6
6
|
class Git {
|
|
7
7
|
options;
|
|
8
8
|
constructor(options) {
|
|
9
9
|
this.options = options;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
return
|
|
13
|
-
log: this.options.log,
|
|
14
|
-
|
|
11
|
+
createProcess(args, options = {}) {
|
|
12
|
+
return new async_process_1.AsyncProcess("git", args, {
|
|
13
|
+
$log: this.options.log,
|
|
14
|
+
cwd: this.options.dir,
|
|
15
|
+
...options,
|
|
15
16
|
});
|
|
16
17
|
}
|
|
18
|
+
async exec(args, options) {
|
|
19
|
+
return await this.createProcess(args, options).waitForClose();
|
|
20
|
+
}
|
|
21
|
+
async stdout(args, options) {
|
|
22
|
+
return await this.createProcess(args, options).stdout.fetch();
|
|
23
|
+
}
|
|
17
24
|
async canBeInit(repo) {
|
|
18
25
|
return ((0, fs_1.isLocalDir)(repo) &&
|
|
19
26
|
(!(await (0, fs_1.existsDir)(repo)) || !(await (0, fs_1.readDir)(repo)).length));
|
|
20
27
|
}
|
|
21
28
|
async clone(options) {
|
|
22
|
-
|
|
29
|
+
await this.exec([
|
|
23
30
|
"clone",
|
|
24
31
|
...(/^\w+\:\/\//.test(options.repo) ? ["--depth=1"] : []),
|
|
25
32
|
...(options.orphan ? ["--orphan"] : []),
|
|
@@ -31,42 +38,41 @@ class Git {
|
|
|
31
38
|
]);
|
|
32
39
|
}
|
|
33
40
|
async checkout(options) {
|
|
34
|
-
|
|
41
|
+
await this.exec([
|
|
35
42
|
"checkout",
|
|
36
43
|
...(options.orphan ? ["--orphan"] : []),
|
|
37
44
|
options.branchName,
|
|
38
45
|
]);
|
|
39
46
|
}
|
|
40
47
|
async checkBranch(options) {
|
|
41
|
-
const
|
|
48
|
+
const stdout = await this.stdout([
|
|
42
49
|
"ls-remote",
|
|
43
50
|
"--exit-code",
|
|
44
51
|
...(options.repo ? [options.repo] : ["--heads", "origin"]),
|
|
45
52
|
], {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
...(options.repo && {
|
|
54
|
+
cwd: undefined,
|
|
55
|
+
}),
|
|
56
|
+
cwd: options.repo ? undefined : this.options.dir,
|
|
57
|
+
$exitCode: false,
|
|
58
|
+
});
|
|
59
|
+
return stdout
|
|
50
60
|
.split(/\r?\n/g)
|
|
51
61
|
.some((line) => line.endsWith(`refs/heads/${options.name}`));
|
|
52
62
|
}
|
|
53
63
|
async removeAll() {
|
|
54
|
-
|
|
64
|
+
await this.exec(["rm", "--force", "--ignore-unmatch", "*"]);
|
|
55
65
|
}
|
|
56
66
|
async haveChanges() {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
});
|
|
60
|
-
return !!statusResult.stdout.trim().length;
|
|
67
|
+
const stdout = await this.stdout(["status", "-s"]);
|
|
68
|
+
return !!stdout.trim().length;
|
|
61
69
|
}
|
|
62
70
|
async fetchCommitId(tag) {
|
|
63
|
-
return (await this.
|
|
71
|
+
return (await this.stdout(["rev-list", "-n", "1", tag])).trim();
|
|
64
72
|
}
|
|
65
73
|
async getTags(names) {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
return result.stdout.split(/\r?\n/).reduce((result, value) => {
|
|
74
|
+
const stdout = await this.stdout(["tag", "-n", ...(names ?? [])]);
|
|
75
|
+
return stdout.split(/\r?\n/).reduce((result, value) => {
|
|
70
76
|
value = value.trim();
|
|
71
77
|
if (!value.length)
|
|
72
78
|
return result;
|
|
@@ -91,15 +97,10 @@ class Git {
|
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
async pushTags() {
|
|
94
|
-
|
|
100
|
+
await this.exec(["push", "--tags"]);
|
|
95
101
|
}
|
|
96
102
|
async push(options) {
|
|
97
|
-
|
|
98
|
-
"push",
|
|
99
|
-
"--progress",
|
|
100
|
-
"origin",
|
|
101
|
-
options.branchName,
|
|
102
|
-
]);
|
|
103
|
+
await this.exec(["push", "--progress", "origin", options.branchName]);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
exports.Git = Git;
|