@datatruck/cli 0.34.3 → 0.34.5

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.
Files changed (48) hide show
  1. package/lib/actions/BackupAction.js +125 -39
  2. package/lib/actions/ConfigAction.js +1 -1
  3. package/lib/actions/CopyAction.js +110 -74
  4. package/lib/actions/InitAction.js +1 -1
  5. package/lib/actions/PruneAction.js +3 -2
  6. package/lib/actions/RestoreAction.d.ts +0 -2
  7. package/lib/actions/RestoreAction.js +131 -62
  8. package/lib/cli.js +1 -1
  9. package/lib/commands/StartServerCommand.js +2 -1
  10. package/lib/repositories/DatatruckRepository.d.ts +1 -1
  11. package/lib/repositories/DatatruckRepository.js +31 -18
  12. package/lib/repositories/GitRepository.js +11 -3
  13. package/lib/repositories/RepositoryAbstract.d.ts +2 -1
  14. package/lib/repositories/RepositoryAbstract.js +3 -1
  15. package/lib/repositories/ResticRepository.js +1 -1
  16. package/lib/tasks/GitTask.js +2 -1
  17. package/lib/tasks/MssqlTask.js +2 -2
  18. package/lib/tasks/MysqlDumpTask.js +1 -1
  19. package/lib/tasks/SqlDumpTaskAbstract.js +2 -2
  20. package/lib/utils/async-process.js +3 -2
  21. package/lib/utils/cli.js +10 -10
  22. package/lib/utils/data-format.js +3 -3
  23. package/lib/utils/datatruck/client.d.ts +7 -3
  24. package/lib/utils/datatruck/client.js +9 -2
  25. package/lib/utils/datatruck/command.js +1 -1
  26. package/lib/utils/datatruck/config.js +4 -4
  27. package/lib/utils/datatruck/report-list.js +2 -1
  28. package/lib/utils/datatruck/repository.d.ts +3 -3
  29. package/lib/utils/datatruck/repository.js +4 -4
  30. package/lib/utils/datatruck/task.js +1 -1
  31. package/lib/utils/{datatruck/error.d.ts → error.d.ts} +1 -1
  32. package/lib/utils/{datatruck/error.js → error.js} +2 -2
  33. package/lib/utils/fs.d.ts +2 -1
  34. package/lib/utils/fs.js +22 -3
  35. package/lib/utils/git.d.ts +5 -0
  36. package/lib/utils/git.js +10 -0
  37. package/lib/utils/list.d.ts +3 -1
  38. package/lib/utils/list.js +2 -3
  39. package/lib/utils/mysql.js +1 -1
  40. package/lib/utils/object.d.ts +1 -1
  41. package/lib/utils/object.js +1 -1
  42. package/lib/utils/progress.d.ts +8 -1
  43. package/lib/utils/progress.js +38 -5
  44. package/lib/utils/reportSteps.js +3 -2
  45. package/lib/utils/string.js +1 -1
  46. package/lib/utils/temp.d.ts +13 -10
  47. package/lib/utils/temp.js +47 -40
  48. package/package.json +1 -1
@@ -1,4 +1,49 @@
1
1
  "use strict";
2
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
3
+ if (value !== null && value !== void 0) {
4
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
5
+ var dispose;
6
+ if (async) {
7
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
8
+ dispose = value[Symbol.asyncDispose];
9
+ }
10
+ if (dispose === void 0) {
11
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
12
+ dispose = value[Symbol.dispose];
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ env.stack.push({ value: value, dispose: dispose, async: async });
16
+ }
17
+ else if (async) {
18
+ env.stack.push({ async: true });
19
+ }
20
+ return value;
21
+ };
22
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
23
+ return function (env) {
24
+ function fail(e) {
25
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
26
+ env.hasError = true;
27
+ }
28
+ function next() {
29
+ while (env.stack.length) {
30
+ var rec = env.stack.pop();
31
+ try {
32
+ var result = rec.dispose && rec.dispose.call(rec.value);
33
+ if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
34
+ }
35
+ catch (e) {
36
+ fail(e);
37
+ }
38
+ }
39
+ if (env.hasError) throw env.error;
40
+ }
41
+ return next();
42
+ };
43
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
44
+ var e = new Error(message);
45
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
46
+ });
2
47
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
48
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
49
  };
