@datatruck/cli 0.3.0 → 0.4.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.
@@ -1,3 +1,4 @@
1
+ import { GlobalOptionsType } from "../Command/CommandAbstract";
1
2
  import type { ConfigType } from "../Config/Config";
2
3
  import { IfRequireKeys } from "../util/ts-util";
3
4
  export declare type ConfigActionOptionsType = {
@@ -10,5 +11,9 @@ export declare class ConfigAction<TRequired extends boolean = true> {
10
11
  static validate(config: ConfigType): void;
11
12
  static check(config: ConfigType): void;
12
13
  static normalize(config: ConfigType): ConfigType;
13
- exec(): Promise<ConfigType>;
14
+ static fromGlobalOptions(globalOptions: GlobalOptionsType<true>): Promise<ConfigType>;
15
+ exec(): Promise<{
16
+ path: string;
17
+ data: ConfigType;
18
+ }>;
14
19
  }
@@ -53,12 +53,28 @@ class ConfigAction {
53
53
  });
54
54
  return config;
55
55
  }
56
+ static async fromGlobalOptions(globalOptions) {
57
+ if (typeof globalOptions.config === "string") {
58
+ const configAction = new ConfigAction({
59
+ path: globalOptions.config,
60
+ verbose: !!globalOptions.verbose && globalOptions.verbose > 0,
61
+ });
62
+ const result = await configAction.exec();
63
+ return result.data;
64
+ }
65
+ else {
66
+ return globalOptions.config;
67
+ }
68
+ }
56
69
  async exec() {
57
70
  const path = await (0, fs_util_1.findFile)(this.options.path, "datatruck.config", fs_util_1.parseFileExtensions, "Config path not found");
58
71
  const config = await (0, fs_util_1.parseFile)(path, "config");
59
72
  ConfigAction.validate(config);
60
73
  ConfigAction.check(config);
61
- return ConfigAction.normalize(config);
74
+ return {
75
+ path,
76
+ data: ConfigAction.normalize(config),
77
+ };
62
78
  }
63
79
  }
