@datatruck/cli 0.36.8 → 0.37.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.
@@ -759,11 +759,12 @@
759
759
  "enabled": {
760
760
  "type": "boolean"
761
761
  },
762
- "actions": {
763
- "type": "array",
764
- "items": {
765
- "$ref": "#/definitions/CronAction"
766
- }
762
+ "logPath": {
763
+ "default": "'/var/logs/datatruck'",
764
+ "type": [
765
+ "string",
766
+ "boolean"
767
+ ]
767
768
  }
768
769
  },
769
770
  "additionalProperties": false
@@ -771,6 +772,12 @@
771
772
  },
772
773
  "additionalProperties": false
773
774
  },
775
+ "jobs": {
776
+ "type": "object",
777
+ "additionalProperties": {
778
+ "$ref": "#/definitions/Job"
779
+ }
780
+ },
774
781
  "reports": {
775
782
  "type": "array",
776
783
  "items": {
@@ -1658,12 +1665,46 @@
1658
1665
  }
1659
1666
  ]
1660
1667
  },
1661
- "CronAction": {
1668
+ "Job": {
1662
1669
  "anyOf": [
1663
1670
  {
1664
1671
  "additionalProperties": false,
1665
1672
  "type": "object",
1666
1673
  "properties": {
1674
+ "action": {
1675
+ "type": "string",
1676
+ "const": "backup"
1677
+ },
1678
+ "options": {
1679
+ "type": "object",
1680
+ "properties": {
1681
+ "package": {
1682
+ "type": "string"
1683
+ },
1684
+ "packageTask": {
1685
+ "type": "string"
1686
+ },
1687
+ "repository": {
1688
+ "type": "string"
1689
+ },
1690
+ "repositoryType": {
1691
+ "type": "string"
1692
+ },
1693
+ "tag": {
1694
+ "type": "string"
1695
+ },
1696
+ "dryRun": {
1697
+ "type": "boolean"
1698
+ },
1699
+ "date": {
1700
+ "type": "string"
1701
+ },
1702
+ "prune": {
1703
+ "type": "boolean"
1704
+ }
1705
+ },
1706
+ "additionalProperties": false
1707
+ },
1667
1708
  "schedule": {
1668
1709
  "anyOf": [
1669
1710
  {
@@ -1771,52 +1812,48 @@
1771
1812
  "type": "string"
1772
1813
  }
1773
1814
  ]
1774
- },
1775
- "name": {
1815
+ }
1816
+ },
1817
+ "required": [
1818
+ "action",
1819
+ "options"
1820
+ ]
1821
+ },
1822
+ {
1823
+ "additionalProperties": false,
1824
+ "type": "object",
1825
+ "properties": {
1826
+ "action": {
1776
1827
  "type": "string",
1777
- "const": "backup"
1828
+ "const": "copy"
1778
1829
  },
1779
1830
  "options": {
1780
1831
  "type": "object",
1781
1832
  "properties": {
1782
- "package": {
1833
+ "id": {
1783
1834
  "type": "string"
1784
1835
  },
1785
- "packageTask": {
1786
- "type": "string"
1836
+ "last": {
1837
+ "type": "number"
1787
1838
  },
1788
- "repository": {
1839
+ "package": {
1789
1840
  "type": "string"
1790
1841
  },
1791
- "repositoryType": {
1842
+ "packageTask": {
1792
1843
  "type": "string"
1793
1844
  },
1794
- "tag": {
1845
+ "repository": {
1795
1846
  "type": "string"
1796
1847
  },
1797
- "dryRun": {
1798
- "type": "boolean"
1799
- },
1800
- "date": {
1848
+ "repository2": {
1801
1849
  "type": "string"
1802
- },
1803
- "prune": {
1804
- "type": "boolean"
1805
1850
  }
1806
1851
  },
1807
- "additionalProperties": false
1808
- }
1809
- },
1810
- "required": [
1811
- "name",
1812
- "options",
1813
- "schedule"
1814
- ]
1815
- },
1816
- {
1817
- "additionalProperties": false,
1818
- "type": "object",
1819
- "properties": {
1852
+ "additionalProperties": false,
1853
+ "required": [
1854
+ "repository"
1855
+ ]
1856
+ },
1820
1857
  "schedule": {
1821
1858
  "anyOf": [
1822
1859
  {
@@ -1924,49 +1961,24 @@
1924
1961
  "type": "string"
1925
1962
  }
1926
1963
  ]
1927
- },
1928
- "name": {
1929
- "type": "string",
1930
- "const": "copy"
1931
- },
1932
- "options": {
1933
- "type": "object",
1934
- "properties": {
1935
- "id": {
1936
- "type": "string"
1937
- },
1938
- "last": {
1939
- "type": "number"
1940
- },
1941
- "package": {
1942
- "type": "string"
1943
- },
1944
- "packageTask": {
1945
- "type": "string"
1946
- },
1947
- "repository": {
1948
- "type": "string"
1949
- },
1950
- "repository2": {
1951
- "type": "string"
1952
- }
1953
- },
1954
- "additionalProperties": false,
1955
- "required": [
1956
- "repository"
1957
- ]
1958
1964
  }
1959
1965
  },
1960
1966
  "required": [
1961
- "name",
1962
- "options",
1963
- "schedule"
1967
+ "action",
1968
+ "options"
1964
1969
  ]
1965
1970
  },
1966
1971
  {
1967
1972
  "additionalProperties": false,
1968
1973
  "type": "object",
1969
1974
  "properties": {
1975
+ "action": {
1976
+ "type": "string",
1977
+ "const": "prune"
1978
+ },
1979
+ "options": {
1980
+ "$ref": "#/definitions/Omit<PruneCommandOptions,\"confirm\">"
1981
+ },
1970
1982
  "schedule": {
1971
1983
  "anyOf": [
1972
1984
  {
@@ -2074,19 +2086,11 @@
2074
2086
  "type": "string"
2075
2087
  }
2076
2088
  ]
2077
- },
2078
- "name": {
2079
- "type": "string",
2080
- "const": "prune"
2081
- },
2082
- "options": {
2083
- "$ref": "#/definitions/Omit<PruneCommandOptions,\"confirm\">"
2084
2089
  }
2085
2090
  },
2086
2091
  "required": [
2087
- "name",
2088
- "options",
2089
- "schedule"
2092
+ "action",
2093
+ "options"
2090
2094
  ]
2091
2095
  }
2092
2096
  ]
@@ -77,7 +77,12 @@ export declare class BackupAction<TRequired extends boolean = true> {
77
77
  dataFormat(result: Listr3TaskResultEnd<Context>[], options?: {
78
78
  streams?: StdStreams;
79
79
  verbose?: number;
80
+ errors?: Error[];
80
81
  }): DataFormat;
81
- exec(): Promise<(import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<Context>)[]>;
82
+ exec(): Promise<{
83
+ result: (import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<Context>)[];
84
+ exitCode: number;
85
+ errors: Error[];
86
+ }>;
82
87
  }
83
88
  export {};
@@ -202,15 +202,17 @@ class BackupAction {
202
202
  { value: "Duration", width: 10 },
203
203
  { value: "Error", width: 50 },
204
204
  ],
205
- rows: () => result
206
- .filter((item) => item.key !== "cleanup")
207
- .map((item) => [
208
- (0, cli_1.renderResult)(item.error),
209
- renderTitle(item, true),
210
- renderData(item, result, "table"),
211
- (0, date_1.duration)(item.elapsed),
212
- (0, cli_1.renderError)(item.error, options.verbose),
213
- ]),
205
+ rows: () => {
206
+ return result
207
+ .filter((item) => item.key !== "cleanup")
208
+ .map((item) => [
209
+ (0, cli_1.renderResult)(item.error),
210
+ renderTitle(item, true),
211
+ renderData(item, result, "table"),
212
+ (0, date_1.duration)(item.elapsed),
213
+ (0, cli_1.renderError)(item.error, options.errors?.indexOf(item.error)),
214
+ ]);
215
+ },
214
216
  },
215
217
  });
216
218
  }
@@ -430,7 +432,7 @@ class BackupAction {
430
432
  },
431
433
  }),
432
434
  ])
