@datatruck/cli 0.34.4 → 0.35.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.
@@ -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,7 +63,7 @@ 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
68
  throw new error_1.AppError(`Repository (${this.repository.name}) out path does not exist: ${fs.resolvePath(".")}`);
69
69
  const snapshots = [];
@@ -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)
@@ -177,11 +177,11 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
177
177
  .join("-") + (pack.compress ? `.tar.gz` : `.tar`);
178
178
  const includeList = stream.path(packIndex);
179
179
  if (includeList) {
180
- tarStats[packBasename] = {
180
+ const stats = (tarStats[packBasename] = {
181
181
  files: stream.lines(packIndex),
182
182
  size: 0,
183
183
  checksum: "",
184
- };
184
+ });
185
185
  const tarPath = (0, path_1.join)(outPath, packBasename);
186
186
  await (0, tar_1.createTar)({
187
187
  compress: pack.compress,
@@ -192,8 +192,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
192
192
  onEntry: async (data) => scanner.progress(pack.compress ? "Compressing" : "Packing", data.path),
193
193
  });
194
194
  scanner.progress("Fetching tar stats", (0, path_1.basename)(tarPath), false);
195
- tarStats[packBasename].checksum = await (0, crypto_1.calcFileHash)(tarPath, "sha1");
196
- 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;
197
197
  if (!fs.isLocal()) {
198
198
  scanner.progress("Uploading tar", (0, path_1.basename)(tarPath), false);
199
199
  await fs.upload(tarPath, `${snapshotName}/${packBasename}`);
@@ -204,7 +204,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
204
204
  }
205
205
  scanner.end();
206
206
  // Meta
207
- const size = Object.values(tarStats).reduce((total, { size }) => total + size, 0);
207
+ const size = Object.values(tarStats).reduce((total, stat) => total + stat.size, 0);
208
208
  const metaPath = `${snapshotName}/meta.json`;
209
209
  const nodePkg = (0, fs_1.parsePackageFile)();
210
210
  const meta = {
@@ -225,8 +225,8 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
225
225
  };
226
226
  }
227
227
  async copy(data) {
228
- const sourceFs = (0, client_1.createFs)(this.config.backend);
229
- 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);
230
230
  const snapshotName = DatatruckRepository.buildSnapshotName(data.snapshot, data.package);
231
231
  if (data.options.verbose)
232
232
  (0, cli_1.logExec)(`Copying backup files to ${data.mirrorRepositoryConfig.backend}`);
@@ -296,7 +296,7 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
296
296
  return { bytes };
297
297
  }
298
298
  async restore(data) {
299
- const fs = (0, client_1.createFs)(this.config.backend);
299
+ const fs = (0, client_1.createFs)(this.config.backend, this.verbose);
300
300
  const relRestorePath = data.snapshotPath;
301
301
  (0, assert_1.ok)(relRestorePath);
302
302
  const restorePath = (0, path_1.resolve)(relRestorePath);
@@ -325,10 +325,20 @@ class DatatruckRepository extends RepositoryAbstract_1.RepositoryAbstract {
325
325
  if (!fs.isLocal()) {
326
326
  const tempDir = await (0, temp_1.mkTmpDir)(exports.datatruckRepositoryName, "repo", "restore", "remote-fs", entry);
327
327
  tempEntry = `${tempDir}/${entry}`;
328
- 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
+ });
329
336
  }
