@datatruck/cli 0.15.0 → 0.16.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 +7 -7
- package/Action/RestoreAction.js +4 -4
- package/Entity/StateEntityAbstract.d.ts +2 -6
- package/Error/AppError.d.ts +1 -0
- package/Error/AppError.js +4 -0
- package/Repository/DatatruckRepository.js +68 -87
- package/Repository/RepositoryAbstract.d.ts +4 -15
- package/Repository/ResticRepository.js +14 -14
- package/SessionDriver/ConsoleSessionDriver.d.ts +2 -6
- package/SessionDriver/ConsoleSessionDriver.js +52 -26
- package/SessionDriver/SqliteSessionDriver.js +5 -0
- package/SessionManager/BackupSessionManager.d.ts +5 -3
- package/SessionManager/BackupSessionManager.js +14 -18
- package/SessionManager/RestoreSessionManager.d.ts +6 -4
- package/SessionManager/RestoreSessionManager.js +14 -18
- package/SessionManager/SessionManagerAbstract.d.ts +5 -1
- package/SessionManager/SessionManagerAbstract.js +13 -2
- package/Task/GitTask.js +6 -6
- package/Task/MariadbTask.js +3 -3
- package/Task/MysqlDumpTask.d.ts +3 -1
- package/Task/MysqlDumpTask.js +5 -2
- package/Task/PostgresqlDumpTask.d.ts +3 -1
- package/Task/PostgresqlDumpTask.js +2 -2
- package/Task/SqlDumpTaskAbstract.d.ts +3 -1
- package/Task/SqlDumpTaskAbstract.js +33 -11
- package/Task/TaskAbstract.d.ts +3 -14
- package/migrations/001-initial.sql +6 -36
- package/package.json +1 -1
- package/util/cli-util.d.ts +1 -1
- package/util/cli-util.js +17 -2
- package/util/fs-util.js +1 -1
- package/util/process-util.d.ts +3 -0
- package/util/process-util.js +11 -0
- package/util/progress.d.ts +12 -0
- package/util/progress.js +2 -0
- package/util/zip-util.js +6 -2
package/Action/BackupAction.js
CHANGED
|
@@ -15,7 +15,7 @@ class BackupAction {
|
|
|
15
15
|
}
|
|
16
16
|
async init(session) {
|
|
17
17
|
const snapshot = {
|
|
18
|
-
id: (0, crypto_1.
|
|
18
|
+
id: (0, crypto_1.randomUUID)().replaceAll("-", ""),
|
|
19
19
|
date: this.options.date ?? new Date().toISOString(),
|
|
20
20
|
};
|
|
21
21
|
await session.initDrivers();
|
|
@@ -74,10 +74,10 @@ class BackupAction {
|
|
|
74
74
|
options: this.options,
|
|
75
75
|
snapshot,
|
|
76
76
|
targetPath,
|
|
77
|
-
onProgress: async (
|
|
77
|
+
onProgress: async (progress) => {
|
|
78
78
|
await session.progressTask({
|
|
79
79
|
id: taskId,
|
|
80
|
-
|
|
80
|
+
progress,
|
|
81
81
|
});
|
|
82
82
|
},
|
|
83
83
|
});
|
|
@@ -116,10 +116,10 @@ class BackupAction {
|
|
|
116
116
|
(!config.names || config.names.includes(repo.name)))?.config,
|
|
117
117
|
options: this.options,
|
|
118
118
|
snapshot: snapshot,
|
|
119
|
-
onProgress: async (
|
|
119
|
+
onProgress: async (progress) => {
|
|
120
120
|
await session.progressRepository({
|
|
121
121
|
id: repositoryId,
|
|
122
|
-
|
|
122
|
+
progress,
|
|
123
123
|
});
|
|
124
124
|
},
|
|
125
125
|
});
|
|
@@ -156,10 +156,10 @@ class BackupAction {
|
|
|
156
156
|
package: pkg,
|
|
157
157
|
snapshot,
|
|
158
158
|
mirrorRepositoryConfig: mirrorRepo.config,
|
|
159
|
-
onProgress: async (
|
|
159
|
+
onProgress: async (progress) => {
|
|
160
160
|
await session.progressRepository({
|
|
161
161
|
id: repositoryId,
|
|
162
|
-
|
|
162
|
+
progress,
|
|
163
163
|
});
|
|
164
164
|
},
|
|
165
165
|
});
|
package/Action/RestoreAction.js
CHANGED
|
@@ -111,10 +111,10 @@ class RestoreAction {
|
|
|
111
111
|
options: this.options,
|
|
112
112
|
snapshot,
|
|
113
113
|
targetPath,
|
|
114
|
-
onProgress: async (
|
|
114
|
+
onProgress: async (progress) => {
|
|
115
115
|
await session.progressTask({
|
|
116
116
|
id: taskId,
|
|
117
|
-
|
|
117
|
+
progress,
|
|
118
118
|
});
|
|
119
119
|
},
|
|
120
120
|
});
|
|
@@ -156,10 +156,10 @@ class RestoreAction {
|
|
|
156
156
|
(!config.names || config.names.includes(repo.name)))?.config,
|
|
157
157
|
options: this.options,
|
|
158
158
|
snapshot: snapshot,
|
|
159
|
-
onProgress: async (
|
|
159
|
+
onProgress: async (progress) => {
|
|
160
160
|
await session.progressRepository({
|
|
161
161
|
id: repositoryId,
|
|
162
|
-
|
|
162
|
+
progress,
|
|
163
163
|
});
|
|
164
164
|
},
|
|
165
165
|
});
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
+
import { Progress } from "../util/progress";
|
|
1
2
|
import { CrudEntityAbstract } from "./CrudEntityAbstract";
|
|
2
3
|
export declare abstract class StateEntityAbstract extends CrudEntityAbstract {
|
|
3
4
|
state: "started" | "ended" | null;
|
|
4
5
|
error?: string | null;
|
|
5
6
|
startDate?: string | null;
|
|
6
7
|
endDate?: string | null;
|
|
7
|
-
|
|
8
|
-
progressCurrent?: number | null;
|
|
9
|
-
progressPercent?: number | null;
|
|
10
|
-
progressStepDescription?: string | null;
|
|
11
|
-
progressStepItem?: string | null;
|
|
12
|
-
progressStepPercent?: number | null;
|
|
8
|
+
progress?: Progress;
|
|
13
9
|
}
|
package/Error/AppError.d.ts
CHANGED
package/Error/AppError.js
CHANGED
|
@@ -76,8 +76,6 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
76
76
|
return `${date}_${pkgName}_${snapshotShortId}`;
|
|
77
77
|
}
|
|
78
78
|
static parseSnapshotName(name) {
|
|
79
|
-
if (!name.endsWith(".json"))
|
|
80
|
-
return null;
|
|
81
79
|
name = name.replace(/\.json$/, "");
|
|
82
80
|
const nameParts = name.split("_");
|
|
83
81
|
if (nameParts.length !== 3)
|
|
@@ -110,12 +108,12 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
110
108
|
current: 0,
|
|
111
109
|
progress: async (description, data) => {
|
|
112
110
|
await options.onProgress({
|
|
113
|
-
|
|
111
|
+
relative: {
|
|
114
112
|
description,
|
|
115
|
-
|
|
113
|
+
payload: data.path,
|
|
116
114
|
percent: data.percent,
|
|
117
115
|
},
|
|
118
|
-
|
|
116
|
+
absolute: {
|
|
119
117
|
total: object.total,
|
|
120
118
|
current: object.current + data.current,
|
|
121
119
|
percent: (0, math_util_1.progressPercent)(object.total, object.current + data.current),
|
|
@@ -133,9 +131,9 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
133
131
|
const diff = currentTime - lastTime;
|
|
134
132
|
if (diff > 1000) {
|
|
135
133
|
await options.onProgress({
|
|
136
|
-
|
|
134
|
+
relative: {
|
|
137
135
|
description: "Scanning files",
|
|
138
|
-
|
|
136
|
+
payload: object.total.toString(),
|
|
139
137
|
},
|
|
140
138
|
});
|
|
141
139
|
lastTime = currentTime;
|
|
@@ -144,15 +142,15 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
144
142
|
await cb(entry);
|
|
145
143
|
}
|
|
146
144
|
await options.onProgress({
|
|
147
|
-
|
|
145
|
+
relative: {
|
|
148
146
|
description: "Scanned files",
|
|
149
|
-
|
|
147
|
+
payload: object.total.toString(),
|
|
150
148
|
},
|
|
151
149
|
});
|
|
152
150
|
},
|
|
153
151
|
};
|
|
154
152
|
await options.onProgress({
|
|
155
|
-
|
|
153
|
+
relative: {
|
|
156
154
|
description: "Scanning files",
|
|
157
155
|
},
|
|
158
156
|
});
|
|
@@ -172,15 +170,12 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
172
170
|
packageName: data.snapshot.packageName,
|
|
173
171
|
});
|
|
174
172
|
const snapshotPath = (0, path_1.join)(this.config.outPath, snapshotName);
|
|
175
|
-
const metaPath = `${snapshotPath}.json`;
|
|
176
173
|
if (data.options.verbose)
|
|
177
174
|
(0, cli_util_1.logExec)(`Deleting ${snapshotPath}`);
|
|
178
175
|
if (await (0, fs_util_1.checkDir)(snapshotPath))
|
|
179
176
|
await (0, promises_1.rm)(snapshotPath, {
|
|
180
177
|
recursive: true,
|
|
181
178
|
});
|
|
182
|
-
if (await (0, fs_util_1.checkFile)(metaPath))
|
|
183
|
-
await (0, promises_1.rm)(metaPath);
|
|
184
179
|
}
|
|
185
180
|
async onSnapshots(data) {
|
|
186
181
|
if (!(await (0, fs_util_1.checkDir)(this.config.outPath)))
|
|
@@ -199,7 +194,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
199
194
|
if (data.options.ids &&
|
|
200
195
|
!data.options.ids.some((id) => snapshotNameData.snapshotShortId.startsWith(id.slice(0, 8))))
|
|
201
196
|
continue;
|
|
202
|
-
const metaPath = (0, path_1.join)(this.config.outPath, snapshotName);
|
|
197
|
+
const metaPath = (0, path_1.join)(this.config.outPath, snapshotName, "meta.json");
|
|
203
198
|
const meta = await DatatruckRepository.parseMetaData(metaPath);
|
|
204
199
|
if (taskPatterns && !(0, string_util_1.checkMatch)(meta.task, taskPatterns))
|
|
205
200
|
continue;
|
|
@@ -263,10 +258,10 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
263
258
|
: undefined;
|
|
264
259
|
const packs = compress?.packs || [];
|
|
265
260
|
const tmpDir = await (0, fs_util_1.mkTmpDir)("path-lists");
|
|
266
|
-
const
|
|
261
|
+
const unpackedStream = (0, fs_1.createWriteStream)((0, path_1.join)(tmpDir, "unpacked.txt"));
|
|
267
262
|
const singlePackStream = (0, fs_1.createWriteStream)((0, path_1.join)(tmpDir, "single-pack.txt"));
|
|
268
263
|
const packStreams = Array.from({ length: packs.length }).map((v, i) => (0, fs_1.createWriteStream)((0, path_1.join)(tmpDir, `pack-${i}.txt`)));
|
|
269
|
-
const streams = [
|
|
264
|
+
const streams = [unpackedStream, singlePackStream, ...packStreams];
|
|
270
265
|
if (data.options.verbose)
|
|
271
266
|
(0, cli_util_1.logExec)(`Writing file lists in ${tmpDir}`);
|
|
272
267
|
const scanner = await this.createFileScanner({
|
|
@@ -286,7 +281,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
286
281
|
const pathSubject = entry.stats.isDirectory()
|
|
287
282
|
? entry.path.slice(0, -1)
|
|
288
283
|
: entry.path;
|
|
289
|
-
let stream =
|
|
284
|
+
let stream = unpackedStream;
|
|
290
285
|
let successPackIndex;
|
|
291
286
|
for (const [packIndex, pack] of packs.entries()) {
|
|
292
287
|
if ((0, string_util_1.checkPath)(pathSubject, pack.include, pack.exclude)) {
|
|
@@ -297,17 +292,17 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
297
292
|
break;
|
|
298
293
|
}
|
|
299
294
|
}
|
|
300
|
-
const
|
|
301
|
-
const isPackStream = stream !==
|
|
295
|
+
const isUnpackedStream = stream === unpackedStream;
|
|
296
|
+
const isPackStream = stream !== unpackedStream;
|
|
302
297
|
const isSinglePackStream = stream === singlePackStream;
|
|
303
298
|
const include = isPackStream
|
|
304
299
|
? entry.stats.isDirectory()
|
|
305
|
-
? await (0, fs_util_1.isEmptyDir)(entry.path)
|
|
300
|
+
? await (0, fs_util_1.isEmptyDir)((0, path_1.join)(sourcePath, entry.path))
|
|
306
301
|
: true
|
|
307
302
|
: true;
|
|
308
303
|
if (include) {
|
|
309
304
|
let value = entry.path;
|
|
310
|
-
if (
|
|
305
|
+
if (isUnpackedStream) {
|
|
311
306
|
value += `:${entry.stats.uid}:${entry.stats.gid}:${entry.stats.mode}`;
|
|
312
307
|
}
|
|
313
308
|
else if (isSinglePackStream) {
|
|
@@ -323,20 +318,19 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
323
318
|
}
|
|
324
319
|
})(),
|
|
325
320
|
]);
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
await (0, promises_1.
|
|
329
|
-
await (0, promises_1.copyFile)(nonPackStream.path, (0, path_1.join)(dttPath, "permissions.txt"));
|
|
321
|
+
const unpackedPath = (0, path_1.join)(outPath, "unpacked");
|
|
322
|
+
await (0, promises_1.mkdir)(unpackedPath);
|
|
323
|
+
await (0, promises_1.copyFile)(unpackedStream.path, (0, path_1.join)(outPath, "permissions.txt"));
|
|
330
324
|
// Non pack
|
|
331
325
|
if (data.options.verbose)
|
|
332
|
-
(0, cli_util_1.logExec)(`Copying files from ${
|
|
326
|
+
(0, cli_util_1.logExec)(`Copying files from ${unpackedStream.path.toString()} to ${unpackedPath}`);
|
|
333
327
|
await (0, fs_util_1.cpy)({
|
|
334
328
|
input: {
|
|
335
329
|
type: "pathList",
|
|
336
|
-
path:
|
|
330
|
+
path: unpackedStream.path.toString(),
|
|
337
331
|
basePath: sourcePath,
|
|
338
332
|
},
|
|
339
|
-
targetPath:
|
|
333
|
+
targetPath: unpackedPath,
|
|
340
334
|
skipNotFoundError: true,
|
|
341
335
|
concurrency: this.config.fileCopyConcurrency,
|
|
342
336
|
onProgress: async (progress) => await scanner.progress(progress.type === "end" ? "Files copied" : "Copying file", progress),
|
|
@@ -353,7 +347,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
353
347
|
const outBasename = (`pack${pack.name ? `-${encodeURIComponent(pack.name)}` : ""}` +
|
|
354
348
|
`-${encodeURIComponent(packPath.replace(/[\\/]/g, "-"))}` +
|
|
355
349
|
`.zip`).slice(0, 255);
|
|
356
|
-
const target = (0, path_1.join)(
|
|
350
|
+
const target = (0, path_1.join)(outPath, outBasename);
|
|
357
351
|
await (0, zip_util_1.zip)({
|
|
358
352
|
path: pkg.path,
|
|
359
353
|
output: target,
|
|
@@ -367,7 +361,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
367
361
|
// Packs
|
|
368
362
|
for (const [packIndex, packStream] of packStreams.entries()) {
|
|
369
363
|
const pack = packs[packIndex];
|
|
370
|
-
const target = (0, path_1.join)(
|
|
364
|
+
const target = (0, path_1.join)(outPath, `pack-${packIndex}${pack.name ? `-${pack.name}` : ""}.zip`);
|
|
371
365
|
await (0, zip_util_1.zip)({
|
|
372
366
|
path: sourcePath,
|
|
373
367
|
output: target,
|
|
@@ -379,7 +373,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
379
373
|
});
|
|
380
374
|
}
|
|
381
375
|
// Meta
|
|
382
|
-
const metaPath = `${outPath}.json`;
|
|
376
|
+
const metaPath = `${outPath}/meta.json`;
|
|
383
377
|
const nodePkg = (0, fs_util_1.parsePackageFile)();
|
|
384
378
|
const meta = {
|
|
385
379
|
id: data.snapshot.id,
|
|
@@ -388,8 +382,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
388
382
|
package: data.package.name,
|
|
389
383
|
task: data.package.task?.name,
|
|
390
384
|
version: nodePkg.version,
|
|
391
|
-
size:
|
|
392
|
-
(await (0, fs_util_1.fastFolderSizeAsync)(dttPath)),
|
|
385
|
+
size: await (0, fs_util_1.fastFolderSizeAsync)(outPath),
|
|
393
386
|
};
|
|
394
387
|
if (data.options.verbose)
|
|
395
388
|
(0, cli_util_1.logExec)(`Writing metadata into ${metaPath}`);
|
|
@@ -403,8 +396,6 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
403
396
|
});
|
|
404
397
|
const sourcePath = (0, path_1.resolve)((0, path_1.join)(this.config.outPath, snapshotName));
|
|
405
398
|
const targetPath = (0, path_1.resolve)((0, path_1.join)(data.mirrorRepositoryConfig.outPath, snapshotName));
|
|
406
|
-
const sourceMetaPath = `${sourcePath}.json`;
|
|
407
|
-
const targetMetaPath = `${targetPath}.json`;
|
|
408
399
|
if (data.options.verbose)
|
|
409
400
|
(0, cli_util_1.logExec)(`Copying backup files to ${targetPath}`);
|
|
410
401
|
await (0, promises_1.mkdir)(targetPath);
|
|
@@ -424,7 +415,6 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
424
415
|
targetPath,
|
|
425
416
|
onProgress: async (progress) => await scanner.progress(progress.type === "end" ? "Files copied" : "Copying file", progress),
|
|
426
417
|
});
|
|
427
|
-
await (0, promises_1.copyFile)(sourceMetaPath, targetMetaPath);
|
|
428
418
|
}
|
|
429
419
|
async onRestore(data) {
|
|
430
420
|
const relRestorePath = data.targetPath ?? data.package.restorePath;
|
|
@@ -443,36 +433,30 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
443
433
|
packageName: data.package.name,
|
|
444
434
|
});
|
|
445
435
|
const sourcePath = (0, path_1.join)(this.config.outPath, snapshotName);
|
|
446
|
-
const dttFolder = `.dtt-${data.snapshot.id.slice(0, 8)}`;
|
|
447
|
-
const dttPath = (0, path_1.join)(sourcePath, dttFolder);
|
|
448
436
|
const scanner = await this.createFileScanner({
|
|
449
437
|
glob: {
|
|
450
|
-
include: ["
|
|
438
|
+
include: ["unpacked/**/*"],
|
|
451
439
|
cwd: sourcePath,
|
|
452
|
-
ignore: [dttFolder],
|
|
453
440
|
},
|
|
454
441
|
onProgress: data.onProgress,
|
|
455
442
|
});
|
|
456
443
|
await scanner.start();
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
},
|
|
474
|
-
});
|
|
475
|
-
}
|
|
444
|
+
const it = await (0, promises_1.opendir)(sourcePath);
|
|
445
|
+
for await (const dirent of it) {
|
|
446
|
+
const path = (0, path_1.join)(sourcePath, dirent.name);
|
|
447
|
+
if (dirent.name === "permissions.txt") {
|
|
448
|
+
scanner.total++;
|
|
449
|
+
}
|
|
450
|
+
else if (dirent.name.endsWith(".zip")) {
|
|
451
|
+
await (0, zip_util_1.listZip)({
|
|
452
|
+
path,
|
|
453
|
+
verbose: data.options.verbose,
|
|
454
|
+
onStream: async (item) => {
|
|
455
|
+
const isDir = item.Folder === "+";
|
|
456
|
+
if (!isDir)
|
|
457
|
+
scanner.total++;
|
|
458
|
+
},
|
|
459
|
+
});
|
|
476
460
|
}
|
|
477
461
|
}
|
|
478
462
|
if (data.options.verbose)
|
|
@@ -480,39 +464,36 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
480
464
|
await (0, fs_util_1.cpy)({
|
|
481
465
|
input: {
|
|
482
466
|
type: "glob",
|
|
483
|
-
sourcePath,
|
|
484
|
-
exclude: [dttFolder],
|
|
467
|
+
sourcePath: (0, path_1.join)(sourcePath, "unpacked"),
|
|
485
468
|
},
|
|
486
469
|
targetPath: restorePath,
|
|
487
470
|
concurrency: this.config.fileCopyConcurrency,
|
|
488
471
|
onProgress: async (progress) => await scanner.progress(progress.type === "end" ? "Files copied" : "Copying file", progress),
|
|
489
472
|
});
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
});
|
|
515
|
-
}
|
|
473
|
+
const it2 = await (0, promises_1.opendir)(sourcePath);
|
|
474
|
+
for await (const dirent of it2) {
|
|
475
|
+
const path = (0, path_1.join)(sourcePath, dirent.name);
|
|
476
|
+
if (dirent.name === "permissions.txt") {
|
|
477
|
+
if (data.options.verbose)
|
|
478
|
+
(0, cli_util_1.logExec)(`Applying permissions (${path})`);
|
|
479
|
+
await scanner.progress("Applying permissions", {
|
|
480
|
+
current: 0,
|
|
481
|
+
});
|
|
482
|
+
await (0, fs_util_1.applyPermissions)(restorePath, path);
|
|
483
|
+
await scanner.progress("Permissions applied", {
|
|
484
|
+
current: 1,
|
|
485
|
+
type: "end",
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
else if (dirent.name.endsWith(".zip")) {
|
|
489
|
+
await (0, zip_util_1.unzip)({
|
|
490
|
+
input: path,
|
|
491
|
+
output: restorePath,
|
|
492
|
+
verbose: data.options.verbose,
|
|
493
|
+
onProgress: async (progress) => await scanner.progress(progress.type === "start"
|
|
494
|
+
? "Starting extracting"
|
|
495
|
+
: "Extracting file", progress),
|
|
496
|
+
});
|
|
516
497
|
}
|
|
517
498
|
}
|
|
518
499
|
}
|
|
@@ -4,6 +4,7 @@ import type { RestoreActionOptionsType } from "../Action/RestoreAction";
|
|
|
4
4
|
import type { SnapshotExtendedType, SnapshotsActionOptionsType } from "../Action/SnapshotsAction";
|
|
5
5
|
import type { PackageConfigType } from "../Config/PackageConfig";
|
|
6
6
|
import type { RepositoryConfigType } from "../Config/RepositoryConfig";
|
|
7
|
+
import { Progress } from "../util/progress";
|
|
7
8
|
export declare type SnapshotType = {
|
|
8
9
|
id: string;
|
|
9
10
|
date: string;
|
|
@@ -15,18 +16,6 @@ export declare type SnapshotResultType = SnapshotType & {
|
|
|
15
16
|
tags: string[];
|
|
16
17
|
size: number;
|
|
17
18
|
};
|
|
18
|
-
export declare type ProgressDataType = {
|
|
19
|
-
stats?: {
|
|
20
|
-
total?: number;
|
|
21
|
-
current?: number;
|
|
22
|
-
percent?: number;
|
|
23
|
-
};
|
|
24
|
-
step?: {
|
|
25
|
-
description?: string;
|
|
26
|
-
item?: string;
|
|
27
|
-
percent?: number | null;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
19
|
export declare type InitDataType = {
|
|
31
20
|
options: InitActionOptionsType;
|
|
32
21
|
};
|
|
@@ -38,7 +27,7 @@ export declare type CopyBackupType<TRepositoryConfig> = {
|
|
|
38
27
|
snapshot: SnapshotType;
|
|
39
28
|
package: PackageConfigType;
|
|
40
29
|
mirrorRepositoryConfig: TRepositoryConfig;
|
|
41
|
-
onProgress: (data:
|
|
30
|
+
onProgress: (data: Progress) => Promise<void>;
|
|
42
31
|
};
|
|
43
32
|
export declare type BackupDataType<TPackageConfig> = {
|
|
44
33
|
options: BackupActionOptionsType;
|
|
@@ -46,7 +35,7 @@ export declare type BackupDataType<TPackageConfig> = {
|
|
|
46
35
|
package: PackageConfigType;
|
|
47
36
|
targetPath: string | undefined;
|
|
48
37
|
packageConfig: TPackageConfig | undefined;
|
|
49
|
-
onProgress: (data:
|
|
38
|
+
onProgress: (data: Progress) => Promise<void>;
|
|
50
39
|
};
|
|
51
40
|
export declare type RestoreDataType<TPackageConfig> = {
|
|
52
41
|
options: RestoreActionOptionsType;
|
|
@@ -54,7 +43,7 @@ export declare type RestoreDataType<TPackageConfig> = {
|
|
|
54
43
|
package: PackageConfigType;
|
|
55
44
|
targetPath: string | undefined;
|
|
56
45
|
packageConfig: TPackageConfig;
|
|
57
|
-
onProgress: (data:
|
|
46
|
+
onProgress: (data: Progress) => Promise<void>;
|
|
58
47
|
};
|
|
59
48
|
export declare type PruneDataType = {
|
|
60
49
|
snapshot: SnapshotExtendedType;
|
|
@@ -195,7 +195,7 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
195
195
|
verbose: data.options.verbose,
|
|
196
196
|
});
|
|
197
197
|
await data.onProgress({
|
|
198
|
-
|
|
198
|
+
relative: {
|
|
199
199
|
description: "Writing excluded paths list",
|
|
200
200
|
},
|
|
201
201
|
});
|
|
@@ -225,7 +225,7 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
225
225
|
if (data.options.verbose)
|
|
226
226
|
(0, cli_util_1.logExec)(`Writing paths lists`);
|
|
227
227
|
await data.onProgress({
|
|
228
|
-
|
|
228
|
+
relative: {
|
|
229
229
|
description: "Writing excluded paths list",
|
|
230
230
|
},
|
|
231
231
|
});
|
|
@@ -237,7 +237,7 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
237
237
|
throw new AppError_1.AppError(`Tag prefix is not allowed`);
|
|
238
238
|
const packageTag = ResticRepository.buildSnapshotTag(RepositoryAbstract_1.SnapshotTagEnum.PACKAGE, data.package.name);
|
|
239
239
|
await data.onProgress({
|
|
240
|
-
|
|
240
|
+
relative: {
|
|
241
241
|
description: "Fetching last snapshot",
|
|
242
242
|
},
|
|
243
243
|
});
|
|
@@ -251,7 +251,7 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
251
251
|
let totalFilesChanges = 0;
|
|
252
252
|
const totalFilesChangesLimit = 10;
|
|
253
253
|
await data.onProgress({
|
|
254
|
-
|
|
254
|
+
relative: {
|
|
255
255
|
description: "Executing backup action",
|
|
256
256
|
},
|
|
257
257
|
});
|
|
@@ -286,20 +286,20 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
286
286
|
if (totalFilesChanges > totalFilesChangesLimit) {
|
|
287
287
|
showProgressBar = true;
|
|
288
288
|
}
|
|
289
|
-
else if (lastProgress?.
|
|
289
|
+
else if (lastProgress?.absolute?.total !== streamData.total_files) {
|
|
290
290
|
totalFilesChanges = 0;
|
|
291
291
|
}
|
|
292
292
|
else {
|
|
293
293
|
totalFilesChanges++;
|
|
294
294
|
}
|
|
295
295
|
await data.onProgress((lastProgress = {
|
|
296
|
-
|
|
296
|
+
relative: {
|
|
297
297
|
description: "Copying file",
|
|
298
|
-
|
|
298
|
+
payload: streamData.current_files?.join(", ") ?? "-",
|
|
299
299
|
},
|
|
300
|
-
|
|
301
|
-
total: Math.max(lastProgress?.
|
|
302
|
-
current: Math.max(lastProgress?.
|
|
300
|
+
absolute: {
|
|
301
|
+
total: Math.max(lastProgress?.absolute?.total || 0, streamData.total_files || 0),
|
|
302
|
+
current: Math.max(lastProgress?.absolute?.current || 0, streamData.files_done ?? 0),
|
|
303
303
|
percent: showProgressBar
|
|
304
304
|
? Number((streamData.percent_done * 100).toFixed(2))
|
|
305
305
|
: 0,
|
|
@@ -319,9 +319,9 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
319
319
|
const sizeTag = ResticRepository.buildSnapshotTag(RepositoryAbstract_1.SnapshotTagEnum.SIZE, resticTotalBytes.toString());
|
|
320
320
|
await restic.exec(["tag", "--add", sizeTag, resticSnapshotId]);
|
|
321
321
|
await data.onProgress({
|
|
322
|
-
|
|
323
|
-
total: lastProgress?.
|
|
324
|
-
current: lastProgress?.
|
|
322
|
+
absolute: {
|
|
323
|
+
total: lastProgress?.absolute?.total || 0,
|
|
324
|
+
current: lastProgress?.absolute?.total || 0,
|
|
325
325
|
percent: 100,
|
|
326
326
|
},
|
|
327
327
|
});
|
|
@@ -372,7 +372,7 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
372
372
|
if (streamData.message_type === "restore-status") {
|
|
373
373
|
const current = Math.min(streamData.total_bytes, snapshot.size);
|
|
374
374
|
await data.onProgress({
|
|
375
|
-
|
|
375
|
+
absolute: {
|
|
376
376
|
total: snapshot.size,
|
|
377
377
|
current,
|
|
378
378
|
percent: (0, math_util_1.progressPercent)(snapshot.size, current),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import { Progress } from "../util/progress";
|
|
2
3
|
import { WriteDataType, ReadResultType, SessionDriverAbstract, SessionDriverOptions } from "./SessionDriverAbstract";
|
|
3
4
|
declare type BadgeType = {
|
|
4
5
|
name: string;
|
|
@@ -12,12 +13,7 @@ declare type MessageType = {
|
|
|
12
13
|
text?: string;
|
|
13
14
|
badges: BadgeType[];
|
|
14
15
|
errorBadge?: BadgeType;
|
|
15
|
-
|
|
16
|
-
progressTotal?: number | null;
|
|
17
|
-
progressPercent?: number | null;
|
|
18
|
-
progressStepDescription?: string | null;
|
|
19
|
-
progressStepItem?: string | null;
|
|
20
|
-
progressStepPercent?: number | null;
|
|
16
|
+
progress?: Progress;
|
|
21
17
|
};
|
|
22
18
|
declare type ConsoleSessionDriverOptions = SessionDriverOptions & {
|
|
23
19
|
progress?: "auto" | "tty" | "plain";
|