@datatruck/cli 0.3.1 → 0.5.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.
- package/Action/BackupAction.js +1 -0
- package/Action/ConfigAction.d.ts +6 -1
- package/Action/ConfigAction.js +17 -1
- package/Action/InitAction.js +3 -0
- package/Action/PruneAction.js +1 -1
- package/Action/RestoreAction.js +4 -1
- package/Action/SnapshotsAction.d.ts +2 -1
- package/Action/SnapshotsAction.js +6 -1
- package/CHANGELOG.md +24 -0
- package/Command/BackupCommand.js +1 -5
- package/Command/BackupSessionsCommand.js +1 -5
- package/Command/CommandAbstract.d.ts +2 -1
- package/Command/ConfigCommand.js +1 -5
- package/Command/InitCommand.js +1 -5
- package/Command/PruneCommand.js +1 -5
- package/Command/RestoreCommand.js +1 -5
- package/Command/RestoreSessionsCommand.js +1 -5
- package/Command/SnapshotsCommand.js +1 -5
- package/Config/Config.d.ts +1 -0
- package/Config/Config.js +1 -0
- package/Config/RepositoryConfig.d.ts +4 -0
- package/Config/RepositoryConfig.js +19 -0
- package/Repository/ResticRepository.d.ts +7 -3
- package/Repository/ResticRepository.js +21 -5
- package/cli.js +22 -3
- package/config.schema.json +53 -3
- package/globalData.d.ts +5 -0
- package/globalData.js +7 -0
- package/package.json +1 -1
- package/util/ResticUtil.js +11 -3
- package/util/datatruck/config-util.d.ts +4 -1
- package/util/datatruck/config-util.js +11 -1
- package/util/fs-util.js +5 -3
- package/util/process-util.d.ts +1 -1
- package/util/process-util.js +1 -1
package/Action/BackupAction.js
CHANGED
|
@@ -23,6 +23,7 @@ class BackupAction {
|
|
|
23
23
|
packageNames: this.options.packageNames,
|
|
24
24
|
repositoryNames: this.options.repositoryNames,
|
|
25
25
|
repositoryTypes: this.options.repositoryTypes,
|
|
26
|
+
sourceAction: "backup",
|
|
26
27
|
});
|
|
27
28
|
packages = (0, config_util_1.resolvePackages)(packages, {
|
|
28
29
|
snapshotId: snapshot.id,
|
package/Action/ConfigAction.d.ts
CHANGED
|
@@ -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
|
-
|
|
14
|
+
static fromGlobalOptions(globalOptions: GlobalOptionsType<true>): Promise<ConfigType>;
|
|
15
|
+
exec(): Promise<{
|
|
16
|
+
path: string;
|
|
17
|
+
data: ConfigType;
|
|
18
|
+
}>;
|
|
14
19
|
}
|
package/Action/ConfigAction.js
CHANGED
|
@@ -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
|
|
74
|
+
return {
|
|
75
|
+
path,
|
|
76
|
+
data: ConfigAction.normalize(config),
|
|
77
|
+
};
|
|
62
78
|
}
|
|
63
79
|
}
|
|
64
80
|
exports.ConfigAction = ConfigAction;
|
package/Action/InitAction.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InitAction = void 0;
|
|
4
4
|
const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
|
|
5
|
+
const config_util_1 = require("../util/datatruck/config-util");
|
|
5
6
|
class InitAction {
|
|
6
7
|
constructor(config, options) {
|
|
7
8
|
this.config = config;
|
|
@@ -10,6 +11,8 @@ class InitAction {
|
|
|
10
11
|
async exec() {
|
|
11
12
|
const result = [];
|
|
12
13
|
for (const repo of this.config.repositories) {
|
|
14
|
+
if (!(0, config_util_1.filterRepository)(repo, "init"))
|
|
15
|
+
continue;
|
|
13
16
|
if (this.options.repositoryNames &&
|
|
14
17
|
!this.options.repositoryNames.includes(repo.name))
|
|
15
18
|
continue;
|
package/Action/PruneAction.js
CHANGED
|
@@ -24,7 +24,7 @@ class PruneAction {
|
|
|
24
24
|
}
|
|
25
25
|
async exec() {
|
|
26
26
|
const snapshotsAction = new SnapshotsAction_1.SnapshotsAction(this.config, this.options);
|
|
27
|
-
const snapshots = await snapshotsAction.exec();
|
|
27
|
+
const snapshots = await snapshotsAction.exec("prune");
|
|
28
28
|
const snapshotsDeleted = [];
|
|
29
29
|
const reasons = {};
|
|
30
30
|
const inputFilter = {
|
package/Action/RestoreAction.js
CHANGED
|
@@ -203,7 +203,10 @@ class RestoreAction {
|
|
|
203
203
|
const snapshots = this.groupSnapshots(await this.findSnapshots());
|
|
204
204
|
if (!snapshots.length)
|
|
205
205
|
throw new AppError_1.AppError("None snapshot found");
|
|
206
|
-
let packages = (0, config_util_1.filterPackages)(this.config,
|
|
206
|
+
let packages = (0, config_util_1.filterPackages)(this.config, {
|
|
207
|
+
...this.options,
|
|
208
|
+
sourceAction: "restore",
|
|
209
|
+
});
|
|
207
210
|
packages = (0, config_util_1.resolvePackages)(packages, {
|
|
208
211
|
snapshotId: this.options.snapshotId,
|
|
209
212
|
snapshotDate: snapshots[0].date,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ConfigType } from "../Config/Config";
|
|
2
|
+
import { RepositoryConfigEnabledActionType } from "../Config/RepositoryConfig";
|
|
2
3
|
import { SnapshotResultType } from "../Repository/RepositoryAbstract";
|
|
3
4
|
import { IfRequireKeys } from "../util/ts-util";
|
|
4
5
|
export declare type SnapshotGroupByType = keyof Pick<SnapshotExtendedType, "packageName" | "repositoryName" | "repositoryType">;
|
|
@@ -27,5 +28,5 @@ export declare class SnapshotsAction<TRequired extends boolean = true> {
|
|
|
27
28
|
readonly config: ConfigType;
|
|
28
29
|
readonly options: IfRequireKeys<TRequired, SnapshotsActionOptionsType>;
|
|
29
30
|
constructor(config: ConfigType, options: IfRequireKeys<TRequired, SnapshotsActionOptionsType>);
|
|
30
|
-
exec(): Promise<SnapshotExtendedType[]>;
|
|
31
|
+
exec(sourceAction?: RepositoryConfigEnabledActionType): Promise<SnapshotExtendedType[]>;
|
|
31
32
|
}
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SnapshotsAction = void 0;
|
|
4
4
|
const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
|
|
5
|
+
const config_util_1 = require("../util/datatruck/config-util");
|
|
5
6
|
const snapshot_util_1 = require("../util/datatruck/snapshot-util");
|
|
6
7
|
class SnapshotsAction {
|
|
7
8
|
constructor(config, options) {
|
|
8
9
|
this.config = config;
|
|
9
10
|
this.options = options;
|
|
10
11
|
}
|
|
11
|
-
async exec() {
|
|
12
|
+
async exec(sourceAction) {
|
|
13
|
+
if (!sourceAction)
|
|
14
|
+
sourceAction = "snapshots";
|
|
12
15
|
let result = [];
|
|
13
16
|
for (const repo of this.config.repositories) {
|
|
17
|
+
if (!(0, config_util_1.filterRepository)(repo, sourceAction))
|
|
18
|
+
continue;
|
|
14
19
|
if (this.options.repositoryNames &&
|
|
15
20
|
!this.options.repositoryNames.includes(repo.name))
|
|
16
21
|
continue;
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @datatruck/cli
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`5aeb2af`](https://github.com/swordev/datatruck/commit/5aeb2afb96692e00bdba501b58df9cc0e02dceaa) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `enabled` option to repository config
|
|
8
|
+
|
|
9
|
+
* [`75de836`](https://github.com/swordev/datatruck/commit/75de8369356cf02ed3fd5c58b1f9bea66432cda8) Thanks [@juanrgm](https://github.com/juanrgm)! - Allow restic password without file
|
|
10
|
+
|
|
11
|
+
## 0.4.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`eeb00a6`](https://github.com/swordev/datatruck/commit/eeb00a69d75c91da40711ae79475612b1d5193b6) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `tempDir` config option
|
|
16
|
+
|
|
17
|
+
## 0.3.2
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [`8957c3b`](https://github.com/swordev/datatruck/commit/8957c3b5846606db8b825fef357445210f2a3ac3) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix restic progress parser
|
|
22
|
+
|
|
23
|
+
* [`2989718`](https://github.com/swordev/datatruck/commit/29897185e3d6659359d51ab2212351005137f86c) Thanks [@juanrgm](https://github.com/juanrgm)! - Show closing reason
|
|
24
|
+
|
|
25
|
+
- [`b9e0843`](https://github.com/swordev/datatruck/commit/b9e0843c7970944cfd30a7d2a543f515adfa60e4) Thanks [@juanrgm](https://github.com/juanrgm)! - Show restic progress in megabytes
|
|
26
|
+
|
|
3
27
|
## 0.3.1
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/Command/BackupCommand.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
};
|
package/Command/ConfigCommand.js
CHANGED
|
@@ -27,11 +27,7 @@ class ConfigCommand extends CommandAbstract_1.CommandAbstract {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
async onExec() {
|
|
30
|
-
const
|
|
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,
|
package/Command/InitCommand.js
CHANGED
|
@@ -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
|
|
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,
|
package/Command/PruneCommand.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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,
|
package/Config/Config.d.ts
CHANGED
|
@@ -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
|
@@ -4,8 +4,12 @@ import { ResticRepositoryConfigType, resticRepositoryName } from "../Repository/
|
|
|
4
4
|
import type { JSONSchema7 } from "json-schema";
|
|
5
5
|
export declare const repositoryConfigDefinition: JSONSchema7;
|
|
6
6
|
export declare type RepositoryConfigTypeType = RepositoryConfigType["type"];
|
|
7
|
+
export declare type RepositoryConfigEnabledActionType = "backup" | "init" | "prune" | "restore" | "snapshots";
|
|
7
8
|
export declare type RepositoryConfigType = {
|
|
8
9
|
name: string;
|
|
10
|
+
enabled?: boolean | {
|
|
11
|
+
[K in "defaults" | RepositoryConfigEnabledActionType]?: boolean;
|
|
12
|
+
};
|
|
9
13
|
} & ({
|
|
10
14
|
type: typeof resticRepositoryName;
|
|
11
15
|
config: ResticRepositoryConfigType;
|
|
@@ -17,6 +17,25 @@ exports.repositoryConfigDefinition = {
|
|
|
17
17
|
properties: {
|
|
18
18
|
type: { type: "string" },
|
|
19
19
|
name: { type: "string" },
|
|
20
|
+
enabled: {
|
|
21
|
+
anyOf: [
|
|
22
|
+
{
|
|
23
|
+
type: "boolean",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: "object",
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
properties: {
|
|
29
|
+
defaults: { type: "boolean" },
|
|
30
|
+
backup: { type: "boolean" },
|
|
31
|
+
init: { type: "boolean" },
|
|
32
|
+
prune: { type: "boolean" },
|
|
33
|
+
restore: { type: "boolean" },
|
|
34
|
+
snapshots: { type: "boolean" },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
20
39
|
config: {},
|
|
21
40
|
},
|
|
22
41
|
anyOf: Object.keys(types).map((type) => ({
|
|
@@ -2,7 +2,9 @@ import { RepositoryType } from "../util/ResticUtil";
|
|
|
2
2
|
import { RepositoryAbstract, BackupDataType, InitDataType, RestoreDataType, SnapshotsDataType, SnapshotResultType, SnapshotTagObjectType, SnapshotTagEnum, PruneDataType } from "./RepositoryAbstract";
|
|
3
3
|
import { JSONSchema7 } from "json-schema";
|
|
4
4
|
export declare type ResticRepositoryConfigType = {
|
|
5
|
-
|
|
5
|
+
password: string | {
|
|
6
|
+
path: string;
|
|
7
|
+
};
|
|
6
8
|
repository: RepositoryType;
|
|
7
9
|
};
|
|
8
10
|
export declare type ResticPackageRepositoryConfigType = {};
|
|
@@ -12,11 +14,13 @@ export declare const resticPackageRepositoryDefinition: JSONSchema7;
|
|
|
12
14
|
export declare class ResticRepository extends RepositoryAbstract<ResticRepositoryConfigType> {
|
|
13
15
|
static refPrefix: string;
|
|
14
16
|
protected env: {
|
|
15
|
-
|
|
17
|
+
RESTIC_PASSWORD?: string;
|
|
18
|
+
RESTIC_PASSWORD_FILE?: string;
|
|
16
19
|
RESTIC_REPOSITORY: string;
|
|
17
20
|
};
|
|
18
21
|
buildEnv(): Promise<{
|
|
19
|
-
|
|
22
|
+
RESTIC_PASSWORD?: string | undefined;
|
|
23
|
+
RESTIC_PASSWORD_FILE?: string | undefined;
|
|
20
24
|
RESTIC_REPOSITORY: string;
|
|
21
25
|
}>;
|
|
22
26
|
static buildSnapshotTag(name: SnapshotTagEnum, value: string): string;
|
|
@@ -18,10 +18,22 @@ const path_1 = require("path");
|
|
|
18
18
|
exports.resticRepositoryName = "restic";
|
|
19
19
|
exports.resticRepositoryDefinition = {
|
|
20
20
|
type: "object",
|
|
21
|
-
required: ["
|
|
21
|
+
required: ["password", "repository"],
|
|
22
22
|
additionalProperties: false,
|
|
23
23
|
properties: {
|
|
24
|
-
|
|
24
|
+
password: {
|
|
25
|
+
anyOf: [
|
|
26
|
+
{ type: "string" },
|
|
27
|
+
{
|
|
28
|
+
type: "object",
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
required: ["path"],
|
|
31
|
+
properties: {
|
|
32
|
+
path: { type: "string" },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
25
37
|
repository: {
|
|
26
38
|
type: "object",
|
|
27
39
|
additionalProperties: false,
|
|
@@ -59,7 +71,9 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
59
71
|
if (this.env)
|
|
60
72
|
return this.env;
|
|
61
73
|
return (this.env = {
|
|
62
|
-
|
|
74
|
+
...(typeof this.config.password === "string"
|
|
75
|
+
? { RESTIC_PASSWORD: this.config.password }
|
|
76
|
+
: { RESTIC_PASSWORD_FILE: (0, path_1.resolve)(this.config.password.path) }),
|
|
63
77
|
RESTIC_REPOSITORY: await ResticUtil_1.ResticUtil.formatRepository(this.config.repository),
|
|
64
78
|
});
|
|
65
79
|
}
|
|
@@ -210,8 +224,10 @@ class ResticRepository extends RepositoryAbstract_1.RepositoryAbstract {
|
|
|
210
224
|
onStream: async (streamData) => {
|
|
211
225
|
if (streamData.message_type === "status") {
|
|
212
226
|
await data.onProgress({
|
|
213
|
-
total: streamData.total_bytes,
|
|
214
|
-
current: streamData.bytes_done
|
|
227
|
+
total: Number((streamData.total_bytes / 1024 / 1024).toFixed(2)),
|
|
228
|
+
current: streamData.bytes_done
|
|
229
|
+
? Number((streamData.bytes_done / 1024 / 1024).toFixed(2))
|
|
230
|
+
: 0,
|
|
215
231
|
percent: Number((streamData.percent_done * 100).toFixed(2)),
|
|
216
232
|
step: streamData.current_files?.join(", ") ?? "-",
|
|
217
233
|
});
|
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
|
-
|
|
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(
|
|
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 {
|
package/config.schema.json
CHANGED
|
@@ -20,6 +20,37 @@
|
|
|
20
20
|
"name": {
|
|
21
21
|
"type": "string"
|
|
22
22
|
},
|
|
23
|
+
"enabled": {
|
|
24
|
+
"anyOf": [
|
|
25
|
+
{
|
|
26
|
+
"type": "boolean"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"properties": {
|
|
32
|
+
"defaults": {
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
35
|
+
"backup": {
|
|
36
|
+
"type": "boolean"
|
|
37
|
+
},
|
|
38
|
+
"init": {
|
|
39
|
+
"type": "boolean"
|
|
40
|
+
},
|
|
41
|
+
"prune": {
|
|
42
|
+
"type": "boolean"
|
|
43
|
+
},
|
|
44
|
+
"restore": {
|
|
45
|
+
"type": "boolean"
|
|
46
|
+
},
|
|
47
|
+
"snapshots": {
|
|
48
|
+
"type": "boolean"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
23
54
|
"config": {}
|
|
24
55
|
},
|
|
25
56
|
"anyOf": [
|
|
@@ -462,13 +493,29 @@
|
|
|
462
493
|
"restic-repository": {
|
|
463
494
|
"type": "object",
|
|
464
495
|
"required": [
|
|
465
|
-
"
|
|
496
|
+
"password",
|
|
466
497
|
"repository"
|
|
467
498
|
],
|
|
468
499
|
"additionalProperties": false,
|
|
469
500
|
"properties": {
|
|
470
|
-
"
|
|
471
|
-
"
|
|
501
|
+
"password": {
|
|
502
|
+
"anyOf": [
|
|
503
|
+
{
|
|
504
|
+
"type": "string"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"type": "object",
|
|
508
|
+
"additionalProperties": false,
|
|
509
|
+
"required": [
|
|
510
|
+
"path"
|
|
511
|
+
],
|
|
512
|
+
"properties": {
|
|
513
|
+
"path": {
|
|
514
|
+
"type": "string"
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
]
|
|
472
519
|
},
|
|
473
520
|
"repository": {
|
|
474
521
|
"type": "object",
|
|
@@ -769,6 +816,9 @@
|
|
|
769
816
|
"$schema": {
|
|
770
817
|
"type": "string"
|
|
771
818
|
},
|
|
819
|
+
"tempDir": {
|
|
820
|
+
"type": "string"
|
|
821
|
+
},
|
|
772
822
|
"repositories": {
|
|
773
823
|
"type": "array",
|
|
774
824
|
"items": {
|
package/globalData.d.ts
ADDED
package/globalData.js
ADDED
package/package.json
CHANGED
package/util/ResticUtil.js
CHANGED
|
@@ -117,9 +117,17 @@ class ResticUtil {
|
|
|
117
117
|
stdout: {
|
|
118
118
|
...(options.onStream && {
|
|
119
119
|
onData: async (data) => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
+
}
|
|
123
131
|
}
|
|
124
132
|
},
|
|
125
133
|
}),
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { ConfigType } from "../../Config/Config";
|
|
2
2
|
import type { PackageConfigType } from "../../Config/PackageConfig";
|
|
3
|
-
|
|
3
|
+
import { RepositoryConfigEnabledActionType, RepositoryConfigType } from "../../Config/RepositoryConfig";
|
|
4
|
+
export declare function findRepositoryOrFail(config: ConfigType, repositoryName: string): RepositoryConfigType;
|
|
5
|
+
export declare function filterRepository(repository: RepositoryConfigType, action?: RepositoryConfigEnabledActionType): boolean;
|
|
4
6
|
export declare function filterPackages(config: ConfigType, options: {
|
|
5
7
|
packageNames?: string[];
|
|
6
8
|
repositoryNames?: string[];
|
|
7
9
|
repositoryTypes?: string[];
|
|
10
|
+
sourceAction?: RepositoryConfigEnabledActionType;
|
|
8
11
|
}): PackageConfigType[];
|
|
9
12
|
declare type ResolvePackagePathParamsType = ResolvePackageParamsType & {
|
|
10
13
|
packageName: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.params = exports.dbNameParams = exports.pkgRestorePathParams = exports.pkgExcludeParams = exports.pkgIncludeParams = exports.pkgPathParams = exports.resolvePackages = exports.resolvePackage = exports.resolveDatabaseName = exports.resolvePackagePath = exports.filterPackages = exports.findRepositoryOrFail = void 0;
|
|
3
|
+
exports.params = exports.dbNameParams = exports.pkgRestorePathParams = exports.pkgExcludeParams = exports.pkgIncludeParams = exports.pkgPathParams = exports.resolvePackages = exports.resolvePackage = exports.resolveDatabaseName = exports.resolvePackagePath = exports.filterPackages = exports.filterRepository = exports.findRepositoryOrFail = void 0;
|
|
4
4
|
const AppError_1 = require("../../Error/AppError");
|
|
5
5
|
const fs_util_1 = require("../fs-util");
|
|
6
6
|
const string_util_1 = require("../string-util");
|
|
@@ -12,6 +12,14 @@ function findRepositoryOrFail(config, repositoryName) {
|
|
|
12
12
|
return repo;
|
|
13
13
|
}
|
|
14
14
|
exports.findRepositoryOrFail = findRepositoryOrFail;
|
|
15
|
+
function filterRepository(repository, action) {
|
|
16
|
+
const enabled = repository.enabled ?? true;
|
|
17
|
+
if (typeof enabled === "boolean")
|
|
18
|
+
return enabled;
|
|
19
|
+
const defaults = enabled["defaults"] ?? true;
|
|
20
|
+
return action ? enabled[action] ?? defaults : defaults;
|
|
21
|
+
}
|
|
22
|
+
exports.filterRepository = filterRepository;
|
|
15
23
|
function filterPackages(config, options) {
|
|
16
24
|
const packagePatterns = (0, string_util_1.makePathPatterns)(options.packageNames);
|
|
17
25
|
return config.packages
|
|
@@ -19,6 +27,8 @@ function filterPackages(config, options) {
|
|
|
19
27
|
pkg = Object.assign({}, pkg);
|
|
20
28
|
pkg.repositoryNames = (pkg.repositoryNames ?? []).filter((name) => {
|
|
21
29
|
const repo = findRepositoryOrFail(config, name);
|
|
30
|
+
if (!filterRepository(repo, options?.sourceAction))
|
|
31
|
+
return false;
|
|
22
32
|
return ((!options.repositoryNames ||
|
|
23
33
|
options.repositoryNames.includes(name)) &&
|
|
24
34
|
(!options.repositoryTypes ||
|
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
|
-
|
|
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() {
|
package/util/process-util.d.ts
CHANGED
|
@@ -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 {};
|
package/util/process-util.js
CHANGED
|
@@ -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
|
|
178
|
+
process.on(eventName, (...args) => cb(eventName, ...args));
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
exports.onExit = onExit;
|