@datatruck/cli 0.21.0 → 0.21.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.
@@ -9,6 +9,9 @@ export type MetaDataType = {
9
9
  tags: string[];
10
10
  version: string;
11
11
  size: number;
12
+ tarStats?: Record<string, {
13
+ files: number;
14
+ }>;
12
15
  };
13
16
  export type DatatruckRepositoryConfigType = {
14
17
  outPath: string;
@@ -213,22 +213,26 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
213
213
  });
214
214
  await stream.end();
215
215
  let packIndex = 0;
216
+ const tarStats = {};
216
217
  for (const pack of packs) {
217
218
  const packBasename = [`pack`, packIndex.toString(), pack.name]
218
219
  .filter((v) => typeof v === "string")
219
220
  .map((v) => encodeURIComponent(v.toString().replace(/[\\/]/g, "-")))
220
- .join("-");
221
- const ext = pack.compress ? `.tar.gz` : `.tar`;
221
+ .join("-") + (pack.compress ? `.tar.gz` : `.tar`);
222
222
  const includeList = stream.path(packIndex);
223
- if (includeList)
223
+ if (includeList) {
224
+ tarStats[packBasename] = {
225
+ files: stream.lines(packIndex),
226
+ };
224
227
  await (0, tar_1.createTar)({
225
228
  compress: pack.compress,
226
229
  verbose: data.options.verbose,
227
230
  includeList,
228
231
  path: sourcePath,
229
- output: (0, path_1.join)(outPath, packBasename) + ext,
232
+ output: (0, path_1.join)(outPath, packBasename),
230
233
  onEntry: async (data) => await scanner.progress(pack.compress ? "Compressing" : "Packing", data.path),
231
234
  });
235
+ }
232
236
  packIndex++;
233
237
  }
234
238
  await scanner.end();
@@ -243,6 +247,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
243
247
  task: data.package.task?.name,
244
248
  version: nodePkg.version,
245
249
  size: await (0, fs_1.fastFolderSizeAsync)(outPath),
250
+ tarStats,
246
251
  };
247
252
  if (data.options.verbose)
248
253
  (0, cli_1.logExec)(`Writing metadata into ${metaPath}`);
@@ -298,6 +303,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
298
303
  packageName: data.package.name,
299
304
  });
300
305
  const sourcePath = (0, path_1.join)(this.config.outPath, snapshotName);
306
+ const metaPath = (0, path_1.join)(sourcePath, "meta.json");
307
+ const meta = await DatatruckRepository.parseMetaData(metaPath);
301
308
  const scanner = await (0, fs_1.createFileScanner)({
302
309
  onProgress: data.onProgress,
303
310
  glob: {
@@ -306,26 +313,37 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
306
313
  },
307
314
  });
308
315
  const tarFiles = [];
316
+ const tarStats = meta?.tarStats || {};
309
317
  await scanner.start(async (entry) => {
310
318
  const path = (0, path_1.join)(sourcePath, entry.name);
311
319
  const isTar = entry.name.endsWith(".tar");
312
320
  const isTarGz = entry.name.endsWith(".tar.gz");
313
321
  if (isTar || isTarGz) {
314
322
  tarFiles.push(path);
315
- await (0, tar_1.listTar)({
316
- input: path,
317
- verbose: data.options.verbose,
318
- onEntry: () => {
319
- scanner.total++;
320
- },
321
- });
323
+ if (typeof tarStats[entry.name]?.files === "number") {
324
+ scanner.total += tarStats[entry.name].files;
325
+ }
326
+ else {
327
+ scanner.progress("Scanning", entry.name, false);
328
+ const selfTarStats = (tarStats[entry.name] = { files: 0 });
329
+ await (0, tar_1.listTar)({
330
+ input: path,
331
+ verbose: data.options.verbose,
332
+ onEntry: () => {
333
+ scanner.total++;
334
+ selfTarStats.files++;
335
+ },
336
+ });
337
+ }
322
338
  }
323
339
  return false;
324
340
  });
325
341
  if (data.options.verbose)
326
342
  (0, cli_1.logExec)(`Unpacking files to ${restorePath}`);