337
+ const stats = tarStats[entry];
338
+ if (data.options.verbose)
339
+ (0, cli_1.logExec)(`Stats of '${entry}' is not available`);
330
340
  await (0, tar_1.extractTar)({
331
- total: tarStats[entry].files,
341
+ total: stats?.files,
332
342
  input: tempEntry ?? fs.resolvePath(sourceEntry),
333
343
  output: restorePath,
334
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) {
@@ -0,0 +1,21 @@
1
+ import { TaskBackupData, TaskRestoreData, TaskAbstract } from "./TaskAbstract";
2
+ export type MongoDumpTaskConfig = {
3
+ command?: string;
4
+ hostname?: string;
5
+ port?: number;
6
+ username?: string;
7
+ password?: string | {
8
+ path: string;
9
+ };
10
+ compress?: boolean;
11
+ concurrency?: number;
12
+ };
13
+ export declare const mongodumpTaskName = "mongo-dump";
14
+ export declare class MongoDumpTask extends TaskAbstract<MongoDumpTaskConfig> {
15
+ protected verbose?: boolean;
16
+ private get command();
17
+ backup(data: TaskBackupData): Promise<{
18
+ snapshotPath: string;
19
+ }>;
20
+ restore(data: TaskRestoreData): Promise<void>;
21
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoDumpTask = exports.mongodumpTaskName = void 0;
4
+ const async_process_1 = require("../utils/async-process");
5
+ const fs_1 = require("../utils/fs");
6
+ const temp_1 = require("../utils/temp");
7
+ const TaskAbstract_1 = require("./TaskAbstract");
8
+ exports.mongodumpTaskName = "mongo-dump";
9
+ class MongoDumpTask extends TaskAbstract_1.TaskAbstract {
10
+ verbose;
11
+ get command() {
12
+ return this.config.command ?? "mongodump";
13
+ }
14
+ async backup(data) {
15
+ this.verbose = data.options.verbose;
16
+ const snapshotPath = data.package.path ??
17
+ (await (0, temp_1.mkTmpDir)(exports.mongodumpTaskName, "task", "backup", "snapshot"));
18
+ await (0, fs_1.mkdirIfNotExists)(snapshotPath);
19
+ await (0, fs_1.ensureEmptyDir)(snapshotPath);
20
+ const p = new async_process_1.AsyncProcess(this.command, [
21
+ ...(this.config.hostname ? ["/h", this.config.hostname] : []),
22
+ ...(this.config.port ? ["/p", this.config.port] : []),
23
+ ...(this.config.username ? ["/u", this.config.username] : []),
24
+ ...(this.config.compress ? ["/gzip"] : []),
25
+ ...(this.config.concurrency ? ["/j", this.config.concurrency] : []),
26
+ "/o",
27
+ snapshotPath,
28
+ ], {
29
+ $log: this.verbose,
30
+ });
31
+ const password = this.config.password !== undefined
32
+ ? (await (0, fs_1.fetchData)(this.config.password, (p) => p.path)) ?? ""
33
+ : "";
34
+ p.stdin.writable.write(`${password}\n`);
35
+ await p.stderr.parseLines((line) => {
36
+ data.onProgress({
37
+ absolute: {
38
+ description: line.slice(0, 255),
39
+ },
40
+ });
41
+ });
42
+ return { snapshotPath };
43
+ }
44
+ async restore(data) {
45
+ throw new Error("Not implemented");
46
+ }
47
+ }
48
+ exports.MongoDumpTask = MongoDumpTask;
@@ -64,14 +64,26 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
64
64
  const dumpProcess = new async_process_1.AsyncProcess("pg_dump", [
65
65
  ...(await this.buildConnectionArgs(this.config.database)),
66
66
  ...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
67
- ], { $log: this.verbose });
67
+ ], {
68
+ $log: {
69
+ exec: this.verbose,
70
+ stderr: this.verbose,
71
+ allToStderr: true,
72
+ },
73
+ });
68
74
  await dumpProcess.stdout.pipe(output, onProgress);
69
75
  }
70
76
  async onExportStoredPrograms() {
71
77
  throw new Error(`Method not implemented: onExportStoredPrograms`);
72
78
  }
73
79
  async onImport(path, database) {
74
- await async_process_1.AsyncProcess.exec("psql", [...(await this.buildConnectionArgs(database)), "-f", (0, path_1.normalize)(path)], { $log: this.verbose });
80
+ await async_process_1.AsyncProcess.exec("psql", [...(await this.buildConnectionArgs(database)), "-f", (0, path_1.normalize)(path)], {
81
+ $log: {
82
+ exec: this.verbose,
83
+ stderr: this.verbose,
84
+ allToStderr: true,
85
+ },
86
+ });
75
87
  }
76
88
  }
77
89
  exports.PostgresqlDumpTask = PostgresqlDumpTask;
@@ -2,10 +2,14 @@ import { DiskStats } from "../fs";
2
2
  import { BasicProgress } from "../progress";
