@datatruck/cli 0.13.0 → 0.15.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 +3 -15
- package/Action/RestoreAction.js +2 -10
- package/Command/BackupCommand.js +2 -1
- package/Command/BackupSessionsCommand.js +1 -0
- package/Command/RestoreCommand.js +1 -1
- package/Command/RestoreSessionsCommand.js +1 -0
- package/Entity/StateEntityAbstract.d.ts +2 -1
- package/Repository/DatatruckRepository.d.ts +2 -0
- package/Repository/DatatruckRepository.js +239 -108
- package/Repository/RepositoryAbstract.d.ts +10 -5
- package/Repository/ResticRepository.js +34 -17
- package/SessionDriver/ConsoleSessionDriver.d.ts +2 -3
- package/SessionDriver/ConsoleSessionDriver.js +11 -10
- package/SessionManager/BackupSessionManager.d.ts +10 -11
- package/SessionManager/BackupSessionManager.js +24 -5
- package/SessionManager/RestoreSessionManager.d.ts +12 -11
- package/SessionManager/RestoreSessionManager.js +24 -5
- package/SessionManager/SessionManagerAbstract.d.ts +14 -0
- package/SessionManager/SessionManagerAbstract.js +21 -0
- package/Task/GitTask.js +23 -14
- package/Task/MariadbTask.js +9 -4
- package/Task/SqlDumpTaskAbstract.js +31 -10
- package/Task/TaskAbstract.d.ts +10 -5
- package/cli.js +1 -1
- package/config.schema.json +4 -0
- package/migrations/001-initial.sql +12 -6
- package/package.json +1 -1
- package/util/fs-util.d.ts +27 -21
- package/util/fs-util.js +89 -101
- package/util/math-util.js +2 -0
- package/util/process-util.d.ts +1 -0
- package/util/process-util.js +20 -4
- package/util/string-util.d.ts +1 -0
- package/util/string-util.js +8 -1
- package/util/zip-util.d.ts +64 -19
- package/util/zip-util.js +156 -59
package/util/zip-util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.unzip = exports.zip = exports.buildArguments = void 0;
|
|
3
|
+
exports.unzip = exports.zip = exports.listZip = exports.checkSSEOption = exports.buildArguments = void 0;
|
|
4
4
|
const process_util_1 = require("./process-util");
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
function buildArguments(filters) {
|
|
@@ -30,45 +30,101 @@ function buildArguments(filters) {
|
|
|
30
30
|
return args;
|
|
31
31
|
}
|
|
32
32
|
exports.buildArguments = buildArguments;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
let checkSSEOptionResult;
|
|
34
|
+
async function checkSSEOption(command = "7z") {
|
|
35
|
+
const result = await (0, process_util_1.exec)(command);
|
|
36
|
+
if (typeof checkSSEOptionResult === "boolean")
|
|
37
|
+
return checkSSEOptionResult;
|
|
38
|
+
return (checkSSEOptionResult = result.stdout.includes(" -sse"));
|
|
39
|
+
}
|
|
40
|
+
exports.checkSSEOption = checkSSEOption;
|
|
41
|
+
const listZipLineEqChar = " = ";
|
|
42
|
+
function parseListZipLine(line, buffer) {
|
|
43
|
+
if (buffer.started) {
|
|
44
|
+
if (line === "") {
|
|
45
|
+
if (buffer.opened) {
|
|
46
|
+
const { stream } = buffer;
|
|
47
|
+
buffer.stream = {};
|
|
48
|
+
buffer.opened = false;
|
|
49
|
+
return stream;
|
|
50
|
+
}
|
|
49
51
|
}
|
|
50
|
-
else
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
folders: Number(folders),
|
|
57
|
-
files: Number(files),
|
|
58
|
-
},
|
|
59
|
-
});
|
|
52
|
+
else {
|
|
53
|
+
const separator = line.indexOf(listZipLineEqChar);
|
|
54
|
+
const key = line.slice(0, separator);
|
|
55
|
+
const value = line.slice(separator + listZipLineEqChar.length);
|
|
56
|
+
buffer.opened = true;
|
|
57
|
+
buffer.stream[key] = value;
|
|
60
58
|
}
|
|
61
59
|
}
|
|
60
|
+
else if (line.startsWith("----------")) {
|
|
61
|
+
buffer.started = true;
|
|
62
|
+
buffer.stream = {};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function listZip(data) {
|
|
66
|
+
const buffer = {};
|
|
67
|
+
await (0, process_util_1.exec)(data.command ?? "7z", ["l", data.path, "-slt"], {}, {
|
|
68
|
+
log: {
|
|
69
|
+
exec: data.verbose ?? false,
|
|
70
|
+
stderr: data.verbose ?? false,
|
|
71
|
+
stdout: false,
|
|
72
|
+
},
|
|
73
|
+
onExitCodeError: (data, error) => (data.exitCode > 2 ? error : false),
|
|
74
|
+
stdout: {
|
|
75
|
+
parseLines: true,
|
|
76
|
+
onData: async (line) => {
|
|
77
|
+
const stream = parseListZipLine(line, buffer);
|
|
78
|
+
if (stream) {
|
|
79
|
+
await data.onStream?.(stream);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
exports.listZip = listZip;
|
|
86
|
+
function parseZipLine(line) {
|
|
87
|
+
let matches = null;
|
|
88
|
+
line = line.trim();
|
|
89
|
+
if (!line.length)
|
|
90
|
+
return;
|
|
91
|
+
if ((matches = /^(\d+)% (\d+ )?\+/.exec(line))) {
|
|
92
|
+
const path = line.slice(line.indexOf("+") + 1).trim();
|
|
93
|
+
const progress = Number(matches[1]);
|
|
94
|
+
const files = matches[2] ? Number(matches[2]) : 1;
|
|
95
|
+
return {
|
|
96
|
+
type: "progress",
|
|
97
|
+
data: { progress, path, files },
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
else if (line.startsWith("Add new data to archive:")) {
|
|
101
|
+
const [, folders] = /(\d+) folders?/i.exec(line) || [, 0];
|
|
102
|
+
const [, files] = /(\d+) files?/i.exec(line) || [, 0];
|
|
103
|
+
return {
|
|
104
|
+
type: "summary",
|
|
105
|
+
data: {
|
|
106
|
+
folders: Number(folders),
|
|
107
|
+
files: Number(files),
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
62
111
|
}
|
|
63
112
|
async function zip(data) {
|
|
64
|
-
let
|
|
113
|
+
let summary = {
|
|
65
114
|
folders: 0,
|
|
66
115
|
files: 0,
|
|
67
116
|
};
|
|
68
|
-
|
|
117
|
+
await data.onProgress?.({
|
|
118
|
+
current: 0,
|
|
119
|
+
percent: 0,
|
|
120
|
+
total: 0,
|
|
121
|
+
type: "start",
|
|
122
|
+
});
|
|
69
123
|
await (0, process_util_1.exec)(data.command ?? "7z", [
|
|
70
124
|
"a",
|
|
71
|
-
|
|
125
|
+
// https://sourceforge.net/p/sevenzip/bugs/2099/,
|
|
126
|
+
// https://github.com/mcmilk/7-Zip/commit/87ba6f01ba3c5b2ce3186bddfe3d7d880639193c#diff-779d6b1bfa6196b288478f78ca96c4d4c6d7ac6cf8be15a28a20dabc9137ca36L515
|
|
127
|
+
...((await checkSSEOption(data.command)) ? [] : ["-mmt1"]),
|
|
72
128
|
"-bsp1",
|
|
73
129
|
...(data.deleteOnZip ? ["-sdel"] : []),
|
|
74
130
|
(0, path_1.normalize)(data.output),
|
|
@@ -79,41 +135,61 @@ async function zip(data) {
|
|
|
79
135
|
cwd: data.path,
|
|
80
136
|
}, {
|
|
81
137
|
log: data.verbose ?? false,
|
|
82
|
-
|
|
83
|
-
toExitCode: true,
|
|
84
|
-
},
|
|
138
|
+
onExitCodeError: (data, error) => (data.exitCode > 2 ? error : false),
|
|
85
139
|
stdout: {
|
|
86
|
-
onData: (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (stream
|
|
90
|
-
|
|
91
|
-
|
|
140
|
+
onData: async (lines) => {
|
|
141
|
+
for (const line of lines.split(/\r?\n/)) {
|
|
142
|
+
const stream = parseZipLine(line);
|
|
143
|
+
if (stream) {
|
|
144
|
+
if (stream.type === "summary")
|
|
145
|
+
summary = stream.data;
|
|
146
|
+
if (stream.type === "progress") {
|
|
147
|
+
const current = Math.max(0, stream.data.files - 1);
|
|
148
|
+
await data.onProgress?.({
|
|
149
|
+
total: summary.files,
|
|
150
|
+
current,
|
|
151
|
+
path: stream.data.path,
|
|
152
|
+
percent: stream.data.progress,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
await data.onStream?.(stream);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
92
158
|
},
|
|
93
159
|
},
|
|
94
160
|
});
|
|
95
|
-
|
|
161
|
+
await data.onProgress?.({
|
|
162
|
+
total: summary.files,
|
|
163
|
+
current: summary.files,
|
|
164
|
+
percent: 100,
|
|
165
|
+
type: "end",
|
|
166
|
+
});
|
|
167
|
+
return summary;
|
|
96
168
|
}
|
|
97
169
|
exports.zip = zip;
|
|
98
|
-
function
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
data: { progress, path, files },
|
|
109
|
-
});
|
|
110
|
-
}
|
|
170
|
+
function parseUnzipLine(line) {
|
|
171
|
+
let matches = null;
|
|
172
|
+
if ((matches = /^\s*(\d+)% (\d+) \-/.exec(line))) {
|
|
173
|
+
const progress = Number(matches[1]);
|
|
174
|
+
const files = Number(matches[2]);
|
|
175
|
+
const path = line.slice(line.indexOf("-") + 1).trim();
|
|
176
|
+
return {
|
|
177
|
+
type: "progress",
|
|
178
|
+
data: { percent: progress, path, files },
|
|
179
|
+
};
|
|
111
180
|
}
|
|
112
181
|
}
|
|
113
182
|
async function unzip(data) {
|
|
114
|
-
|
|
183
|
+
let summary = {
|
|
184
|
+
files: 0,
|
|
185
|
+
};
|
|
186
|
+
await data.onProgress?.({
|
|
187
|
+
current: summary.files,
|
|
188
|
+
percent: 0,
|
|
189
|
+
type: "start",
|
|
190
|
+
});
|
|
191
|
+
const result = await (0, process_util_1.exec)(data.command ?? "7z", [
|
|
115
192
|
"x",
|
|
116
|
-
"-mmt1",
|
|
117
193
|
"-bsp1",
|
|
118
194
|
(0, path_1.normalize)(data.input),
|
|
119
195
|
...buildArguments(data.files ?? []),
|
|
@@ -123,13 +199,34 @@ async function unzip(data) {
|
|
|
123
199
|
log: data.verbose ?? false,
|
|
124
200
|
stderr: { toExitCode: true },
|
|
125
201
|
stdout: {
|
|
126
|
-
...(data.onStream && {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
202
|
+
...((data.onStream || data.onProgress) && {
|
|
203
|
+
parseLines: true,
|
|
204
|
+
onData: async (line) => {
|
|
205
|
+
const stream = parseUnzipLine(line);
|
|
206
|
+
if (stream) {
|
|
207
|
+
if (stream.type === "progress") {
|
|
208
|
+
const current = Math.max(0, stream.data.files - 1);
|
|
209
|
+
summary.files = stream.data.files;
|
|
210
|
+
await data.onProgress?.({
|
|
211
|
+
current,
|
|
212
|
+
percent: stream.data.percent,
|
|
213
|
+
path: stream.data.path,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
await data.onStream?.(stream);
|
|
217
|
+
}
|
|
130
218
|
},
|
|
131
219
|
}),
|
|
132
220
|
},
|
|
133
221
|
});
|
|
222
|
+
await data.onProgress?.({
|
|
223
|
+
current: summary.files,
|
|
224
|
+
percent: 100,
|
|
225
|
+
type: "end",
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
...result,
|
|
229
|
+
...summary,
|
|
230
|
+
};
|
|
134
231
|
}
|
|
135
232
|
exports.unzip = unzip;
|