433
- .exec();
435
+ .execAndParse(this.options.verbose);
434
436
  }
435
437
  }
436
438
  exports.BackupAction = BackupAction;
@@ -41,6 +41,7 @@ export declare class CopyAction<TRequired extends boolean = true> {
41
41
  dataFormat(result: Listr3TaskResultEnd<Context>[], options?: {
42
42
  streams?: StdStreams;
43
43
  verbose?: number;
44
+ errors?: Error[];
44
45
  }): DataFormat;
45
46
  protected fetchSnapshots(repo: RepositoryAbstract<any>): Promise<Snapshot[]>;
46
47
  protected createSourceRepoMap(): StrictMap<[Pick<Snapshot, "packageName" | "id">, Pick<RepositoryConfig, "type">], RepositoryAbstract<any>>;
@@ -54,5 +55,9 @@ export declare class CopyAction<TRequired extends boolean = true> {
54
55
  }): Promise<{
55
56
  bytes: number;
56
57
  }>;
57
- exec(): Promise<(import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<Context>)[]>;
58
+ exec(): Promise<{
59
+ result: (import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<Context>)[];
60
+ exitCode: number;
61
+ errors: Error[];
62
+ }>;
58
63
  }
@@ -122,7 +122,7 @@ class CopyAction {
122
122
  renderTitle(item, true),
123
123
  renderData(item, result, "table"),
124
124
  (0, date_1.duration)(item.elapsed),
125
- (0, cli_1.renderError)(item.error, options.verbose),
125
+ (0, cli_1.renderError)(item.error, options.errors?.indexOf(item.error)),
126
126
  ]),