@@ -10,6 +55,7 @@ const config_1 = require("../utils/datatruck/config");
10
55
  const repository_1 = require("../utils/datatruck/repository");
11
56
  const task_1 = require("../utils/datatruck/task");
12
57
  const date_1 = require("../utils/date");
58
+ const error_1 = require("../utils/error");
13
59
  const fs_1 = require("../utils/fs");
14
60
  const list_1 = require("../utils/list");
15
61
  const progress_1 = require("../utils/progress");
@@ -70,27 +116,25 @@ class RestoreAction {
70
116
  const repoConfig = (0, config_1.findRepositoryOrFail)(this.config, snapshot.repositoryName);
71
117
  const repo = await (0, repository_1.createAndInitRepo)(repoConfig, this.options.verbose);
72
118
  let snapshotPath = pkg.restorePath ?? pkg.path;
73
- await data.gc.cleanupIfFail(async () => {
74
- if (task) {
75
- const taskResult = await task.prepareRestore({
76
- options: this.options,
77
- package: pkg,
78
- snapshot,
79
- });
80
- snapshotPath = taskResult?.snapshotPath;
81
- }
82
- await (0, fs_1.initEmptyDir)(snapshotPath);
83
- if (this.config.minFreeDiskSpace)
84
- await (0, fs_1.ensureFreeDiskSpace)([snapshotPath], this.config.minFreeDiskSpace);
85
- await repo.restore({
119
+ if (task) {
120
+ const taskResult = await task.prepareRestore({
86
121
  options: this.options,
87
- snapshot: data.snapshot,
88
122
  package: pkg,
89
- snapshotPath: snapshotPath,
90
- packageConfig: pkg.repositoryConfigs?.find((config) => config.type === repoConfig.type &&
91
- (!config.names || config.names.includes(repoConfig.name)))?.config,
92
- onProgress: data.onProgress,
123
+ snapshot,
93
124
  });
125
+ snapshotPath = taskResult?.snapshotPath;
126
+ }
127
+ await (0, fs_1.initEmptyDir)(snapshotPath);
128
+ if (this.config.minFreeDiskSpace)
129
+ await (0, fs_1.ensureFreeDiskSpace)([snapshotPath], this.config.minFreeDiskSpace);
130
+ await repo.restore({
131
+ options: this.options,
132
+ snapshot: data.snapshot,
133
+ package: pkg,
134
+ snapshotPath: snapshotPath,
135
+ packageConfig: pkg.repositoryConfigs?.find((config) => config.type === repoConfig.type &&
136
+ (!config.names || config.names.includes(repoConfig.name)))?.config,
137
+ onProgress: data.onProgress,
94
138
  });
95
139
  return { snapshotPath };
96
140
  }
@@ -138,6 +182,7 @@ class RestoreAction {
138
182
  }
139
183
  async exec() {
140
184
  const { options } = this;
185
+ const gc = new temp_1.GargabeCollector();
141
186
  const pm = new progress_1.ProgressManager({
142
187
  verbose: options.verbose,
143
188
  tty: options.tty,
@@ -146,6 +191,7 @@ class RestoreAction {
146
191
  const l = new list_1.Listr3({
147
192
  streams: options.streams,
148
193
  progressManager: pm,
194
+ gargabeCollector: gc,
149
195
  });
150
196
  return l
151
197
  .add(l.$task({
@@ -165,10 +211,10 @@ class RestoreAction {
165
211
  if (minFreeDiskSpace)
166
212
  await (0, temp_1.ensureFreeDiskTempSpace)(minFreeDiskSpace);
167
213
  if (!options.snapshotId)
168
- throw new Error("Snapshot id is required");
214
+ throw new error_1.AppError("Snapshot id is required");
169
215
  const snapshots = this.groupSnapshots(await this.findSnapshots());
170
216
  if (!snapshots.length)
171
- throw new Error("None snapshot found");
217
+ throw new error_1.AppError("None snapshot found");
172
218
  data.id = options.snapshotId;
173
219
  data.packages = snapshots.length;
174
220
  return snapshots.map((snapshot) => l.$task({
@@ -183,48 +229,71 @@ class RestoreAction {
183
229
  },
184
230
  exitOnError: false,
185
231
  run: async (listTask) => {
186
- let pkg = (0, config_1.resolvePackage)((0, config_1.findPackageOrFail)(this.config, snapshot.packageName), {
187
- snapshotId: options.snapshotId,
188
- snapshotDate: snapshot.date,
189
- action: "restore",
190
- });
191
- if (this.options.initial)
192
- pkg = { ...pkg, restorePath: pkg.path };
193
- const gc = new temp_1.GargabeCollector();
194
- const task = pkg.task ? (0, task_1.createTask)(pkg.task) : undefined;
195
- const restore = await this.restore({
196
- gc,
197
- pkg,
198
- task,
199
- snapshot: snapshot,
200
- onProgress: (p) => pm.update(p, (t) => (listTask.output = t)),
201
- });
202
- if (!task)
203
- return await gc.cleanup();
204
- return l.$tasks({
205
- key: "task",
206
- keyIndex: pkg.name,
207
- data: { taskName: pkg.task.name, packageName: pkg.name },
208
- title: {
209
- initial: `Execute task: ${pkg.name} (${pkg.task.name})`,
210
- started: `Executing task: ${pkg.name} (${pkg.task.name})`,
211
- completed: `Task executed: ${pkg.name} (${pkg.task.name})`,
212
- failed: `Task execute failed: ${pkg.name} (${pkg.task.name})`,
213
- },
214
- exitOnError: false,
215
- runWrapper: gc.cleanup.bind(gc),
216
- run: async (listTask) => {
217
- const { snapshotPath } = restore;
218
- (0, assert_1.ok)(snapshotPath);
219
- await task.restore({
220
- package: pkg,
221
- options,
222
- snapshot,
223
- snapshotPath,
224
- onProgress: (p) => pm.update(p, (t) => (listTask.output = t)),
225
- });
226
- },
227
- });
232
+ const env_1 = { stack: [], error: void 0, hasError: false };
233
+ try {
234
+ let pkg = (0, config_1.resolvePackage)((0, config_1.findPackageOrFail)(this.config, snapshot.packageName), {
235
+ snapshotId: options.snapshotId,
236
+ snapshotDate: snapshot.date,
237
+ action: "restore",
238
+ });
239
+ if (this.options.initial)
240
+ pkg = { ...pkg, restorePath: pkg.path };
241
+ const task = pkg.task ? (0, task_1.createTask)(pkg.task) : undefined;
242
+ const progress = __addDisposableResource(env_1, pm.create(listTask), false);
243
+ const restoreGc = gc.create();
244
+ const restore = await restoreGc.disposeIfFail(() => this.restore({
245
+ pkg,
246
+ task,
247
+ snapshot: snapshot,
248
+ onProgress: progress.update,
249
+ }));
250
+ if (!task)
251
+ return await restoreGc.dispose();
252
+ return l.$tasks({
253
+ key: "task",
254
+ keyIndex: pkg.name,
255
+ data: { taskName: pkg.task.name, packageName: pkg.name },
256
+ title: {
257
+ initial: `Execute task: ${pkg.name} (${pkg.task.name})`,
258
+ started: `Executing task: ${pkg.name} (${pkg.task.name})`,
259
+ completed: `Task executed: ${pkg.name} (${pkg.task.name})`,
260
+ failed: `Task execute failed: ${pkg.name} (${pkg.task.name})`,
261
+ },
262
+ exitOnError: false,
263
+ run: async (listTask) => {
264
+ const env_2 = { stack: [], error: void 0, hasError: false };
265
+ try {
266
+ const _ = __addDisposableResource(env_2, restoreGc.disposeOnFinish(), true);
267
+ const { snapshotPath } = restore;
268
+ (0, assert_1.ok)(snapshotPath);
269
+ const progress = __addDisposableResource(env_2, pm.create(listTask), false);
270
+ await task.restore({
271
+ package: pkg,
272
+ options,
273
+ snapshot,
274
+ snapshotPath,
275
+ onProgress: progress.update,
276
+ });
277
+ }
278
+ catch (e_2) {
279
+ env_2.error = e_2;
280
+ env_2.hasError = true;
281
+ }
282
+ finally {
283
+ const result_1 = __disposeResources(env_2);
284
+ if (result_1)
285
+ await result_1;
286
+ }
287
+ },
288
+ });
289
+ }
290
+ catch (e_1) {
291
+ env_1.error = e_1;
292
+ env_1.hasError = true;
293
+ }
294
+ finally {
295
+ __disposeResources(env_1);
296
+ }
228
297
  },
229
298
  }));
230
299
  },
package/lib/cli.js CHANGED
@@ -8,7 +8,7 @@ const ConfigAction_1 = require("./actions/ConfigAction");
8
8
  const globalData_1 = __importDefault(require("./globalData"));
9
9
  const cli_1 = require("./utils/cli");
10
10
  const command_1 = require("./utils/datatruck/command");
11
- const error_1 = require("./utils/datatruck/error");
11
+ const error_1 = require("./utils/error");
12
12
  const exit_1 = require("./utils/exit");
13
13
  const fs_1 = require("./utils/fs");
14
14
  const string_1 = require("./utils/string");
@@ -4,6 +4,7 @@ exports.StartServerCommand = void 0;
4
4
  const ConfigAction_1 = require("../actions/ConfigAction");
5
5
  const cron_server_1 = require("../utils/datatruck/cron-server");
6
6
  const repository_server_1 = require("../utils/datatruck/repository-server");
7
+ const error_1 = require("../utils/error");
7
8
  const CommandAbstract_1 = require("./CommandAbstract");
8
9
  class StartServerCommand extends CommandAbstract_1.CommandAbstract {
9
10
  optionsConfig() {
@@ -31,7 +32,7 @@ class StartServerCommand extends CommandAbstract_1.CommandAbstract {
31
32
  const cronOptions = config.server?.cron || {};
32
33
  if (cronOptions.enabled ?? true) {
33
34
  if (typeof this.configPath !== "string")
34
- throw new Error(`Config path is required by cron server`);
35
+ throw new error_1.AppError(`Config path is required by cron server`);
35
36
  const server = (0, cron_server_1.createCronServer)(cronOptions, {
36
37
  verbose,
37
38
  log,
@@ -12,7 +12,7 @@ export type MetaData = {
12
12
  files: number;
13
13
  size: number;
14
14
  checksum: string;
15
- }>;
15
+ } | undefined>;
16
16
  };
17
17
  export type DatatruckRepositoryConfig = {
18
18
  backend: string;
@@ -4,8 +4,8 @@ exports.DatatruckRepository = exports.datatruckRepositoryName = void 0;
4
4
  const cli_1 = require("../utils/cli");
5
5
  const crypto_1 = require("../utils/crypto");
6
6
  const client_1 = require("../utils/datatruck/client");
7
- const error_1 = require("../utils/datatruck/error");
8
7
  const paths_1 = require("../utils/datatruck/paths");
8
+ const error_1 = require("../utils/error");
9
9
  const fs_1 = require("../utils/fs");
10
10
  const math_1 = require("../utils/math");
11
11
  const string_1 = require("../utils/string");
@@ -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,9 +63,9 @@ 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
- throw new Error(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
68
+ throw new error_1.AppError(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
69
69
  const snapshots = [];
70
70
  const snapshotNames = await fs.readdir(".");
71
71
  const packagePatterns = (0, string_1.makePathPatterns)(data.options.packageNames);
@@ -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)
@@ -147,7 +147,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
147
147
  scanner.total++;
148
148
  stream.writeLine(defaultsPackIndex, ".");
149
149
  await scanner.start(async (entry) => {
150
- let packIndex = configPacks.findIndex((pack) => (0, string_1.match)(entry.path, pack.include, pack.exclude));
150
+ let packIndex = packs.findIndex((pack) => pack !== defaultsPack &&
151
+ (0, string_1.match)(entry.path, pack.include, pack.exclude));
151
152
  if (packIndex === -1)
152
153
  packIndex = defaultsPackIndex;
153
154
  const pack = packs[packIndex];
@@ -176,11 +177,11 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
176
177
  .join("-") + (pack.compress ? `.tar.gz` : `.tar`);
177
178
  const includeList = stream.path(packIndex);
178
179
  if (includeList) {
179
- tarStats[packBasename] = {
180
+ const stats = (tarStats[packBasename] = {
180
181
  files: stream.lines(packIndex),
181
182
  size: 0,
182
183
  checksum: "",
183
- };
184
+ });
184
185
  const tarPath = (0, path_1.join)(outPath, packBasename);
185
186
  await (0, tar_1.createTar)({
186
187
  compress: pack.compress,
@@ -191,8 +192,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
191
192
  onEntry: async (data) => scanner.progress(pack.compress ? "Compressing" : "Packing", data.path),
192
193
  });
193
194
  scanner.progress("Fetching tar stats", (0, path_1.basename)(tarPath), false);
194
- tarStats[packBasename].checksum = await (0, crypto_1.calcFileHash)(tarPath, "sha1");
195
- tarStats[packBasename].size = (await (0, promises_1.stat)(tarPath)).size;
195
+ stats.checksum = await (0, crypto_1.calcFileHash)(tarPath, "sha1");
196
+ stats.size = (await (0, promises_1.stat)(tarPath)).size;
196
197
  if (!fs.isLocal()) {
197
198
  scanner.progress("Uploading tar", (0, path_1.basename)(tarPath), false);
198
199
  await fs.upload(tarPath, `${snapshotName}/${packBasename}`);
@@ -203,7 +204,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
203
204
  }
204
205
  scanner.end();
205
206
  // Meta
206
- const size = Object.values(tarStats).reduce((total, { size }) => total + size, 0);
207
+ const size = Object.values(tarStats).reduce((total, stat) => total + stat.size, 0);
207
208
  const metaPath = `${snapshotName}/meta.json`;
208
209
  const nodePkg = (0, fs_1.parsePackageFile)();
209
210
  const meta = {
@@ -224,8 +225,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
224
225
  };
225
226
  }
226
227
  async copy(data) {
227
- const sourceFs = (0, client_1.createFs)(this.config.backend);
228
- 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);
229
230
  const snapshotName = DatatruckRepository.buildSnapshotName(data.snapshot, data.package);
230
231
  if (data.options.verbose)
231
232
  (0, cli_1.logExec)(`Copying backup files to ${data.mirrorRepositoryConfig.backend}`);
@@ -261,6 +262,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
261
262
  relative: {
262
263
  description: "Downloading",
263
264
  format: "size",
265
+ payload: entry,
264
266
  ...progress,
265
267
  },
266
268
  }),
@@ -277,6 +279,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
277
279
  relative: {
278
280
  description: "Downloading",
279
281
  format: "size",
282
+ payload: entry,
280
283
  ...progress,
281
284
  },
282
285
  }),
@@ -293,7 +296,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
293
296
  return { bytes };
294
297
  }
295
298
  async restore(data) {
296
- const fs = (0, client_1.createFs)(this.config.backend);
299
+ const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
297
300
  const relRestorePath = data.snapshotPath;
298
301
  (0, assert_1.ok)(relRestorePath);
299
302
  const restorePath = (0, path_1.resolve)(relRestorePath);
@@ -322,10 +325,20 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
322
325
  if (!fs.isLocal()) {
323
326
  const tempDir = await (0, temp_1.mkTmpDir)(exports.datatruckRepositoryName, "repo", "restore", "remote-fs", entry);
324
327
  tempEntry = `${tempDir}/${entry}`;
325
- 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
+ });
326
336
  }
337
+ const stats = tarStats[entry];
338
+ if (data.options.verbose)
339
+ (0, cli_1.logExec)(`Stats of '${entry}' is not available`);
327
340
  await (0, tar_1.extractTar)({
328
- total: tarStats[entry].files,
341
+ total: stats?.files,
329
342
  input: tempEntry ?? fs.resolvePath(sourceEntry),
330
343
  output: restorePath,
331
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.exec(["commit", "-m", "Initial commit", "--allow-empty"]);
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.exec(["commit", "-m", data.snapshot.id]);
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) {
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ResticRepository = exports.resticRepositoryName = void 0;
7
7
  const cli_1 = require("../utils/cli");
8
- const error_1 = require("../utils/datatruck/error");
9
8
  const paths_1 = require("../utils/datatruck/paths");
9
+ const error_1 = require("../utils/error");
10
10
  const fs_1 = require("../utils/fs");
11
11
  const math_1 = require("../utils/math");
12
12
  const restic_1 = require("../utils/restic");
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GitTask = exports.gitTaskName = void 0;
4
4
  const async_process_1 = require("../utils/async-process");
5
5
  const cli_1 = require("../utils/cli");
6
+ const error_1 = require("../utils/error");
6
7
  const fs_1 = require("../utils/fs");
7
8
  const math_1 = require("../utils/math");
8
9
  const stream_1 = require("../utils/stream");
@@ -21,7 +22,7 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
21
22
  }
22
23
  async backup(data) {
23
24
  if (!data.package.path)
24
- throw new Error(`Path is required`);
25
+ throw new error_1.AppError(`'package.path' is required`);
25
26
  const snapshotPath = await (0, temp_1.mkTmpDir)(exports.gitTaskName, "task", "backup", "snapshot");
26
27
  this.verbose = data.options.verbose;
27
28
  const config = this.config;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MssqlTask = exports.mssqlTaskName = void 0;
4
4
  const async_process_1 = require("../utils/async-process");
5
5
  const config_1 = require("../utils/datatruck/config");
6
- const error_1 = require("../utils/datatruck/error");
6
+ const error_1 = require("../utils/error");
7
7
  const fs_1 = require("../utils/fs");
8
8
  const temp_1 = require("../utils/temp");
9
9
  const TaskAbstract_1 = require("./TaskAbstract");
@@ -51,7 +51,7 @@ class MssqlTask extends TaskAbstract_1.TaskAbstract {
51
51
  async backup(data) {
52
52
  this.verbose = data.options.verbose;
53
53
  if (data.package.path)
54
- throw new Error(`Path is not required: ${data.package.path}`);
54
+ throw new error_1.AppError(`'package.path' is required: ${data.package.path}`);
55
55
  const snapshotPath = await (0, temp_1.mkTmpDir)(exports.mssqlTaskName, "task", "backup", "snapshot");
56
56
  const databaseNames = (await this.fetchDatabaseNames()).filter((databaseName) => (!this.config.includeDatabases ||
57
57
  (0, micromatch_1.isMatch)(databaseName, this.config.includeDatabases)) &&
@@ -4,7 +4,7 @@ exports.MysqlDumpTask = exports.mysqlDumpTaskName = void 0;
4
4
  const async_1 = require("../utils/async");
5
5
  const cli_1 = require("../utils/cli");
6
6
  const config_1 = require("../utils/datatruck/config");
7
- const error_1 = require("../utils/datatruck/error");
7
+ const error_1 = require("../utils/error");
8
8
  const fs_1 = require("../utils/fs");
9
9
  const math_1 = require("../utils/math");
10
10
  const mysql_1 = require("../utils/mysql");
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqlDumpTaskAbstract = void 0;
4
4
  const cli_1 = require("../utils/cli");
5
5
  const config_1 = require("../utils/datatruck/config");
6
- const error_1 = require("../utils/datatruck/error");
6
+ const error_1 = require("../utils/error");
7
7
  const fs_1 = require("../utils/fs");
8
8
  const math_1 = require("../utils/math");
9
9
  const temp_1 = require("../utils/temp");
@@ -42,7 +42,7 @@ function parseSqlFile(fileName) {
42
42
  return { fileName, database: lastName };
43
43
  }
44
44
  else {
45
- throw new Error(`Invalid sql file type: ${type}`);
45
+ throw new error_1.AppError(`Invalid SQL file type: ${type}`);
46
46
  }
47
47
  }
48
48
  class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AsyncProcess = void 0;
4
4
  const cli_1 = require("./cli");
5
+ const error_1 = require("./error");
5
6
  const math_1 = require("./math");
6
7
  const process_1 = require("./process");
7
8
  const stream_1 = require("./stream");
@@ -22,7 +23,7 @@ function ensureDir(cwd) {
22
23
  }
23
24
  catch (error) { }
24
25
  if (!isDir)
25
- throw new Error(`Current working directory does not exist: ${cwd}`);
26
+ throw new error_1.AppError(`Current working directory does not exist: ${cwd}`);
26
27
  }
27
28
  }
28
29
  class StdIn {
@@ -215,7 +216,7 @@ class AsyncProcess {
215
216
  else if (result === false) {
216
217
  return exitCode;
217
218
  }
218
- return new Error(message, {
219
+ return new error_1.AppError(message, {
219
220
  cause: {
220
221
  command: this.command,
221
222
  argv: this.argv,
package/lib/utils/cli.js CHANGED
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.confirm = exports.stringifyOptions = exports.parseOptions = exports.renderObject = exports.renderListTaskItem = exports.renderError = exports.renderResult = exports.logExec = exports.renderProgressBar = exports.showCursorCommand = void 0;
7
+ const error_1 = require("./error");
7
8
  const chalk_1 = __importDefault(require("chalk"));
8
9
  const chalk_2 = require("chalk");
9
10
  const readline_1 = require("readline");
@@ -59,20 +60,19 @@ function renderResult(error, color = true) {
59
60
  }
60
61
  exports.renderResult = renderResult;
61
62
  function renderError(error, verbose) {
62
- let message = null;
63
- if (typeof error === "string") {
64
- message = error;
63
+ if (!error) {
64
+ return "";
65
65
  }
66
- else if (error) {
67
- message = error.message;
66
+ else if (error instanceof error_1.AppError) {
67
+ return chalk_1.default.red(verbose ? error.stack ?? error.message : error.message);
68
68
  }
69
- else {
70
- return "";
69
+ else if (error instanceof Error) {
70
+ return chalk_1.default.red(error.stack ?? error.message);
71
71
  }
72
- if (!verbose) {
73
- message = message.split(/\r?\n/).shift() ?? "";
72
+ else {
73
+ const message = error.split(/\r?\n/).shift() ?? "";
74
+ return chalk_1.default.red(message.trim());
74
75
  }
75
- return chalk_1.default.red(message.trim());
76
76
  }
77
77
  exports.renderError = renderError;
78
78
  function renderListTaskItem(item, color, config) {