64
80
  exports.ConfigAction = ConfigAction;
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @datatruck/cli
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`eeb00a6`](https://github.com/swordev/datatruck/commit/eeb00a69d75c91da40711ae79475612b1d5193b6) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `tempDir` config option
8
+
9
+ ## 0.3.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [`8957c3b`](https://github.com/swordev/datatruck/commit/8957c3b5846606db8b825fef357445210f2a3ac3) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix restic progress parser
14
+
15
+ * [`2989718`](https://github.com/swordev/datatruck/commit/29897185e3d6659359d51ab2212351005137f86c) Thanks [@juanrgm](https://github.com/juanrgm)! - Show closing reason
16
+
17
+ - [`b9e0843`](https://github.com/swordev/datatruck/commit/b9e0843c7970944cfd30a7d2a543f515adfa60e4) Thanks [@juanrgm](https://github.com/juanrgm)! - Show restic progress in megabytes
18
+
19
+ ## 0.3.1
20
+
21
+ ### Patch Changes
22
+
23
+ - [`c3bb4c6`](https://github.com/swordev/datatruck/commit/c3bb4c609887c5525cf35487ea237750addb6e75) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix restic stdout parser
24
+
3
25
  ## 0.3.0
4
26
 
5
27
  ### Minor Changes
@@ -44,11 +44,7 @@ class BackupCommand extends CommandAbstract_1.CommandAbstract {
44
44
  }
45
45
  async onExec() {
46
46
  const verbose = this.globalOptions.verbose ?? 0;
47
- const configAction = new ConfigAction_1.ConfigAction({
48
- path: this.globalOptions.config,
49
- verbose: verbose > 0,
50
- });
51
- const config = await configAction.exec();
47
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
52
48
  const backup = new BackupAction_1.BackupAction(config, {
53
49
  packageNames: this.options.package,
54
50
  repositoryNames: this.options.repository,
@@ -37,11 +37,7 @@ class BackupSessionsCommand extends CommandAbstract_1.CommandAbstract {
37
37
  }
38
38
  async onExec() {
39
39
  const verbose = this.globalOptions.verbose ?? 0;
40
- const configAction = new ConfigAction_1.ConfigAction({
41
- path: this.globalOptions.config,
42
- verbose: verbose > 0,
43
- });
44
- const config = await configAction.exec();
40
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
45
41
  const action = new BackupSessionsAction_1.BackupSessionsAction(config, {
46
42
  packageNames: this.options.package,
47
43
  repositoryNames: this.options.repository,
@@ -1,8 +1,9 @@
1
+ import { ConfigType } from "../Config/Config";
1
2
  import { FormatType } from "../util/DataFormat";
2
3
  import { OptionsType } from "../util/cli-util";
3
4
  import { SimilarObject } from "../util/ts-util";
4
5
  export declare type GlobalOptionsType<TResolved = false> = {
5
- config: string;
6
+ config: string | ConfigType;
6
7
  outputFormat?: FormatType;
7
8
  verbose?: number;
8
9
  };
@@ -27,11 +27,7 @@ class ConfigCommand extends CommandAbstract_1.CommandAbstract {
27
27
  });
28
28
  }
29
29
  async onExec() {
30
- const configAction = new ConfigAction_1.ConfigAction({
31
- path: this.globalOptions.config,
32
- verbose: !!this.globalOptions.verbose,
33
- });
34
- const config = await configAction.exec();
30
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
35
31
  const packages = (0, config_util_1.filterPackages)(config, {
36
32
  packageNames: this.options.package,
37
33
  repositoryNames: this.options.repository,
@@ -25,11 +25,7 @@ class InitCommand extends CommandAbstract_1.CommandAbstract {
25
25
  }
26
26
  async onExec() {
27
27
  const verbose = this.globalOptions.verbose ?? 0;
28
- const configAction = new ConfigAction_1.ConfigAction({
29
- path: this.globalOptions.config,
30
- verbose: verbose > 0,
31
- });
32
- const config = await configAction.exec();
28
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
33
29
  const init = new InitAction_1.InitAction(config, {
34
30
  repositoryNames: this.options.repository,
35
31
  repositoryTypes: this.options.repositoryType,
@@ -101,11 +101,7 @@ class PruneCommand extends CommandAbstract_1.CommandAbstract {
101
101
  }
102
102
  async onExec() {
103
103
  const verbose = this.globalOptions.verbose ?? 0;
104
- const configAction = new ConfigAction_1.ConfigAction({
105
- path: this.globalOptions.config,
106
- verbose: verbose > 0,
107
- });
108
- const config = await configAction.exec();
104
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
109
105
  const prune = new PruneAction_1.PruneAction(config, {
110
106
  ids: this.options.id,
111
107
  packageNames: this.options.package,
@@ -40,11 +40,7 @@ class RestoreCommand extends CommandAbstract_1.CommandAbstract {
40
40
  }
41
41
  async onExec() {
42
42
  const verbose = this.globalOptions.verbose ?? 0;
43
- const configAction = new ConfigAction_1.ConfigAction({
44
- path: this.globalOptions.config,
45
- verbose: verbose > 0,
46
- });
47
- const config = await configAction.exec();
43
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
48
44
  const restore = new RestoreAction_1.RestoreAction(config, {
49
45
  snapshotId: this.options.id,
50
46
  packageNames: this.options.package,
@@ -37,11 +37,7 @@ class RestoreSessionsCommand extends CommandAbstract_1.CommandAbstract {
37
37
  }
38
38
  async onExec() {
39
39
  const verbose = this.globalOptions.verbose ?? 0;
40
- const configAction = new ConfigAction_1.ConfigAction({
41
- path: this.globalOptions.config,
42
- verbose: verbose > 0,
43
- });
44
- const config = await configAction.exec();
40
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
45
41
  const action = new RestoreSessionsAction_1.RestoreSessionsAction(config, {
46
42
  packageNames: this.options.package,
47
43
  repositoryNames: this.options.repository,
@@ -83,11 +83,7 @@ class SnapshotsCommand extends CommandAbstract_1.CommandAbstract {
83
83
  }
84
84
  async onExec() {
85
85
  const verbose = this.globalOptions.verbose ?? 0;
86
- const configAction = new ConfigAction_1.ConfigAction({
87
- path: this.globalOptions.config,
88
- verbose: verbose > 0,
89
- });
90
- const config = await configAction.exec();
86
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptions(this.globalOptions);
91
87
  const snapshots = new SnapshotsAction_1.SnapshotsAction(config, {
92
88
  ids: this.options.id,
93
89
  packageNames: this.options.package,
@@ -2,6 +2,7 @@ import { PackageConfigType } from "./PackageConfig";
2
2
  import { RepositoryConfigType } from "./RepositoryConfig";
3
3
  import type { JSONSchema7 } from "json-schema";
4
4
  export declare type ConfigType = {
5
+ tempDir?: string;
5
6
  repositories: RepositoryConfigType[];
6
7
  packages: PackageConfigType[];
7
8
  };
package/Config/Config.js CHANGED
@@ -8,6 +8,7 @@ exports.configDefinition = {
8
8
  additionalProperties: false,
9
9
  properties: {
10
10
  $schema: { type: "string" },
11
+ tempDir: { type: "string" },
11
12
  repositories: {
12
13
  type: "array",
13
14
  items: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.repository),
@@ -210,8 +210,10 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
210
210
  onStream: async (streamData) => {
211
211
  if (streamData.message_type === "status") {
212
212
  await data.onProgress({
213
- total: streamData.total_bytes,
214
- current: streamData.bytes_done ?? 0,
213
+ total: Number((streamData.total_bytes / 1024 / 1024).toFixed(2)),
214
+ current: streamData.bytes_done
215
+ ? Number((streamData.bytes_done / 1024 / 1024).toFixed(2))
216
+ : 0,
215
217
  percent: Number((streamData.percent_done * 100).toFixed(2)),
216
218
  step: streamData.current_files?.join(", ") ?? "-",
217
219
  });
package/cli.js CHANGED
@@ -1,8 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.exec = exports.parseArgs = exports.buildArgs = void 0;
7
+ const ConfigAction_1 = require("./Action/ConfigAction");
4
8
  const AppError_1 = require("./Error/AppError");
5
9
  const CommandFactory_1 = require("./Factory/CommandFactory");
10
+ const globalData_1 = __importDefault(require("./globalData"));
6
11
  const cli_util_1 = require("./util/cli-util");
7
12
  const fs_util_1 = require("./util/fs-util");
8
13
  const process_util_1 = require("./util/process-util");
@@ -35,7 +40,19 @@ function makeCommandAction(command) {
35
40
  let exitCode = 1;
36
41
  const globalOptions = getGlobalOptions();
37
42
  try {
38
- exitCode = await (0, CommandFactory_1.CommandFactory)(command, getGlobalOptions(), options).onExec();
43
+ const configAction = new ConfigAction_1.ConfigAction({
44
+ path: globalOptions.config,
45
+ verbose: !!globalOptions.verbose,
46
+ });
47
+ const config = await configAction.exec();
48
+ if (config.data.tempDir)
49
+ globalData_1.default.tempDir = (0, path_1.isAbsolute)(config.data.tempDir)
50
+ ? config.data.tempDir
51
+ : (0, path_1.join)((0, path_1.dirname)(config.path), config.data.tempDir);
52
+ exitCode = await (0, CommandFactory_1.CommandFactory)(command, {
53
+ ...globalOptions,
54
+ config: config.data,
55
+ }, options).onExec();
39
56
  }
40
57
  catch (e) {
41
58
  const error = e;
@@ -84,10 +101,12 @@ exports.buildArgs = buildArgs;
84
101
  function parseArgs(args) {
85
102
  program.parse(args);
86
103
  const verbose = getGlobalOptions().verbose;
87
- (0, process_util_1.onExit)((eventName) => {
104
+ (0, process_util_1.onExit)((eventName, error) => {
88
105
  if (eventName !== "exit") {
89
106
  process.stdout.write(cli_util_1.showCursorCommand);
90
- console.log("\nClosing...");
107
+ console.log(`\nClosing... (reason: ${eventName})`);
108
+ if (error instanceof Error)
109
+ console.error((0, chalk_1.red)(error.stack));
91
110
  }
92
111
  if (!verbose)
93
112
  try {
@@ -769,6 +769,9 @@
769
769
  "$schema": {
770
770
  "type": "string"
771
771
  },
772
+ "tempDir": {
773
+ "type": "string"
774
+ },
772
775
  "repositories": {
773
776
  "type": "array",
774
777
  "items": {
@@ -0,0 +1,5 @@
1
+ declare const globalData: {
2
+ configDir?: string;
3
+ tempDir: string;
4
+ };
5
+ export default globalData;
package/globalData.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const os_1 = require("os");
4
+ const globalData = {
5
+ tempDir: (0, os_1.tmpdir)(),
6
+ };
7
+ exports.default = globalData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "dependencies": {
5
5
  "ajv": "^8.11.0",
6
6
  "chalk": "^4.1.2",
@@ -117,8 +117,17 @@ class ResticUtil {
117
117
  stdout: {
118
118
  ...(options.onStream && {
119
119
  onData: async (data) => {
120
- if (data.startsWith("{") && data.endsWith("}")) {
121
- await options.onStream?.(JSON.parse(data));
120
+ for (const rawLine of data.split("\n")) {
121
+ const line = rawLine.trim();
122
+ if (line.startsWith("{") && line.endsWith("}")) {
123
+ let parsedLine;
124
+ try {
125
+ parsedLine = JSON.parse(line);
126
+ }
127
+ catch (error) { }
128
+ if (parsedLine)
129
+ await options.onStream?.(parsedLine);
130
+ }
122
131
  }
123
132
  },
124
133
  }),
package/util/fs-util.js CHANGED
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.writePathLists = exports.writeGitIgnoreList = exports.forEachFile = exports.checkDir = exports.checkFile = exports.readPartialFile = exports.mkTmpDir = exports.tmpDir = exports.sessionTmpDir = exports.parentTmpDir = exports.existsFile = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.readdirIfExists = exports.writeJSONFile = exports.existsDir = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isDirEmpty = exports.isLocalDir = void 0;
7
+ const globalData_1 = __importDefault(require("../globalData"));
4
8
  const path_util_1 = require("./path-util");
5
9
  const crypto_1 = require("crypto");
6
10
  const fs_1 = require("fs");
@@ -8,7 +12,6 @@ const fs_2 = require("fs");
8
12
  const fs_extra_1 = require("fs-extra");
9
13
  const promises_1 = require("fs/promises");
10
14
  const micromatch_1 = require("micromatch");
11
- const os_1 = require("os");
12
15
  const path_1 = require("path");
13
16
  const path_2 = require("path");
14
17
  function isLocalDir(path) {
@@ -110,8 +113,7 @@ async function existsFile(path) {
110
113
  }
111
114
  exports.existsFile = existsFile;
112
115
  function parentTmpDir() {
113
- const tmpDir = (0, os_1.tmpdir)();
114
- return (0, path_1.join)(tmpDir, "datatruck");
116
+ return (0, path_1.join)(globalData_1.default.tempDir, "datatruck-temp");
115
117
  }
116
118
  exports.parentTmpDir = parentTmpDir;
117
119
  function sessionTmpDir() {
@@ -46,5 +46,5 @@ export declare type ExecResultType = {
46
46
  };
47
47
  export declare function exec(command: string, argv?: string[], options?: SpawnOptions | null, settings?: ExecSettingsInterface): Promise<ExecResultType>;
48
48
  declare type EventNameType = "exit" | "SIGINT" | "SIGUSR1" | "SIGUSR2" | "SIGTERM" | "uncaughtException";
49
- export declare function onExit(cb: (eventName: EventNameType) => void): void;
49
+ export declare function onExit(cb: (eventName: EventNameType, ...args: any[]) => void): void;
50
50
  export {};
@@ -175,7 +175,7 @@ const eventNames = [
175
175
  ];
176
176
  function onExit(cb) {
177
177
  for (const eventName of eventNames) {
178
- process.on(eventName, cb.bind(null, eventName));
178
+ process.on(eventName, (...args) => cb(eventName, ...args));
179
179
  }
180
180
  }
181
181
  exports.onExit = onExit;