3
3
  import { AbstractFs, FsOptions } from "../virtual-fs";
4
4
  export declare class RemoteFs extends AbstractFs {
5
- readonly options: FsOptions;
5
+ readonly options: FsOptions & {
6
+ verbose?: boolean;
7
+ };
6
8
  protected url: string;
7
9
  protected headers: Record<string, string>;
8
- constructor(options: FsOptions);
10
+ constructor(options: FsOptions & {
11
+ verbose?: boolean;
12
+ });
9
13
  isLocal(): boolean;
10
14
  protected fetchJson(name: string, params: any[]): Promise<any>;
11
15
  protected post(name: string, params: any[], data: string): Promise<void>;
@@ -28,4 +32,4 @@ export declare class RemoteFs extends AbstractFs {
28
32
  }>;
29
33
  }
30
34
  export declare function isRemoteBackend(backend: string): boolean;
31
- export declare function createFs(backend: string): AbstractFs;
35
+ export declare function createFs(backend: string, verbose: boolean | undefined): AbstractFs;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createFs = exports.isRemoteBackend = exports.RemoteFs = void 0;
4
+ const cli_1 = require("../cli");
4
5
  const http_1 = require("../http");
5
6
  const virtual_fs_1 = require("../virtual-fs");
6
7
  const repository_server_1 = require("./repository-server");
@@ -69,9 +70,13 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
69
70
  await this.fetchJson("rmAll", [path]);
70
71
  }
71
72
  async fetchDiskStats(path) {
73
+ if (this.options.verbose)
74
+ (0, cli_1.logExec)("fs.fetchDiskStats", [path]);
72
75
  return await this.fetchJson("fetchDiskStats", [path]);
73
76
  }