127
127
  },
128
128
  });
@@ -330,7 +330,7 @@ class CopyAction {
330
330
  },
331
331
  }),
332
332
  ])
333
- .exec();
333
+ .execAndParse(this.options.verbose);
334
334
  }
335
335
  }
336
336
  exports.CopyAction = CopyAction;
@@ -53,7 +53,12 @@ export declare class RestoreAction<TRequired extends boolean = true> {
53
53
  dataFormat(result: Listr3TaskResultEnd<Context>[], options?: {
54
54
  streams?: StdStreams;
55
55
  verbose?: number;
56
+ errors?: Error[];
56
57
  }): DataFormat;
57
- exec(): Promise<(import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<Context>)[]>;
58
+ exec(): Promise<{
59
+ result: (import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<Context>)[];
60
+ exitCode: number;
61
+ errors: Error[];
62
+ }>;
58
63
  }
59
64
  export {};
@@ -176,7 +176,7 @@ class RestoreAction {
176
176
  renderTitle(item, true),
177
177
  renderData(item, true, result),
178
178
  (0, date_1.duration)(item.elapsed),
179
- (0, cli_1.renderError)(item.error, options.verbose),
179
+ (0, cli_1.renderError)(item.error, options.errors?.indexOf(item.error)),
180
180
  ]),
181
181
  },
182
182
  });
@@ -299,7 +299,7 @@ class RestoreAction {
299
299
  }));
300
300
  },
301
301
  }))
302
- .exec();
302
+ .execAndParse(this.options.verbose);
303
303
  }
304
304
  }
305
305
  exports.RestoreAction = RestoreAction;
package/lib/cli.js CHANGED
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -13,7 +36,7 @@ const exit_1 = require("./utils/exit");
13
36
  const fs_1 = require("./utils/fs");