327
343
  for (const tarFile of tarFiles) {
344
+ const entryName = (0, path_1.basename)(tarFile);
328
345
  await (0, tar_1.extractTar)({
346
+ total: tarStats[entryName].files,
329
347
  input: tarFile,
330
348
  output: restorePath,
331
349
  decompress: tarFile.endsWith(".tar.gz"),
@@ -4,7 +4,7 @@ export declare const mysqlDumpTaskName = "mysql-dump";
4
4
  export type MysqlDumpTaskConfigType = {} & SqlDumpTaskConfigType;
5
5
  export declare const mysqlDumpTaskDefinition: JSONSchema7;
6
6
  export declare class MysqlDumpTask extends SqlDumpTaskAbstract<MysqlDumpTaskConfigType> {
7
- buildConnectionArgs(database?: boolean): Promise<string[]>;
7
+ buildConnectionArgs(database?: string): Promise<string[]>;
8
8
  onDatabaseIsEmpty(name: string): Promise<boolean>;
9
9
  onCreateDatabase(database: TargetDatabaseType): Promise<void>;
10
10
  onExecQuery(query: string): Promise<import("../utils/process").ExecResultType>;
@@ -13,14 +13,14 @@ exports.mysqlDumpTaskDefinition = {
13
13
  allOf: [(0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.sqlDumpTask)],
14
14
  };
15
15
  class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
16
- async buildConnectionArgs(database = true) {
16
+ async buildConnectionArgs(database) {
17
17
  const password = await this.fetchPassword();
18
18
  return [
19
19
  `--host=${this.config.hostname}`,
20
20
  ...(this.config.port ? [`--port=${this.config.port}`] : []),
21
21
  `--user=${this.config.username}`,
22
22
  `--password=${password ?? ""}`,
23
- ...(database && this.config.database ? [this.config.database] : []),
23
+ ...(database ? [database] : []),
24
24
  ];
25
25
  }
26
26
  async onDatabaseIsEmpty(name) {
@@ -78,7 +78,7 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
78
78
  stream.on("error", reject);
79
79
  }),
80
80
  await (0, process_1.exec)("mysqldump", [
81
- ...(await this.buildConnectionArgs()),
81
+ ...(await this.buildConnectionArgs(this.config.database)),
82
82
  "--lock-tables=false",
83
83
  "--skip-add-drop-table=false",
84
84
  ...tableNames,
@@ -120,7 +120,7 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
120
120
  stream.on("error", reject);
121
121
  }),
122
122
  await (0, process_1.exec)("mysqldump", [
123
- ...(await this.buildConnectionArgs()),
123
+ ...(await this.buildConnectionArgs(this.config.database)),
124
124
  "--lock-tables=false",
125
125
  "--routines",
126
126
  "--events",
@@ -143,7 +143,7 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
143
143
  ]);
144
144
  }
145
145
  async onImport(path, database) {
146
- await (0, process_1.exec)("mysql", [...(await this.buildConnectionArgs(false)), database], null, {
146
+ await (0, process_1.exec)("mysql", await this.buildConnectionArgs(database), null, {
147
147
  pipe: {
148
148
  stream: (0, fs_3.createReadStream)(path),
149
149
  onReadProgress: (data) => {
@@ -81,7 +81,7 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
81
81
  stream.on("error", reject);
82
82
  }),
83
83
  (0, process_1.exec)("pg_dump", [
84
- ...(await this.buildConnectionArgs()),
84
+ ...(await this.buildConnectionArgs(this.config.database)),
85
85
  ...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
86
86
  ], null, {
87
87
  pipe: { stream, onWriteProgress: onProgress },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "dependencies": {
5
5
  "ajv": "^8.12.0",
6
6
  "async": "^3.2.4",
package/utils/fs.d.ts CHANGED
@@ -96,12 +96,13 @@ export declare function createFileScanner(options: {
96
96
  disposed: boolean;
97
97
  total: number;
98
98
  current: number;
99
- progress: (description: string, path?: string) => Promise<void>;
99
+ progress: (description: string, path?: string, increment?: boolean) => Promise<void>;
100
100
  end: () => Promise<void>;
101
101
  start: (cb?: ((entry: Required<Entry>) => any) | undefined) => Promise<void>;
102
102
  }>;
103
103
  type StreamItem = {
104
104
  key: string;
105
+ lines: number;
105
106
  stream: WriteStream;
106
107
  finished: boolean;
107
108
  error?: Error;
@@ -113,6 +114,7 @@ export declare function createWriteStreamPool(options: {
113
114
  }): {
114
115
  pool: Record<string, StreamItem>;
115
116
  path(key: string | number): string | undefined;
117
+ lines(key: string | number): number;
116
118
  writeLine(key: string | number, v: string): boolean;
117
119
  end(): Promise<void>;
118
120
  };
package/utils/fs.js CHANGED
@@ -410,10 +410,10 @@ async function createFileScanner(options) {
410
410
  disposed: false,
411
411
  total: 0,
412
412
  current: 0,
413
- progress: async (description, path) => {
413
+ progress: async (description, path, increment = true) => {
414
414
  if (object.disposed)
415
415
  return;
416
- if (path)
416
+ if (path && increment)
417
417
  object.current++;
418
418
  await options.onProgress({
419
419
  relative: {
@@ -463,6 +463,7 @@ function createWriteStreamPool(options) {
463
463
  const create = (key) => {
464
464
  const item = {
465
465
  key,
466
+ lines: 0,
466
467
  stream: (0, fs_2.createWriteStream)((0, path_2.join)(options.path, options.onStreamPath ? options.onStreamPath(key) : key)),
467
468
  finished: false,
468
469
  };
@@ -484,16 +485,22 @@ function createWriteStreamPool(options) {
484
485
  throw new Error(`Stream path is not defined: ${key}`);
485
486
  return item.stream.path;
486
487
  },
488
+ lines(key) {
489
+ const item = pool[key];
490
+ return item?.lines;
491
+ },
487
492
  writeLine(key, v) {
488
493
  const item = pool[key] || create(key.toString());
489
494
  if (item.finished) {
490
495
  return false;
491
496
  }
492
497
  else if (item.written) {
498
+ item.lines++;
493
499
  return item.stream.write(`\n${v}`);
494
500
  }
495
501
  else {
496
502
  item.written = true;
503
+ item.lines++;
497
504
  return item.stream.write(`${v}`);
498
505
  }
499
506
  },
package/utils/tar.js CHANGED
@@ -137,21 +137,23 @@ async function createTar(options) {
137
137
  }, {
138
138
  log: options.verbose ? { envNames: Object.keys(env) } : false,
139
139
  stderr: { toExitCode: true },
140
- stdout: {
141
- parseLines: "skip-empty",
142
- onData: (line) => {
143
- current++;
144
- const path = vendor === "bsdtar" ? line.slice(2) : line;
145
- options.onEntry?.({
146
- path,
147
- progress: {
148
- total,
149
- current,
150
- percent: (0, math_1.progressPercent)(total, current),
151
- },
152
- });
153
- },
154
- },
140
+ stdout: options.onEntry
141
+ ? {
142
+ parseLines: "skip-empty",
143
+ onData: (line) => {
144
+ current++;
145
+ const path = vendor === "bsdtar" ? line.slice(2) : line;
146
+ options.onEntry?.({
147
+ path,
148
+ progress: {
149
+ total,
150
+ current,
151
+ percent: (0, math_1.progressPercent)(total, current),
152
+ },
153
+ });
154
+ },
155
+ }
156
+ : undefined,
155
157
  });
156
158
  }
157
159
  exports.createTar = createTar;
@@ -164,10 +166,11 @@ function toLocalPath(path) {
164
166
  async function extractTar(options) {
165
167
  let total = options.total ??
166
168
  (await listTar({ input: options.input, verbose: options.verbose }));
167
- if (options.verbose)
168
- (0, cli_1.logExec)("mkdir", ["-p", options.output]);
169
- await (0, promises_1.mkdir)(options.output, { recursive: true });
170
- await (0, fs_1.ensureEmptyDir)(options.output);
169
+ if (!(await (0, fs_1.existsDir)(options.output))) {
170
+ if (options.verbose)
171
+ (0, cli_1.logExec)("mkdir", ["-p", options.output]);
172
+ await (0, promises_1.mkdir)(options.output, { recursive: true });
173
+ }
171
174
  const decompress = await ifX(options.decompress, async (decompress) => ({
172
175
  ...decompress,
173
176
  cores: await resolveCores(decompress.cores),
@@ -192,20 +195,22 @@ async function extractTar(options) {
192
195
  stderr: {
193
196
  toExitCode: true,
194
197
  },
195
- stdout: {
196
- parseLines: "skip-empty",
197
- onData: (path) => {
198
- current++;
199
- options.onEntry?.({
200
- path,
201
- progress: {
202
- total,
203
- current,
204
- percent: (0, math_1.progressPercent)(total, current),
205
- },
206
- });
207
- },
208
- },
198
+ stdout: options.onEntry
199
+ ? {
200
+ parseLines: "skip-empty",
201
+ onData: (path) => {
202
+ current++;
203
+ options.onEntry?.({
204
+ path,
205
+ progress: {
206
+ total,
207
+ current,
208
+ percent: (0, math_1.progressPercent)(total, current),
209
+ },
210
+ });
211
+ },
212
+ }
213
+ : undefined,
209
214
  });
210
215
  }
211
216
  exports.extractTar = extractTar;