@datatruck/cli 0.3.2 → 0.6.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/Action/BackupAction.js +1 -0
- package/Action/ConfigAction.d.ts +6 -1
- package/Action/ConfigAction.js +17 -1
- package/Action/InitAction.js +3 -0
- package/Action/PruneAction.js +1 -1
- package/Action/RestoreAction.js +4 -1
- package/Action/SnapshotsAction.d.ts +2 -1
- package/Action/SnapshotsAction.js +6 -1
- package/CHANGELOG.md +28 -0
- package/Command/BackupCommand.js +1 -5
- package/Command/BackupSessionsCommand.js +1 -5
- package/Command/CommandAbstract.d.ts +2 -1
- package/Command/ConfigCommand.js +1 -5
- package/Command/InitCommand.js +1 -5
- package/Command/PruneCommand.js +1 -5
- package/Command/RestoreCommand.js +1 -5
- package/Command/RestoreSessionsCommand.js +1 -5
- package/Command/SnapshotsCommand.js +1 -5
- package/Config/Config.d.ts +1 -0
- package/Config/Config.js +1 -0
- package/Config/RepositoryConfig.d.ts +4 -0
- package/Config/RepositoryConfig.js +19 -0
- package/Repository/GitRepository.js +2 -3
- package/Repository/LocalRepository.d.ts +4 -0
- package/Repository/LocalRepository.js +38 -37
- package/Repository/RepositoryAbstract.d.ts +4 -4
- package/Repository/ResticRepository.d.ts +7 -3
- package/Repository/ResticRepository.js +33 -12
- package/SessionDriver/ConsoleSessionDriver.js +12 -11
- package/Task/GitTask.d.ts +4 -0
- package/Task/GitTask.js +28 -29
- package/Task/MariadbTask.js +26 -14
- package/Task/MssqlTask.js +1 -2
- package/Task/TaskAbstract.d.ts +4 -4
- package/cli.js +18 -1
- package/config.schema.json +61 -3
- package/globalData.d.ts +5 -0
- package/globalData.js +7 -0
- package/package.json +2 -2
- package/util/GitUtil.js +2 -2
- package/util/ResticUtil.js +1 -2
- package/util/datatruck/config-util.d.ts +4 -1
- package/util/datatruck/config-util.js +11 -1
- package/util/fs-util.d.ts +33 -0
- package/util/fs-util.js +78 -7
|
@@ -18,10 +18,22 @@ const path_1 = require("path");
|
|
|
18
18
|
exports.resticRepositoryName = "restic";
|
|
19
19
|
exports.resticRepositoryDefinition = {
|
|
20
20
|
type: "object",
|
|
21
|
-
required: ["
|
|
21
|
+
required: ["password", "repository"],
|
|
22
22
|
additionalProperties: false,
|
|
23
23
|
properties: {
|
|
24
|
-
|
|
24
|
+
password: {
|
|
25
|
+
anyOf: [
|
|
26
|
+
{ type: "string" },
|
|
27
|
+
{
|
|
28
|
+
type: "object",
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
required: ["path"],
|
|
31
|
+
properties: {
|
|
32
|
+
path: { type: "string" },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
25
37
|
repository: {
|
|
26
38
|
type: "object",
|
|
27
39
|
additionalProperties: false,
|
|
@@ -59,7 +71,9 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
59
71
|
if (this.env)
|
|
60
72
|
return this.env;
|
|
61
73
|
return (this.env = {
|
|
62
|
-
|
|
74
|
+
...(typeof this.config.password === "string"
|
|
75
|
+
? { RESTIC_PASSWORD: this.config.password }
|
|
76
|
+
: { RESTIC_PASSWORD_FILE: (0, path_1.resolve)(this.config.password.path) }),
|
|
63
77
|
RESTIC_REPOSITORY: await ResticUtil_1.ResticUtil.formatRepository(this.config.repository),
|
|
64
78
|
});
|
|
65
79
|
}
|
|
@@ -176,6 +190,9 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
176
190
|
});
|
|
177
191
|
if (data.options.verbose)
|
|
178
192
|
(0, cli_util_1.logExec)(`Writing paths lists`);
|
|
193
|
+
await data.onProgress({
|
|
194
|
+
step: "Writing excluded paths list...",
|
|
195
|
+
});
|
|
179
196
|
gitignorePath = await (0, fs_util_1.writeGitIgnoreList)({
|
|
180
197
|
paths: stream,
|
|
181
198
|
});
|
|
@@ -183,12 +200,19 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
183
200
|
if (data.options.tags?.some((tag) => tag.startsWith(ResticRepository.refPrefix)))
|
|
184
201
|
throw new AppError_1.AppError(`Tag prefix is not allowed`);
|
|
185
202
|
const packageTag = ResticRepository.buildSnapshotTag(RepositoryAbstract_1.SnapshotTagEnum.PACKAGE, data.package.name);
|
|
203
|
+
await data.onProgress({
|
|
204
|
+
step: "Fetching last snapshot...",
|
|
205
|
+
});
|
|
186
206
|
const [lastSnapshot] = await restic.snapshots({
|
|
187
207
|
json: true,
|
|
188
208
|
tags: [packageTag],
|
|
189
209
|
latest: 1,
|
|
190
210
|
});
|
|
191
211
|
const nodePkg = (0, fs_util_1.parsePackageFile)();
|
|
212
|
+
let lastProgress;
|
|
213
|
+
await data.onProgress({
|
|
214
|
+
step: "Executing backup action...",
|
|
215
|
+
});
|
|
192
216
|
await restic.backup({
|
|
193
217
|
cwd: sourcePath,
|
|
194
218
|
paths: ["."],
|
|
@@ -209,22 +233,19 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
209
233
|
],
|
|
210
234
|
onStream: async (streamData) => {
|
|
211
235
|
if (streamData.message_type === "status") {
|
|
212
|
-
await data.onProgress({
|
|
213
|
-
total:
|
|
214
|
-
current: streamData.
|
|
215
|
-
? Number((streamData.bytes_done / 1024 / 1024).toFixed(2))
|
|
216
|
-
: 0,
|
|
236
|
+
await data.onProgress((lastProgress = {
|
|
237
|
+
total: streamData.total_files,
|
|
238
|
+
current: streamData.files_done ?? 0,
|
|
217
239
|
percent: Number((streamData.percent_done * 100).toFixed(2)),
|
|
218
240
|
step: streamData.current_files?.join(", ") ?? "-",
|
|
219
|
-
});
|
|
241
|
+
}));
|
|
220
242
|
}
|
|
221
243
|
},
|
|
222
244
|
});
|
|
223
245
|
await data.onProgress({
|
|
224
|
-
|
|
246
|
+
total: lastProgress?.total || 0,
|
|
247
|
+
current: lastProgress?.total || 0,
|
|
225
248
|
percent: 100,
|
|
226
|
-
step: "",
|
|
227
|
-
total: 100,
|
|
228
249
|
});
|
|
229
250
|
}
|
|
230
251
|
async onRestore(data) {
|
|
@@ -82,18 +82,19 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
82
82
|
const parts = [
|
|
83
83
|
`${padding}${message.textPrefix} [${(0, chalk_1.grey)(sessionId)}] ${message.text}`,
|
|
84
84
|
badges,
|
|
85
|
-
...(haveProgressBar
|
|
86
|
-
? [
|
|
87
|
-
(0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressPercent ?? 0, 10)),
|
|
88
|
-
`${message.progressPercent?.toFixed(2)}%`,
|
|
89
|
-
`${message.progressCurrent}/${message.progressTotal}`,
|
|
90
|
-
message.progressStep,
|
|
91
|
-
`${message.progressStepPercent
|
|
92
|
-
? (0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressStepPercent ?? 0, 10))
|
|
93
|
-
: ""}`,
|
|
94
|
-
].filter((v) => !!v?.length)
|
|
95
|
-
: []),
|
|
96
85
|
];
|
|
86
|
+
if (typeof message.progressPercent === "number") {
|
|
87
|
+
parts.push((0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressPercent ?? 0, 10)), `${message.progressPercent?.toFixed(2)}%`);
|
|
88
|
+
}
|
|
89
|
+
if (typeof message.progressCurrent === "number" ||
|
|
90
|
+
typeof message.progressTotal === "number") {
|
|
91
|
+
parts.push(`${message.progressCurrent ?? "?"}/${message.progressTotal ?? "?"}`);
|
|
92
|
+
}
|
|
93
|
+
if (typeof message.progressStep === "string")
|
|
94
|
+
parts.push(message.progressStep);
|
|
95
|
+
if (typeof message.progressStepPercent === "number") {
|
|
96
|
+
parts.push((0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressStepPercent ?? 0, 10)));
|
|
97
|
+
}
|
|
97
98
|
return parts.join(` ${sep} `);
|
|
98
99
|
}
|
|
99
100
|
async onWrite(data) {
|
package/Task/GitTask.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ export declare type GitTaskConfigType = {
|
|
|
18
18
|
* @default true
|
|
19
19
|
*/
|
|
20
20
|
includeConfig?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* @default 1
|
|
23
|
+
*/
|
|
24
|
+
fileCopyConcurrency?: number;
|
|
21
25
|
};
|
|
22
26
|
export declare const gitTaskName = "git";
|
|
23
27
|
export declare const gitTaskDefinition: JSONSchema7;
|
package/Task/GitTask.js
CHANGED
|
@@ -9,7 +9,6 @@ const process_util_1 = require("../util/process-util");
|
|
|
9
9
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
10
10
|
const assert_1 = require("assert");
|
|
11
11
|
const fs_1 = require("fs");
|
|
12
|
-
const fs_extra_1 = require("fs-extra");
|
|
13
12
|
const promises_1 = require("fs/promises");
|
|
14
13
|
const micromatch_1 = require("micromatch");
|
|
15
14
|
const path_1 = require("path");
|
|
@@ -49,6 +48,10 @@ exports.gitTaskDefinition = {
|
|
|
49
48
|
includeConfig: {
|
|
50
49
|
type: "boolean",
|
|
51
50
|
},
|
|
51
|
+
fileCopyConcurrency: {
|
|
52
|
+
type: "integer",
|
|
53
|
+
minimum: 1,
|
|
54
|
+
},
|
|
52
55
|
},
|
|
53
56
|
};
|
|
54
57
|
class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
@@ -69,6 +72,9 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
69
72
|
(0, assert_1.ok)(typeof targetPath === "string");
|
|
70
73
|
// Bundle
|
|
71
74
|
const bundlePath = (0, path_1.join)(targetPath, "repo.bundle");
|
|
75
|
+
await data.onProgress({
|
|
76
|
+
step: "Creating bundle...",
|
|
77
|
+
});
|
|
72
78
|
await (0, process_util_1.exec)(this.command, ["bundle", "create", bundlePath, "--all"], {
|
|
73
79
|
cwd: path,
|
|
74
80
|
}, {
|
|
@@ -152,40 +158,28 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
152
158
|
for (const option of lsFilesConfig) {
|
|
153
159
|
if (!option.include)
|
|
154
160
|
continue;
|
|
155
|
-
const createdPaths = [];
|
|
156
161
|
const outPath = (0, path_1.join)(targetPath, `repo.${option.name}`);
|
|
157
162
|
await (0, fs_util_1.mkdirIfNotExists)(outPath);
|
|
158
163
|
if (data.options.verbose)
|
|
159
164
|
(0, cli_util_1.logExec)(`Copying ${option.name} files to ${outPath}`);
|
|
160
|
-
|
|
161
|
-
input:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
165
|
+
await (0, fs_util_1.cpy)({
|
|
166
|
+
input: {
|
|
167
|
+
type: "pathList",
|
|
168
|
+
path: option.pathsPath,
|
|
169
|
+
basePath: path,
|
|
170
|
+
},
|
|
171
|
+
targetPath: outPath,
|
|
172
|
+
concurrency: this.config.fileCopyConcurrency,
|
|
173
|
+
onPath: async ({ entryPath }) => {
|
|
172
174
|
currentFiles++;
|
|
173
175
|
await data.onProgress({
|
|
174
176
|
total,
|
|
175
177
|
current: currentFiles,
|
|
176
178
|
percent: (0, math_util_1.progressPercent)(total, currentFiles),
|
|
177
|
-
step:
|
|
179
|
+
step: entryPath,
|
|
178
180
|
});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
await (0, promises_1.mkdir)(dir, {
|
|
182
|
-
recursive: true,
|
|
183
|
-
});
|
|
184
|
-
createdPaths.push(dir);
|
|
185
|
-
}
|
|
186
|
-
await (0, promises_1.copyFile)(source, target);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
181
|
+
},
|
|
182
|
+
});
|
|
189
183
|
await (0, promises_1.rm)(option.pathsPath);
|
|
190
184
|
}
|
|
191
185
|
}
|
|
@@ -235,10 +229,15 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
235
229
|
if (await (0, fs_util_1.checkDir)(sourcePath)) {
|
|
236
230
|
if (data.options.verbose)
|
|
237
231
|
(0, cli_util_1.logExec)(`Copying ${name} files to ${restorePath}`);
|
|
238
|
-
await (0,
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
232
|
+
await (0, fs_util_1.cpy)({
|
|
233
|
+
input: {
|
|
234
|
+
type: "glob",
|
|
235
|
+
sourcePath,
|
|
236
|
+
},
|
|
237
|
+
targetPath: restorePath,
|
|
238
|
+
concurrency: this.config.fileCopyConcurrency,
|
|
239
|
+
onPath: async ({ entryPath }) => {
|
|
240
|
+
await incrementProgress(entryPath);
|
|
242
241
|
},
|
|
243
242
|
});
|
|
244
243
|
}
|
package/Task/MariadbTask.js
CHANGED
|
@@ -83,21 +83,30 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
83
83
|
await (0, fs_util_1.forEachFile)(sourcePath, () => {
|
|
84
84
|
total++;
|
|
85
85
|
});
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
let childProcess;
|
|
87
|
+
const onData = async (strLines) => {
|
|
88
|
+
const paths = [];
|
|
89
|
+
const pathRegex = /\[\d{1,}\] \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Copying (.+) to/;
|
|
90
|
+
const lines = strLines.split(/\r?\n/);
|
|
91
|
+
let fatalError = false;
|
|
92
|
+
for (const line of lines) {
|
|
93
|
+
if (line.includes("[ERROR] InnoDB: Unsupported redo log format.") ||
|
|
94
|
+
line.includes("Error: cannot read redo log header")) {
|
|
95
|
+
fatalError = true;
|
|
95
96
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
else {
|
|
98
|
+
const matches = pathRegex.exec(line);
|
|
99
|
+
if (matches) {
|
|
100
|
+
current++;
|
|
101
|
+
paths.push(matches[1]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (fatalError) {
|
|
106
|
+
childProcess.kill();
|
|
107
|
+
}
|
|
108
|
+
else if (paths.length) {
|
|
109
|
+
const path = (0, posix_1.normalize)(paths[0]);
|
|
101
110
|
await data.onProgress({
|
|
102
111
|
current,
|
|
103
112
|
percent: (0, math_util_1.progressPercent)(total, current),
|
|
@@ -108,6 +117,9 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
108
117
|
};
|
|
109
118
|
await (0, process_util_1.exec)(command, args, undefined, {
|
|
110
119
|
log: this.verbose,
|
|
120
|
+
onSpawn: (p) => {
|
|
121
|
+
childProcess = p;
|
|
122
|
+
},
|
|
111
123
|
stdout: {
|
|
112
124
|
onData,
|
|
113
125
|
},
|
package/Task/MssqlTask.js
CHANGED
|
@@ -8,7 +8,6 @@ const fs_util_1 = require("../util/fs-util");
|
|
|
8
8
|
const process_util_1 = require("../util/process-util");
|
|
9
9
|
const TaskAbstract_1 = require("./TaskAbstract");
|
|
10
10
|
const assert_1 = require("assert");
|
|
11
|
-
const fs_extra_1 = require("fs-extra");
|
|
12
11
|
const promises_1 = require("fs/promises");
|
|
13
12
|
const micromatch_1 = require("micromatch");
|
|
14
13
|
const path_1 = require("path");
|
|
@@ -85,7 +84,7 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
|
|
|
85
84
|
const restorePath = data.package.restorePath;
|
|
86
85
|
(0, assert_1.ok)(typeof restorePath === "string");
|
|
87
86
|
await (0, fs_util_1.mkdirIfNotExists)(restorePath);
|
|
88
|
-
const files = await (0,
|
|
87
|
+
const files = await (0, promises_1.readdir)(restorePath);
|
|
89
88
|
for (const file of files) {
|
|
90
89
|
if (!file.endsWith(MssqlTask.SUFFIX))
|
|
91
90
|
continue;
|
package/Task/TaskAbstract.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { RestoreActionOptionsType } from "../Action/RestoreAction";
|
|
|
3
3
|
import { PackageConfigType } from "../Config/PackageConfig";
|
|
4
4
|
import { SnapshotType } from "../Repository/RepositoryAbstract";
|
|
5
5
|
export declare type ProgressDataType = {
|
|
6
|
-
total
|
|
7
|
-
current
|
|
8
|
-
percent
|
|
9
|
-
step
|
|
6
|
+
total?: number;
|
|
7
|
+
current?: number;
|
|
8
|
+
percent?: number;
|
|
9
|
+
step?: string;
|
|
10
10
|
stepPercent?: number;
|
|
11
11
|
};
|
|
12
12
|
export declare type BackupDataType = {
|
package/cli.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.exec = exports.parseArgs = exports.buildArgs = void 0;
|
|
7
|
+
const ConfigAction_1 = require("./Action/ConfigAction");
|
|
4
8
|
const AppError_1 = require("./Error/AppError");
|
|
5
9
|
const CommandFactory_1 = require("./Factory/CommandFactory");
|
|
10
|
+
const globalData_1 = __importDefault(require("./globalData"));
|
|
6
11
|
const cli_util_1 = require("./util/cli-util");
|
|
7
12
|
const fs_util_1 = require("./util/fs-util");
|
|
8
13
|
const process_util_1 = require("./util/process-util");
|
|
@@ -35,7 +40,19 @@ function makeCommandAction(command) {
|
|
|
35
40
|
let exitCode = 1;
|
|
36
41
|
const globalOptions = getGlobalOptions();
|
|
37
42
|
try {
|
|
38
|
-
|
|
43
|
+
const configAction = new ConfigAction_1.ConfigAction({
|
|
44
|
+
path: globalOptions.config,
|
|
45
|
+
verbose: !!globalOptions.verbose,
|
|
46
|
+
});
|
|
47
|
+
const config = await configAction.exec();
|
|
48
|
+
if (config.data.tempDir)
|
|
49
|
+
globalData_1.default.tempDir = (0, path_1.isAbsolute)(config.data.tempDir)
|
|
50
|
+
? config.data.tempDir
|
|
51
|
+
: (0, path_1.join)((0, path_1.dirname)(config.path), config.data.tempDir);
|
|
52
|
+
exitCode = await (0, CommandFactory_1.CommandFactory)(command, {
|
|
53
|
+
...globalOptions,
|
|
54
|
+
config: config.data,
|
|
55
|
+
}, options).onExec();
|
|
39
56
|
}
|
|
40
57
|
catch (e) {
|
|
41
58
|
const error = e;
|
package/config.schema.json
CHANGED
|
@@ -20,6 +20,37 @@
|
|
|
20
20
|
"name": {
|
|
21
21
|
"type": "string"
|
|
22
22
|
},
|
|
23
|
+
"enabled": {
|
|
24
|
+
"anyOf": [
|
|
25
|
+
{
|
|
26
|
+
"type": "boolean"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"properties": {
|
|
32
|
+
"defaults": {
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
35
|
+
"backup": {
|
|
36
|
+
"type": "boolean"
|
|
37
|
+
},
|
|
38
|
+
"init": {
|
|
39
|
+
"type": "boolean"
|
|
40
|
+
},
|
|
41
|
+
"prune": {
|
|
42
|
+
"type": "boolean"
|
|
43
|
+
},
|
|
44
|
+
"restore": {
|
|
45
|
+
"type": "boolean"
|
|
46
|
+
},
|
|
47
|
+
"snapshots": {
|
|
48
|
+
"type": "boolean"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
23
54
|
"config": {}
|
|
24
55
|
},
|
|
25
56
|
"anyOf": [
|
|
@@ -456,19 +487,39 @@
|
|
|
456
487
|
}
|
|
457
488
|
}
|
|
458
489
|
]
|
|
490
|
+
},
|
|
491
|
+
"fileCopyConcurrency": {
|
|
492
|
+
"type": "integer",
|
|
493
|
+
"minimum": 1
|
|
459
494
|
}
|
|
460
495
|
}
|
|
461
496
|
},
|
|
462
497
|
"restic-repository": {
|
|
463
498
|
"type": "object",
|
|
464
499
|
"required": [
|
|
465
|
-
"
|
|
500
|
+
"password",
|
|
466
501
|
"repository"
|
|
467
502
|
],
|
|
468
503
|
"additionalProperties": false,
|
|
469
504
|
"properties": {
|
|
470
|
-
"
|
|
471
|
-
"
|
|
505
|
+
"password": {
|
|
506
|
+
"anyOf": [
|
|
507
|
+
{
|
|
508
|
+
"type": "string"
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
"type": "object",
|
|
512
|
+
"additionalProperties": false,
|
|
513
|
+
"required": [
|
|
514
|
+
"path"
|
|
515
|
+
],
|
|
516
|
+
"properties": {
|
|
517
|
+
"path": {
|
|
518
|
+
"type": "string"
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
]
|
|
472
523
|
},
|
|
473
524
|
"repository": {
|
|
474
525
|
"type": "object",
|
|
@@ -568,6 +619,10 @@
|
|
|
568
619
|
},
|
|
569
620
|
"includeConfig": {
|
|
570
621
|
"type": "boolean"
|
|
622
|
+
},
|
|
623
|
+
"fileCopyConcurrency": {
|
|
624
|
+
"type": "integer",
|
|
625
|
+
"minimum": 1
|
|
571
626
|
}
|
|
572
627
|
}
|
|
573
628
|
},
|
|
@@ -769,6 +824,9 @@
|
|
|
769
824
|
"$schema": {
|
|
770
825
|
"type": "string"
|
|
771
826
|
},
|
|
827
|
+
"tempDir": {
|
|
828
|
+
"type": "string"
|
|
829
|
+
},
|
|
772
830
|
"repositories": {
|
|
773
831
|
"type": "array",
|
|
774
832
|
"items": {
|
package/globalData.d.ts
ADDED
package/globalData.js
ADDED
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datatruck/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"ajv": "^8.11.0",
|
|
6
|
+
"async": "^3.2.4",
|
|
6
7
|
"chalk": "^4.1.2",
|
|
7
8
|
"cli-table3": "^0.6.2",
|
|
8
9
|
"commander": "^9.2.0",
|
|
9
10
|
"dayjs": "^1.11.2",
|
|
10
11
|
"fast-glob": "^3.2.11",
|
|
11
|
-
"fs-extra": "^10.1.0",
|
|
12
12
|
"micromatch": "^4.0.5",
|
|
13
13
|
"sqlite": "^4.1.1",
|
|
14
14
|
"sqlite3": "^5.0.8"
|
package/util/GitUtil.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GitUtil = void 0;
|
|
4
4
|
const fs_util_1 = require("./fs-util");
|
|
5
5
|
const process_util_1 = require("./process-util");
|
|
6
|
-
const
|
|
6
|
+
const promises_1 = require("fs/promises");
|
|
7
7
|
class GitUtil {
|
|
8
8
|
constructor(options) {
|
|
9
9
|
this.options = options;
|
|
@@ -16,7 +16,7 @@ class GitUtil {
|
|
|
16
16
|
}
|
|
17
17
|
async canBeInit(repo) {
|
|
18
18
|
return ((0, fs_util_1.isLocalDir)(repo) &&
|
|
19
|
-
(!(await (0, fs_util_1.checkDir)(repo)) || !(await (0,
|
|
19
|
+
(!(await (0, fs_util_1.checkDir)(repo)) || !(await (0, promises_1.readdir)(repo)).length));
|
|
20
20
|
}
|
|
21
21
|
async clone(options) {
|
|
22
22
|
return await this.exec([
|
package/util/ResticUtil.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.ResticUtil = void 0;
|
|
|
4
4
|
const fs_util_1 = require("./fs-util");
|
|
5
5
|
const process_util_1 = require("./process-util");
|
|
6
6
|
const string_util_1 = require("./string-util");
|
|
7
|
-
const fs_extra_1 = require("fs-extra");
|
|
8
7
|
const promises_1 = require("fs/promises");
|
|
9
8
|
const path_1 = require("path");
|
|
10
9
|
class ResticUtil {
|
|
@@ -20,7 +19,7 @@ class ResticUtil {
|
|
|
20
19
|
if (input.passwordFile)
|
|
21
20
|
input = {
|
|
22
21
|
...input,
|
|
23
|
-
password: (await (0,
|
|
22
|
+
password: (await (0, promises_1.readFile)(input.passwordFile)).toString(),
|
|
24
23
|
};
|
|
25
24
|
return `${input.backend}:${(0, string_util_1.formatUri)(input, hidePassword)}`;
|
|
26
25
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { ConfigType } from "../../Config/Config";
|
|
2
2
|
import type { PackageConfigType } from "../../Config/PackageConfig";
|
|
3
|
-
|
|
3
|
+
import { RepositoryConfigEnabledActionType, RepositoryConfigType } from "../../Config/RepositoryConfig";
|
|
4
|
+
export declare function findRepositoryOrFail(config: ConfigType, repositoryName: string): RepositoryConfigType;
|
|
5
|
+
export declare function filterRepository(repository: RepositoryConfigType, action?: RepositoryConfigEnabledActionType): boolean;
|
|
4
6
|
export declare function filterPackages(config: ConfigType, options: {
|
|
5
7
|
packageNames?: string[];
|
|
6
8
|
repositoryNames?: string[];
|
|
7
9
|
repositoryTypes?: string[];
|
|
10
|
+
sourceAction?: RepositoryConfigEnabledActionType;
|
|
8
11
|
}): PackageConfigType[];
|
|
9
12
|
declare type ResolvePackagePathParamsType = ResolvePackageParamsType & {
|
|
10
13
|
packageName: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.params = exports.dbNameParams = exports.pkgRestorePathParams = exports.pkgExcludeParams = exports.pkgIncludeParams = exports.pkgPathParams = exports.resolvePackages = exports.resolvePackage = exports.resolveDatabaseName = exports.resolvePackagePath = exports.filterPackages = exports.findRepositoryOrFail = void 0;
|
|
3
|
+
exports.params = exports.dbNameParams = exports.pkgRestorePathParams = exports.pkgExcludeParams = exports.pkgIncludeParams = exports.pkgPathParams = exports.resolvePackages = exports.resolvePackage = exports.resolveDatabaseName = exports.resolvePackagePath = exports.filterPackages = exports.filterRepository = exports.findRepositoryOrFail = void 0;
|
|
4
4
|
const AppError_1 = require("../../Error/AppError");
|
|
5
5
|
const fs_util_1 = require("../fs-util");
|
|
6
6
|
const string_util_1 = require("../string-util");
|
|
@@ -12,6 +12,14 @@ function findRepositoryOrFail(config, repositoryName) {
|
|
|
12
12
|
return repo;
|
|
13
13
|
}
|
|
14
14
|
exports.findRepositoryOrFail = findRepositoryOrFail;
|
|
15
|
+
function filterRepository(repository, action) {
|
|
16
|
+
const enabled = repository.enabled ?? true;
|
|
17
|
+
if (typeof enabled === "boolean")
|
|
18
|
+
return enabled;
|
|
19
|
+
const defaults = enabled["defaults"] ?? true;
|
|
20
|
+
return action ? enabled[action] ?? defaults : defaults;
|
|
21
|
+
}
|
|
22
|
+
exports.filterRepository = filterRepository;
|
|
15
23
|
function filterPackages(config, options) {
|
|
16
24
|
const packagePatterns = (0, string_util_1.makePathPatterns)(options.packageNames);
|
|
17
25
|
return config.packages
|
|
@@ -19,6 +27,8 @@ function filterPackages(config, options) {
|
|
|
19
27
|
pkg = Object.assign({}, pkg);
|
|
20
28
|
pkg.repositoryNames = (pkg.repositoryNames ?? []).filter((name) => {
|
|
21
29
|
const repo = findRepositoryOrFail(config, name);
|
|
30
|
+
if (!filterRepository(repo, options?.sourceAction))
|
|
31
|
+
return false;
|
|
22
32
|
return ((!options.repositoryNames ||
|
|
23
33
|
options.repositoryNames.includes(name)) &&
|
|
24
34
|
(!options.repositoryTypes ||
|
package/util/fs-util.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import { Interface } from "readline";
|
|
2
3
|
export declare function isLocalDir(path: string): boolean;
|
|
3
4
|
export declare function isDirEmpty(path: string): Promise<boolean>;
|
|
4
5
|
export declare function mkdirIfNotExists(path: string): Promise<string>;
|
|
@@ -44,3 +45,35 @@ export declare function writePathLists(options: {
|
|
|
44
45
|
multipleStats: Record<string, number>;
|
|
45
46
|
};
|
|
46
47
|
}>;
|
|
48
|
+
export declare function cpy(options: {
|
|
49
|
+
input: {
|
|
50
|
+
type: "glob";
|
|
51
|
+
sourcePath: string;
|
|
52
|
+
include?: string[];
|
|
53
|
+
exclude?: string[];
|
|
54
|
+
} | {
|
|
55
|
+
type: "stream";
|
|
56
|
+
basePath: string;
|
|
57
|
+
value: Interface;
|
|
58
|
+
} | {
|
|
59
|
+
type: "pathList";
|
|
60
|
+
path: string;
|
|
61
|
+
basePath: string;
|
|
62
|
+
};
|
|
63
|
+
targetPath: string;
|
|
64
|
+
/**
|
|
65
|
+
* @default 1
|
|
66
|
+
*/
|
|
67
|
+
concurrency?: number;
|
|
68
|
+
onPath?: (data: {
|
|
69
|
+
isDir: boolean;
|
|
70
|
+
entryPath: string;
|
|
71
|
+
entrySourcePath: string;
|
|
72
|
+
entryTargetPath: string;
|
|
73
|
+
stats: {
|
|
74
|
+
paths: number;
|
|
75
|
+
files: number;
|
|
76
|
+
dirs: number;
|
|
77
|
+
};
|
|
78
|
+
}) => Promise<boolean | void>;
|
|
79
|
+
}): Promise<void>;
|