14
37
  const string_1 = require("./utils/string");
15
38
  const temp_1 = require("./utils/temp");
16
- const chalk_1 = require("chalk");
39
+ const chalk_1 = __importStar(require("chalk"));
17
40
  const commander_1 = require("commander");
18
41
  const fs_2 = require("fs");
19
42
  const path_1 = require("path");
@@ -27,43 +50,73 @@ function getGlobalOptions() {
27
50
  };
28
51
  }
29
52
  function makeCommand(command) {
30
- const programCommand = program.command(command);
31
53
  const instance = (0, command_1.createCommand)(command, getGlobalOptions(), null);
32
54
  const options = instance.optionsConfig();
55
+ const inlineOptions = [];
56
+ for (const name in options) {
57
+ const option = options[name];
58
+ if (typeof option.option !== "string") {
59
+ inlineOptions.push({ name, required: option.required });
60
+ }
61
+ }
62
+ const programCommand = program.command([
63
+ command,
64
+ ...inlineOptions.map((v) => (v.required ? `<${v.name}>` : `[${v.name}]`)),
65
+ ].join(" "));
33
66
  for (const key in options) {
34
67
  const option = options[key];
35
- const description = `${option.description}${option.defaults ? ` (defaults: ${option.defaults})` : ""}`;
36
- if (option.required) {
37
- programCommand.requiredOption(option.option, description);
38
- }
39
- else {
40
- programCommand.option(option.option, description);
68
+ if (typeof option.option === "string") {
69
+ const description = `${option.description}${option.defaults ? ` (defaults: ${option.defaults})` : ""}`;
70
+ if (option.required) {
71
+ programCommand.requiredOption(option.option, description);
72
+ }
73
+ else {
74
+ programCommand.option(option.option, description);
75
+ }
41
76
  }
42
77
  }
43
- return programCommand.action(makeCommandAction(command));
78
+ return programCommand.action(async (...args) => {
79
+ const inlineValues = args.slice(0, inlineOptions.length);
80
+ const action = makeCommandAction(command);
81
+ const inOptions = args[inlineOptions.length] || {};
82
+ const options = inlineOptions.reduce((result, inlineOption, index) => {
83
+ const value = inlineValues[index];
84
+ if (value !== undefined)
85
+ result[inlineOption.name] = value;
86
+ return result;
87
+ }, inOptions);
88
+ return await action(options);
89
+ });
44
90
  }
45
- function makeCommandAction(command) {
91
+ function makeCommandAction(commandName) {
46
92
  return async function (options) {
47
93
  let exitCode = 1;
94
+ let error;
95
+ let errors;
48
96
  const globalOptions = getGlobalOptions();
49
97
  try {
50
- const configAction = new ConfigAction_1.ConfigAction({
51
- path: globalOptions.config,
52
- verbose: !!globalOptions.verbose,
53
- });
54
- const config = await configAction.exec();
98
+ const config = await ConfigAction_1.ConfigAction.fromGlobalOptionsWithPath(globalOptions);
55
99
  if (config.data.tempDir)
56
100
  globalData_1.default.tempDir = (0, path_1.isAbsolute)(config.data.tempDir)
57
101
  ? config.data.tempDir
58
102
  : (0, path_1.join)((0, path_1.dirname)(config.path), config.data.tempDir);
59
- const response = await (0, command_1.createCommand)(command, {
60
- ...globalOptions,
61
- config: config.data,
62
- }, options, {}, globalOptions.config).exec();
103
+ const command = (0, command_1.createCommand)(commandName, { ...globalOptions }, options, {}, globalOptions.config);
104
+ const response = await command.exec();
105
+ errors = response.errors;
63
106
  exitCode = response.exitCode;
64
107
  }
65
108
  catch (e) {
66
- const error = e;
109
+ error = e;
110
+ }
111
+ if (errors?.length) {
112
+ console.error();
113
+ errors.forEach((error, index) => {
114
+ console.error(chalk_1.default.red(`${index + 1}. ` + error.stack ?? error.message));
115
+ if (errors[index + 1])
116
+ console.error();
117
+ });
118
+ }
119
+ if (error) {
67
120
  if (globalOptions.verbose) {
68
121
  console.error((0, chalk_1.red)(error.stack));
69
122
  }
@@ -99,6 +152,7 @@ makeCommand("snapshots").alias("s");
99
152
  makeCommand("prune").alias("p");
100
153
  makeCommand("backup").alias("b");
101
154
  makeCommand("restore").alias("r");
155
+ makeCommand("run");
102
156
  makeCommand("copy").alias("cp");
103
157
  makeCommand("cleanCache").alias("cc");
104
158
  function buildArgs(input, options) {
@@ -117,7 +171,7 @@ function parseArgs(args) {
117
171
  process.stdout.write(cli_1.showCursorCommand);
118
172
  console.info(`\nClosing... (reason: ${eventName})`);
119
173
  if (error instanceof Error)
120
- console.error((0, chalk_1.red)(error.stack));
174
+ console.error(error.stack);
121
175
  }
122
176
  if (!verbose)
123
177
  try {
@@ -41,5 +41,6 @@ export declare class BackupCommand extends CommandAbstract<BackupCommandOptions<
41
41
  };
42
42
  } & import("../utils/datatruck/report-list").ReportListTaskContext>)[];
43
43
  exitCode: number;
44
+ errors: Error[];
44
45
  }>;
45
46
  }
@@ -64,13 +64,16 @@ class BackupCommand extends CommandAbstract_1.CommandAbstract {
64
64
  streams: this.streams,
65
65
  prune: this.options.prune,
66
66
  });
67
- const result = await backup.exec();
67
+ const data = await backup.exec();
68
68
  if (this.globalOptions.outputFormat)
69
69
  backup
70
- .dataFormat(result, { streams: this.streams, verbose })
70
+ .dataFormat(data.result, {
71
+ verbose,
72
+ streams: this.streams,
73
+ errors: data.errors,
74
+ })
71
75
  .log(this.globalOptions.outputFormat);
72
- const exitCode = result.some((item) => item.error) ? 1 : 0;
73
- return { result, exitCode };
76
+ return data;
74
77
  }