74
77
  async upload(source, target) {
78
+ if (this.options.verbose)
79
+ (0, cli_1.logExec)("fs.upload", [source, target]);
75
80
  await (0, http_1.uploadFile)(`${this.url}/upload`, source, {
76
81
  headers: this.headers,
77
82
  query: {
@@ -80,6 +85,8 @@ class RemoteFs extends virtual_fs_1.AbstractFs {
80
85
  });
81
86
  }
82
87
  async download(source, target, options = {}) {
88
+ if (this.options.verbose)
89
+ (0, cli_1.logExec)("fs.download", [source, target]);
83
90
  return await (0, http_1.downloadFile)(`${this.url}/download`, target, {
84
91
  ...options,
85
92
  headers: this.headers,
@@ -92,9 +99,9 @@ function isRemoteBackend(backend) {
92
99
  return backend.startsWith("http:") || backend.startsWith("https:");
93
100
  }
94
101
  exports.isRemoteBackend = isRemoteBackend;
95
- function createFs(backend) {
102
+ function createFs(backend, verbose) {
96
103
  return isRemoteBackend(backend)
97
- ? new RemoteFs({ backend })
104
+ ? new RemoteFs({ backend, verbose })
98
105
  : new virtual_fs_1.LocalFs({ backend });
99
106
  }
100
107
  exports.createFs = createFs;
@@ -1,5 +1,6 @@
1
1
  import type { GitTaskConfig, gitTaskName } from "../../tasks/GitTask";
2
2
  import type { MariadbTaskConfig, mariadbTaskName } from "../../tasks/MariadbTask";
3
+ import { MongoDumpTaskConfig, mongodumpTaskName } from "../../tasks/MongoDumpTask";
3
4
  import type { MssqlTaskConfig, mssqlTaskName } from "../../tasks/MssqlTask";
4
5
  import type { MysqlDumpTaskConfig, mysqlDumpTaskName } from "../../tasks/MysqlDumpTask";
5
6
  import type { PostgresqlDumpTaskConfig, postgresqlDumpTaskName } from "../../tasks/PostgresqlDumpTask";
@@ -24,8 +25,12 @@ export type PostgresqlDumpTaskConfigItem = {
24
25
  name: typeof postgresqlDumpTaskName;
25
26
  config: PostgresqlDumpTaskConfig;
26
27
  };
28
+ export type MongodumpTaskConfigItem = {
29
+ name: typeof mongodumpTaskName;
30
+ config: MongoDumpTaskConfig;
31
+ };
27
32
  export type ScriptTaskConfigItem = {
28
33
  name: typeof scriptTaskName;
29
34
  config: ScriptTaskConfig;
30
35
  };
31
- export type TaskConfig = GitTaskConfigItem | MariadbTaskConfigItem | MssqlTaskConfigItem | MysqlDumpTaskConfigItem | PostgresqlDumpTaskConfigItem | ScriptTaskConfigItem;
36
+ export type TaskConfig = GitTaskConfigItem | MariadbTaskConfigItem | MssqlTaskConfigItem | MysqlDumpTaskConfigItem | PostgresqlDumpTaskConfigItem | MongodumpTaskConfigItem | ScriptTaskConfigItem;
@@ -8,14 +8,14 @@ const micromatch_1 = require("micromatch");
8
8
  function findRepositoryOrFail(config, repositoryName) {
9
9
  const repo = config.repositories.find((v) => v.name === repositoryName);
10
10
  if (!repo)
11
- throw new error_1.AppError(`Repository '${repositoryName}' not found`);
11
+ throw new error_1.AppError(`Repository '${repositoryName}' not found in the config`);
12
12
  return repo;
13
13
  }
14
14
  exports.findRepositoryOrFail = findRepositoryOrFail;
15
15
  function findPackageOrFail(config, packageName) {
16
16
  const pkg = config.packages.find((v) => v.name === packageName);
17
17
  if (!pkg)
18
- throw new error_1.AppError(`Package '${packageName}' not found`);
18
+ throw new error_1.AppError(`Package '${packageName}' not found in the config`);
19
19
  return pkg;
20
20
  }
21
21
  exports.findPackageOrFail = findPackageOrFail;
@@ -9,8 +9,8 @@ declare const repoMap: {
9
9
  datatruck: typeof DatatruckRepository;
10
10
  };
11
11
  export declare function getRepoConstructor(type: keyof typeof repoMap): {
12
- new (config: RepositoryConfig): RepositoryAbstract<any>;
12
+ new (config: RepositoryConfig, verbose?: boolean): RepositoryAbstract<any>;
13
13
  };
14
- export declare function createRepo(repository: RepositoryConfig): RepositoryAbstract<any>;
15
- export declare function createAndInitRepo(repository: RepositoryConfig, verbose?: boolean): Promise<RepositoryAbstract<any>>;
14
+ export declare function createRepo(repository: RepositoryConfig, verbose: boolean | undefined): RepositoryAbstract<any>;
15
+ export declare function createAndInitRepo(repository: RepositoryConfig, verbose: boolean | undefined): Promise<RepositoryAbstract<any>>;
16
16
  export {};
@@ -17,13 +17,13 @@ function getRepoConstructor(type) {
17
17
  return Constructor;
18
18
  }
19
19
  exports.getRepoConstructor = getRepoConstructor;
20
- function createRepo(repository) {
20
+ function createRepo(repository, verbose) {
21
21
  const Constructor = getRepoConstructor(repository.type);
22
- return new Constructor(repository);
22
+ return new Constructor(repository, verbose);
23
23
  }
24
24
  exports.createRepo = createRepo;
25
25
  async function createAndInitRepo(repository, verbose) {
26
- const repo = createRepo(repository);
26
+ const repo = createRepo(repository, verbose);
27
27
  await repo.init({ options: { verbose } });
28
28
  return repo;
29
29
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createTask = void 0;
4
4
  const GitTask_1 = require("../../tasks/GitTask");
5
5
  const MariadbTask_1 = require("../../tasks/MariadbTask");
6
+ const MongoDumpTask_1 = require("../../tasks/MongoDumpTask");
6
7
  const MssqlTask_1 = require("../../tasks/MssqlTask");
7
8
  const MysqlDumpTask_1 = require("../../tasks/MysqlDumpTask");
8
9
  const PostgresqlDumpTask_1 = require("../../tasks/PostgresqlDumpTask");
@@ -24,6 +25,9 @@ function createTask(task) {
24
25
  else if (task.name === MssqlTask_1.mssqlTaskName) {
25
26
  return new MssqlTask_1.MssqlTask(task.config ?? {});
26
27
  }
28
+ else if (task.name === MongoDumpTask_1.mongodumpTaskName) {
29
+ return new MongoDumpTask_1.MongoDumpTask(task.config ?? {});
30
+ }
27
31
  else if (task.name === ScriptTask_1.scriptTaskName) {
28
32
  return new ScriptTask_1.ScriptTask(task.config ?? {});
29
33
  }
package/lib/utils/fs.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
3
  /// <reference types="node" />
4
- import { Progress } from "./progress";
4
+ import { Progress, ProgressStats } from "./progress";
5
5
  import { Entry, Options } from "fast-glob";
6
6
  import { Stats } from "fs";
7
7
  import { WriteStream } from "fs";
@@ -90,6 +90,7 @@ type ProgressObject = {
90
90
  total: number;
91
91
  current: number;
92
92
  update: (description: string, path?: string, increment?: boolean) => void;
93
+ updateRelative: (description: string, path: string, stats: ProgressStats) => void;
93
94
  };
94
95
  export declare function createProgress(options: {
95
96
  onProgress: (data: Progress) => void;
package/lib/utils/fs.js CHANGED
@@ -400,11 +400,29 @@ function createProgress(options) {
400
400
  disposed: false,
401
401
  total: 0,
402
402
  current: 0,
403
+ updateRelative(description, path, stats) {
404
+ if (progress.disposed)
405
+ return;
406
+ options.onProgress({
407
+ relative: {
408
+ ...stats,
409
+ description,
410
+ payload: path,
411
+ },
412
+ absolute: {
413
+ total: progress.total,
414
+ current: progress.current,
415
+ percent: (0, math_1.progressPercent)(progress.total, progress.current),
416
+ },
417
+ });
418
+ },
403
419
  update: (description, path, increment = true) => {
404
420
  if (progress.disposed)
405
421
  return;
406
422
  if (path && increment)
407
423
  progress.current++;
424
+ if (path === "." || path === "./")
425
+ return;
408
426
  options.onProgress({
409
427
  relative: {
410
428
  description,
@@ -28,6 +28,11 @@ export declare class Git {
28
28
  removeAll(): Promise<void>;
29
29
  haveChanges(): Promise<boolean>;
30
30
  fetchCommitId(tag: string): Promise<string>;
31
+ commit(description: string, options?: {
32
+ allowEmpty?: boolean;
33
+ userName?: string;
34
+ userEmail?: string;
35
+ }): Promise<void>;
31
36
  getTags(names?: string[]): Promise<{
32
37
  name: string;
33
38
  message?: string | undefined;
package/lib/utils/git.js CHANGED
@@ -70,6 +70,16 @@ class Git {
70
70
  async fetchCommitId(tag) {
71
71
  return (await this.stdout(["rev-list", "-n", "1", tag])).trim();
72
72
  }
73
+ async commit(description, options = {}) {
74
+ await this.exec([
75
+ ...(options.userName ? ["-c", `user.name='${options.userName}'`] : []),
76
+ ...(options.userEmail ? ["-c", `user.email='${options.userEmail}'`] : []),
77
+ "commit",
78
+ "-m",
79
+ description,
80
+ ...(options.allowEmpty ? ["--allow-empty"] : []),
81
+ ]);
82
+ }
73
83
  async getTags(names) {
74
84
  const stdout = await this.stdout(["tag", "-n", ...(names ?? [])]);
75
85
  return stdout.split(/\r?\n/).reduce((result, value) => {
@@ -1,6 +1,7 @@
1
1
  import { Timer } from "./date";
2
2
  import { ProgressManager } from "./progress";
3
3
  import { StdStreams } from "./stream";
4
+ import { GargabeCollector } from "./temp";
4
5
  import { Listr, ListrGetRendererClassFromValue, ListrLogger, ListrTask, ListrTaskWrapper } from "listr2";
5
6
  export declare class List3Logger<Levels extends string = string> extends ListrLogger<Levels> {
6
7
  constructor(options?: {
@@ -19,7 +20,6 @@ type Listr3Task<T extends Listr3Context, K extends keyof T> = {
19
20
  failed?: string;
20
21
  completed?: string;
21
22
  };
22
- runWrapper?: (cb: () => any) => any;
23
23
  run: (task: ListrTaskWrapper<any, any, any>, data: T[K]) => Promise<void | ListrTask[] | Listr | undefined> | void | undefined | ListrTask[] | Listr;
24
24
  exitOnError?: boolean;
25
25
  enabled?: boolean;
@@ -43,6 +43,7 @@ export declare class Listr3<T extends Listr3Context> extends Listr<void, "defaul
43
43
  readonly $options: {
44
44
  streams?: StdStreams;
45
45
  progressManager?: ProgressManager;
46
+ gargabeCollector?: GargabeCollector;
46
47
  };
47
48
  readonly resultMap: Record<string, Listr3TaskResult<T>>;
48
49
  readonly resultList: Listr3TaskResult<T>[];
@@ -51,6 +52,7 @@ export declare class Listr3<T extends Listr3Context> extends Listr<void, "defaul
51
52
  constructor($options: {
52
53
  streams?: StdStreams;
53
54
  progressManager?: ProgressManager;
55
+ gargabeCollector?: GargabeCollector;
54
56
  });
55
57
  private serializeKeyIndex;
56
58
  private createResultIndex;
package/lib/utils/list.js CHANGED
@@ -89,9 +89,7 @@ class Listr3 extends listr2_1.Listr {
89
89
  const timer = (0, date_1.createTimer)();
90
90
  if (title)
91
91
  try {
92
- const runResult = item.runWrapper
93
- ? await item.runWrapper(async () => await item.run(task, result.data))
94
- : await item.run(task, result.data);
92
+ const runResult = await item.run(task, result.data);
95
93
  if (title.completed)
96
94
  task.title = title.completed;
97
95
  return Array.isArray(runResult)
@@ -153,6 +151,7 @@ class Listr3 extends listr2_1.Listr {
153
151
  throw error;
154
152
  }
155
153
  finally {
154
+ await this.$options.gargabeCollector?.dispose();
156
155
  dispose();
157
156
  }
158
157
  }
@@ -62,8 +62,9 @@ async function createMysqlCli(options) {
62
62
  `user = "${options.username}"`,
63
63
  `password = "${password}"`,
64
64
  ];
65
- await (0, promises_1.writeFile)((sqlConfigPath = (0, path_1.join)(dir, "mysql.conf")), data.join("\n"));
66
- return sqlConfigPath;
65
+ const path = (0, path_1.join)(dir, "mysql.conf");
66
+ await (0, promises_1.writeFile)(path, data.join("\n"));
67
+ return (sqlConfigPath = path);
67
68
  }
68
69
  async function args() {
69
70
  return [`--defaults-file=${await createSqlConfig()}`];
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { Timer } from "./date";
3
4
  export type BasicProgress = {
4
5
  percent: number;
@@ -35,6 +36,7 @@ export declare class ProgressManager {
35
36
  protected interval: Timer | undefined;
36
37
  protected intervalMs: number;
37
38
  protected keydownListener: ((data: Buffer | undefined) => void) | undefined;
39
+ protected pendingProgress: Progress | undefined;
38
40
  readonly tty: Exclude<ProgressTty, "auto">;
39
41
  readonly mode: Exclude<ProgressMode, "auto" | `interval:${number}`>;
40
42
  constructor(options: {
@@ -51,7 +53,12 @@ export declare class ProgressManager {
51
53
  elapsed(): number;
52
54
  start(): void;
53
55
  dispose(): void;
54
- update(progress: Progress, cb: (text: string) => void): void;
56
+ create(input: ((text: string) => void) | {
57
+ output: string;
58
+ }, delay?: number): Disposable & {
59
+ update: (progress: Progress) => void;
60
+ };
61
+ renderProgress(progress: Progress, force?: boolean): string | undefined;
55
62
  }
56
63
  export declare function renderProgress(progress: Progress, bar?: boolean): string[];
57
64
  export declare function renderProgressStats(stats: ProgressStats, progressBar?: boolean): string;