75
78
  }
76
79
  exports.BackupCommand = BackupCommand;
@@ -26,5 +26,6 @@ export declare abstract class CommandAbstract<TUnresolvedOptions, TOptions exten
26
26
  abstract exec(): Promise<{
27
27
  exitCode: number;
28
28
  result?: any;
29
+ errors?: Error[];
29
30
  }>;
30
31
  }
@@ -13,5 +13,6 @@ export declare class CopyCommand extends CommandAbstract<CopyCommandOptions<fals
13
13
  exec(): Promise<{
14
14
  result: (import("../utils/list").List3SummaryResult | import("../utils/list").Listr3TaskResult<import("../actions/CopyAction").Context>)[];
15
15
  exitCode: number;
16
+ errors: Error[];
16
17
  }>;
17
18
  }
@@ -54,13 +54,16 @@ class CopyCommand extends CommandAbstract_1.CommandAbstract {
54
54
  tty: this.globalOptions.tty,
55
55
  progress: this.globalOptions.progress,
56
56
  });
57
- const result = await copy.exec();
57
+ const data = await copy.exec();
58
58
  if (this.globalOptions.outputFormat)
59
59
  copy
60
- .dataFormat(result, { streams: this.streams, verbose })
60
+ .dataFormat(data.result, {
61
+ verbose,
62
+ streams: this.streams,
63
+ errors: data.errors,
64
+ })
61
65
  .log(this.globalOptions.outputFormat);
62
- const exitCode = result.some((item) => item.error) ? 1 : 0;
63
- return { result, exitCode };
66
+ return data;
64
67
  }
65
68
  }
66
69
  exports.CopyCommand = CopyCommand;
@@ -15,5 +15,6 @@ export declare class InitCommand extends CommandAbstract<InitCommandOptions<fals
15
15
  error: Error | null;
16
16
  }[];
17
17
  exitCode: number;
18
+ errors: Error[];
18
19
  }>;
19
20
  }
@@ -5,6 +5,7 @@ const ConfigAction_1 = require("../actions/ConfigAction");
5
5
  const InitAction_1 = require("../actions/InitAction");
6
6
  const cli_1 = require("../utils/cli");
7
7
  const data_format_1 = require("../utils/data-format");
8
+ const error_1 = require("../utils/error");
8
9
  const string_1 = require("../utils/string");
9
10
  const CommandAbstract_1 = require("./CommandAbstract");
10
11
  class InitCommand extends CommandAbstract_1.CommandAbstract {
@@ -31,6 +32,10 @@ class InitCommand extends CommandAbstract_1.CommandAbstract {
31
32
  verbose: verbose > 0,
32
33
  });
33
34
  const result = await init.exec();
35
+ const exitCode = result.some((item) => item.error) ? 1 : 0;
36
+ const errors = result
37
+ .filter((item) => item.error && (verbose || !(item.error instanceof error_1.AppError)))
38
+ .map(({ error }) => error);
34
39
  const dataFormat = new data_format_1.DataFormat({
35
40
  streams: this.streams,
36
41
  json: result,
@@ -47,13 +52,13 @@ class InitCommand extends CommandAbstract_1.CommandAbstract {
47
52
  item.repositoryName,
48
53
  item.repositoryType,
49
54
  item.repositorySource,
50
- (0, cli_1.renderError)(item.error, verbose),
55
+ (0, cli_1.renderError)(item.error, errors.indexOf(item.error)),
51
56
  ]),
52
57
  },
53
58
  });
54
59
  if (this.globalOptions.outputFormat)
55
60
  dataFormat.log(this.globalOptions.outputFormat);
56
- return { result, exitCode: 0 };
61
+ return { result, exitCode, errors };
57
62
  }
58
63
  }
59
64
  exports.InitCommand = InitCommand;
@@ -35,5 +35,6 @@ export declare class RestoreCommand extends CommandAbstract<RestoreCommandOption
35
35
  };
36
36
  }>)[];
37
37
  exitCode: number;
38
+ errors: Error[];
38
39
  }>;
39
40
  }
@@ -65,13 +65,16 @@ class RestoreCommand extends CommandAbstract_1.CommandAbstract {
65
65
  progress: this.globalOptions.progress,
66
66
  streams: this.streams,
67
67
  });
68
- const result = await restore.exec();
68
+ const data = await restore.exec();
69
69
  if (this.globalOptions.outputFormat)
70
70
  restore
71
- .dataFormat(result, { streams: this.streams, verbose })
71
+ .dataFormat(data.result, {
72
+ verbose,
73
+ streams: this.streams,
74
+ errors: data.errors,
75
+ })
72
76
  .log(this.globalOptions.outputFormat);
73
- const exitCode = result.some((item) => item.error) ? 1 : 0;
74
- return { result, exitCode };
77
+ return data;
75
78
  }
76
79
  }
77
80
  exports.RestoreCommand = RestoreCommand;
@@ -0,0 +1,10 @@
1
+ import { CommandAbstract } from "./CommandAbstract";
2
+ export type RunCommandOptions<TResolved = false> = {
3
+ jobName: string;
4
+ };
5
+ export declare class RunCommand extends CommandAbstract<RunCommandOptions<false>, RunCommandOptions<true>> {
6
+ optionsConfig(): import("../utils/cli").OptionsConfig<RunCommandOptions<false>, RunCommandOptions<true>>;
7
+ exec(): Promise<{
8
+ exitCode: number;
9
+ }>;
10
+ }