@datatruck/cli 0.27.0 → 0.28.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.d.ts +69 -34
- package/Action/BackupAction.js +284 -244
- package/Action/CleanCacheAction.d.ts +8 -4
- package/Action/CleanCacheAction.js +8 -5
- package/Action/ConfigAction.d.ts +12 -5
- package/Action/ConfigAction.js +14 -18
- package/Action/CopyAction.d.ts +49 -0
- package/Action/CopyAction.js +144 -0
- package/Action/InitAction.d.ts +3 -3
- package/Action/InitAction.js +9 -9
- package/Action/PruneAction.d.ts +9 -9
- package/Action/PruneAction.js +39 -23
- package/Action/RestoreAction.d.ts +48 -23
- package/Action/RestoreAction.js +158 -195
- package/Action/SnapshotsAction.d.ts +8 -8
- package/Action/SnapshotsAction.js +8 -8
- package/CHANGELOG.md +495 -0
- package/Command/BackupCommand.d.ts +6 -4
- package/Command/BackupCommand.js +9 -26
- package/Command/CleanCacheCommand.d.ts +4 -4
- package/Command/CleanCacheCommand.js +26 -5
- package/Command/CommandAbstract.d.ts +10 -7
- package/Command/CommandAbstract.js +4 -1
- package/Command/ConfigCommand.d.ts +6 -9
- package/Command/ConfigCommand.js +13 -8
- package/Command/CopyCommand.d.ts +15 -0
- package/Command/CopyCommand.js +61 -0
- package/Command/InitCommand.d.ts +4 -4
- package/Command/InitCommand.js +11 -15
- package/Command/PruneCommand.d.ts +3 -3
- package/Command/PruneCommand.js +13 -12
- package/Command/RestoreCommand.js +9 -17
- package/Command/SnapshotsCommand.d.ts +4 -4
- package/Command/SnapshotsCommand.js +16 -15
- package/Command/StartServerCommand.d.ts +3 -3
- package/Config/Config.d.ts +9 -0
- package/Config/Config.js +17 -0
- package/Config/PrunePolicyConfig.d.ts +2 -2
- package/Factory/CommandFactory.d.ts +27 -34
- package/Factory/CommandFactory.js +27 -54
- package/Factory/RepositoryFactory.d.ts +1 -1
- package/Factory/RepositoryFactory.js +3 -3
- package/Factory/TaskFactory.d.ts +1 -1
- package/Factory/TaskFactory.js +3 -3
- package/Repository/DatatruckRepository.d.ts +9 -8
- package/Repository/DatatruckRepository.js +42 -25
- package/Repository/GitRepository.d.ts +9 -8
- package/Repository/GitRepository.js +22 -25
- package/Repository/RepositoryAbstract.d.ts +39 -37
- package/Repository/RepositoryAbstract.js +4 -5
- package/Repository/ResticRepository.d.ts +9 -8
- package/Repository/ResticRepository.js +30 -28
- package/Task/GitTask.d.ts +6 -7
- package/Task/GitTask.js +24 -30
- package/Task/MariadbTask.d.ts +4 -5
- package/Task/MariadbTask.js +26 -32
- package/Task/MssqlTask.d.ts +5 -3
- package/Task/MssqlTask.js +11 -12
- package/Task/MysqlDumpTask.d.ts +10 -3
- package/Task/MysqlDumpTask.js +107 -31
- package/Task/ScriptTask.d.ts +23 -18
- package/Task/ScriptTask.js +34 -24
- package/Task/SqlDumpTaskAbstract.d.ts +8 -3
- package/Task/SqlDumpTaskAbstract.js +31 -19
- package/Task/TaskAbstract.d.ts +24 -25
- package/Task/TaskAbstract.js +6 -10
- package/cli.js +13 -5
- package/config.schema.json +86 -1
- package/package.json +4 -5
- package/utils/DataFormat.d.ts +23 -12
- package/utils/DataFormat.js +36 -14
- package/utils/cli.d.ts +2 -9
- package/utils/cli.js +9 -52
- package/utils/datatruck/client.d.ts +2 -0
- package/utils/datatruck/client.js +3 -0
- package/utils/datatruck/config.d.ts +2 -0
- package/utils/datatruck/config.js +18 -3
- package/utils/datatruck/paths.d.ts +5 -9
- package/utils/datatruck/paths.js +2 -2
- package/utils/datatruck/snapshot.d.ts +2 -2
- package/utils/date.d.ts +7 -3
- package/utils/date.js +22 -14
- package/utils/fs.d.ts +16 -11
- package/utils/fs.js +81 -48
- package/utils/list.d.ts +64 -0
- package/utils/list.js +145 -0
- package/utils/mysql.d.ts +2 -0
- package/utils/mysql.js +21 -2
- package/utils/process.d.ts +1 -0
- package/utils/process.js +24 -31
- package/utils/progress.d.ts +33 -0
- package/utils/progress.js +113 -0
- package/utils/steps.d.ts +11 -0
- package/utils/steps.js +22 -10
- package/utils/stream.d.ts +7 -0
- package/utils/stream.js +10 -0
- package/utils/string.d.ts +0 -1
- package/utils/string.js +1 -13
- package/utils/tar.d.ts +10 -3
- package/utils/tar.js +70 -44
- package/utils/temp.d.ts +26 -0
- package/utils/temp.js +133 -0
- package/utils/virtual-fs.d.ts +6 -2
- package/utils/virtual-fs.js +6 -0
- package/Action/BackupSessionsAction.d.ts +0 -13
- package/Action/BackupSessionsAction.js +0 -18
- package/Action/RestoreSessionsAction.d.ts +0 -13
- package/Action/RestoreSessionsAction.js +0 -18
- package/Command/BackupSessionsCommand.d.ts +0 -12
- package/Command/BackupSessionsCommand.js +0 -92
- package/Command/RestoreSessionsCommand.d.ts +0 -12
- package/Command/RestoreSessionsCommand.js +0 -91
- package/Decorator/EntityDecorator.d.ts +0 -11
- package/Decorator/EntityDecorator.js +0 -17
- package/Entity/BackupSessionEntity.d.ts +0 -6
- package/Entity/BackupSessionEntity.js +0 -25
- package/Entity/BackupSessionRepositoryEntity.d.ts +0 -6
- package/Entity/BackupSessionRepositoryEntity.js +0 -25
- package/Entity/BackupSessionTaskEntity.d.ts +0 -5
- package/Entity/BackupSessionTaskEntity.js +0 -24
- package/Entity/CrudEntityAbstract.d.ts +0 -5
- package/Entity/CrudEntityAbstract.js +0 -9
- package/Entity/RestoreSessionEntity.d.ts +0 -5
- package/Entity/RestoreSessionEntity.js +0 -24
- package/Entity/RestoreSessionRepositoryEntity.d.ts +0 -6
- package/Entity/RestoreSessionRepositoryEntity.js +0 -25
- package/Entity/RestoreSessionTaskEntity.d.ts +0 -5
- package/Entity/RestoreSessionTaskEntity.js +0 -24
- package/Entity/StateEntityAbstract.d.ts +0 -9
- package/Entity/StateEntityAbstract.js +0 -12
- package/Factory/EntityFactory.d.ts +0 -6
- package/Factory/EntityFactory.js +0 -40
- package/SessionDriver/ConsoleSessionDriver.d.ts +0 -42
- package/SessionDriver/ConsoleSessionDriver.js +0 -208
- package/SessionDriver/SessionDriverAbstract.d.ts +0 -77
- package/SessionDriver/SessionDriverAbstract.js +0 -28
- package/SessionDriver/SqliteSessionDriver.d.ts +0 -20
- package/SessionDriver/SqliteSessionDriver.js +0 -173
- package/SessionManager/BackupSessionManager.d.ts +0 -45
- package/SessionManager/BackupSessionManager.js +0 -218
- package/SessionManager/RestoreSessionManager.d.ts +0 -47
- package/SessionManager/RestoreSessionManager.js +0 -218
- package/SessionManager/SessionManagerAbstract.d.ts +0 -18
- package/SessionManager/SessionManagerAbstract.js +0 -36
- package/migrations/001-initial.sql +0 -98
- package/utils/entity.d.ts +0 -4
- package/utils/entity.js +0 -10
package/Action/ConfigAction.js
CHANGED
|
@@ -10,7 +10,6 @@ const config_1 = require("../utils/datatruck/config");
|
|
|
10
10
|
const fs_1 = require("../utils/fs");
|
|
11
11
|
const ajv_1 = __importDefault(require("ajv"));
|
|
12
12
|
const assert_1 = require("assert");
|
|
13
|
-
const path_1 = require("path");
|
|
14
13
|
class ConfigAction {
|
|
15
14
|
options;
|
|
16
15
|
constructor(options) {
|
|
@@ -55,12 +54,6 @@ class ConfigAction {
|
|
|
55
54
|
config = Object.assign({}, config);
|
|
56
55
|
config.packages = config.packages.map((pkg) => {
|
|
57
56
|
pkg = Object.assign({}, pkg);
|
|
58
|
-
if (!pkg.restorePath)
|
|
59
|
-
pkg.restorePath = pkg.path
|
|
60
|
-
? pkg.path
|
|
61
|
-
: (0, path_1.normalize)(`{temp}/{snapshotId}-{action}/{packageName}`);
|
|
62
|
-
if (!pkg.path)
|
|
63
|
-
pkg.path = (0, path_1.normalize)(`{temp}/{snapshotId}-{action}/{packageName}`);
|
|
64
57
|
pkg.repositoryNames =
|
|
65
58
|
pkg.repositoryNames ?? config.repositories.map((repo) => repo.name);
|
|
66
59
|
(0, assert_1.ok)(Array.isArray(pkg.repositoryNames));
|
|
@@ -70,18 +63,21 @@ class ConfigAction {
|
|
|
70
63
|
});
|
|
71
64
|
return config;
|
|
72
65
|
}
|
|
66
|
+
static async fromGlobalOptionsWithPath(globalOptions) {
|
|
67
|
+
if (typeof globalOptions.config !== "string")
|
|
68
|
+
return {
|
|
69
|
+
path: null,
|
|
70
|
+
data: globalOptions.config,
|
|
71
|
+
};
|
|
72
|
+
const configAction = new ConfigAction({
|
|
73
|
+
path: globalOptions.config,
|
|
74
|
+
verbose: !!globalOptions.verbose && globalOptions.verbose > 0,
|
|
75
|
+
});
|
|
76
|
+
return await configAction.exec();
|
|
77
|
+
}
|
|
73
78
|
static async fromGlobalOptions(globalOptions) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
path: globalOptions.config,
|
|
77
|
-
verbose: !!globalOptions.verbose && globalOptions.verbose > 0,
|
|
78
|
-
});
|
|
79
|
-
const result = await configAction.exec();
|
|
80
|
-
return result.data;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
return globalOptions.config;
|
|
84
|
-
}
|
|
79
|
+
const config = await ConfigAction.fromGlobalOptionsWithPath(globalOptions);
|
|
80
|
+
return config.data;
|
|
85
81
|
}
|
|
86
82
|
async exec() {
|
|
87
83
|
const path = await (0, fs_1.findFile)(this.options.path, "datatruck.config", fs_1.parseFileExtensions, "Config path not found");
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ConfigType } from "../Config/Config";
|
|
2
|
+
import { Snapshot } from "../Repository/RepositoryAbstract";
|
|
3
|
+
import { DataFormat } from "../utils/DataFormat";
|
|
4
|
+
import { Listr3TaskResultEnd } from "../utils/list";
|
|
5
|
+
import { Streams } from "../utils/stream";
|
|
6
|
+
import { IfRequireKeys } from "../utils/ts";
|
|
7
|
+
export type CopyActionOptionsType = {
|
|
8
|
+
ids: string[];
|
|
9
|
+
repositoryName: string;
|
|
10
|
+
packageNames?: string[];
|
|
11
|
+
packageTaskNames?: string[];
|
|
12
|
+
repositoryNames2?: string[];
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
tty?: "auto" | boolean;
|
|
15
|
+
progress?: "auto" | "interval" | boolean;
|
|
16
|
+
progressInterval?: number;
|
|
17
|
+
};
|
|
18
|
+
export type CopyActionResult = {
|
|
19
|
+
errors: Error[];
|
|
20
|
+
};
|
|
21
|
+
export type Context = {
|
|
22
|
+
snapshots: {
|
|
23
|
+
snapshots: Snapshot[];
|
|
24
|
+
};
|
|
25
|
+
copy: {
|
|
26
|
+
snapshotId: string;
|
|
27
|
+
packageName: string;
|
|
28
|
+
repositoryName: string;
|
|
29
|
+
mirrorRepositoryName: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export declare class CopyAction<TRequired extends boolean = true> {
|
|
33
|
+
readonly config: ConfigType;
|
|
34
|
+
readonly options: IfRequireKeys<TRequired, CopyActionOptionsType>;
|
|
35
|
+
constructor(config: ConfigType, options: IfRequireKeys<TRequired, CopyActionOptionsType>);
|
|
36
|
+
dataFormat(result: Listr3TaskResultEnd<Context>[], options?: {
|
|
37
|
+
streams?: Streams;
|
|
38
|
+
verbose?: number;
|
|
39
|
+
}): DataFormat;
|
|
40
|
+
exec(): Promise<({
|
|
41
|
+
key: "summary";
|
|
42
|
+
keyIndex?: string | undefined;
|
|
43
|
+
data: {
|
|
44
|
+
errors: number;
|
|
45
|
+
};
|
|
46
|
+
elapsed: number;
|
|
47
|
+
error?: Error | undefined;
|
|
48
|
+
} | import("../utils/list").Listr3TaskResult<Context>)[]>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CopyAction = void 0;
|
|
7
|
+
const RepositoryFactory_1 = require("../Factory/RepositoryFactory");
|
|
8
|
+
const DataFormat_1 = require("../utils/DataFormat");
|
|
9
|
+
const cli_1 = require("../utils/cli");
|
|
10
|
+
const config_1 = require("../utils/datatruck/config");
|
|
11
|
+
const date_1 = require("../utils/date");
|
|
12
|
+
const list_1 = require("../utils/list");
|
|
13
|
+
const progress_1 = require("../utils/progress");
|
|
14
|
+
const temp_1 = require("../utils/temp");
|
|
15
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
class CopyAction {
|
|
17
|
+
config;
|
|
18
|
+
options;
|
|
19
|
+
constructor(config, options) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
dataFormat(result, options = {}) {
|
|
24
|
+
const renderTitle = (item, color) => {
|
|
25
|
+
let title = item.key.slice(0, 1).toUpperCase() + item.key.slice(1);
|
|
26
|
+
return item.key === "copy" && color ? chalk_1.default.cyan(title) : title;
|
|
27
|
+
};
|
|
28
|
+
const renderData = (item, color) => {
|
|
29
|
+
const g = (v) => (color ? `${chalk_1.default.gray(`(${v})`)}` : `(${v})`);
|
|
30
|
+
return item.key === "snapshots"
|
|
31
|
+
? item.data.snapshots.length
|
|
32
|
+
: item.key === "copy"
|
|
33
|
+
? `${item.data.packageName} ${g(item.data.mirrorRepositoryName)}`
|
|
34
|
+
: "";
|
|
35
|
+
};
|
|
36
|
+
return new DataFormat_1.DataFormat({
|
|
37
|
+
streams: options.streams,
|
|
38
|
+
json: result,
|
|
39
|
+
table: {
|
|
40
|
+
headers: [
|
|
41
|
+
{ value: "", width: 3 },
|
|
42
|
+
{ value: "Title", width: 15 },
|
|
43
|
+
{ value: "Data" },
|
|
44
|
+
{ value: "Duration", width: 10 },
|
|
45
|
+
{ value: "Error", width: 50 },
|
|
46
|
+
],
|
|
47
|
+
rows: () => result.map((item) => [
|
|
48
|
+
(0, cli_1.resultColumn)(item.error),
|
|
49
|
+
renderTitle(item, true),
|
|
50
|
+
renderData(item, true),
|
|
51
|
+
(0, date_1.duration)(item.elapsed),
|
|
52
|
+
(0, cli_1.errorColumn)(item.error, options.verbose),
|
|
53
|
+
]),
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async exec() {
|
|
58
|
+
const { options } = this;
|
|
59
|
+
const pm = new progress_1.ProgressManager({
|
|
60
|
+
verbose: options.verbose,
|
|
61
|
+
tty: options.tty,
|
|
62
|
+
enabled: options.progress,
|
|
63
|
+
interval: options.progressInterval,
|
|
64
|
+
});
|
|
65
|
+
const l = new list_1.Listr3({ progressManager: pm });
|
|
66
|
+
return l
|
|
67
|
+
.add(l.$task({
|
|
68
|
+
key: "snapshots",
|
|
69
|
+
data: { snapshots: [] },
|
|
70
|
+
title: {
|
|
71
|
+
initial: "Fetch snapshots",
|
|
72
|
+
started: "Fetching snapshots",
|
|
73
|
+
completed: "Snapshots fetched",
|
|
74
|
+
failed: "Snapshot fetch failed",
|
|
75
|
+
},
|
|
76
|
+
run: async (task, data) => {
|
|
77
|
+
if (this.config.minFreeDiskSpace)
|
|
78
|
+
await (0, temp_1.ensureFreeDiskTempSpace)(this.config.minFreeDiskSpace);
|
|
79
|
+
const sourceRepoConfig = (0, config_1.findRepositoryOrFail)(this.config, this.options.repositoryName);
|
|
80
|
+
const repo = (0, RepositoryFactory_1.createRepo)(sourceRepoConfig);
|
|
81
|
+
const snapshots = await repo.fetchSnapshots({
|
|
82
|
+
options: {
|
|
83
|
+
ids: this.options.ids,
|
|
84
|
+
packageNames: this.options.packageNames,
|
|
85
|
+
packageTaskNames: this.options.packageTaskNames,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
data.snapshots = snapshots;
|
|
89
|
+
task.title = `Snapshots fetched: ${snapshots.length}`;
|
|
90
|
+
if (!snapshots.length)
|
|
91
|
+
throw new Error("No snapshots found");
|
|
92
|
+
const repositoryNames2 = this.options.repositoryNames2 ||
|
|
93
|
+
this.config.repositories
|
|
94
|
+
.filter((r) => r.name !== sourceRepoConfig.name &&
|
|
95
|
+
r.type === sourceRepoConfig.type &&
|
|
96
|
+
(0, config_1.filterRepository)(r, "backup"))
|
|
97
|
+
.map((r) => r.name);
|
|
98
|
+
if (!repositoryNames2.length)
|
|
99
|
+
throw new Error("No mirror snapshots found");
|
|
100
|
+
return snapshots.flatMap((snapshot) => repositoryNames2.map((repo2) => l.$task({
|
|
101
|
+
key: "copy",
|
|
102
|
+
keyIndex: [snapshot.packageName, repo2],
|
|
103
|
+
data: {
|
|
104
|
+
snapshotId: snapshot.id,
|
|
105
|
+
packageName: snapshot.packageName,
|
|
106
|
+
repositoryName: sourceRepoConfig.name,
|
|
107
|
+
mirrorRepositoryName: repo2,
|
|
108
|
+
},
|
|
109
|
+
title: {
|
|
110
|
+
initial: `Copy snapshot: ${repo2}`,
|
|
111
|
+
started: `Copying snapshot: ${repo2}`,
|
|
112
|
+
completed: `Snapshot copied: ${repo2}`,
|
|
113
|
+
failed: `Snapshot copy failed: ${repo2}`,
|
|
114
|
+
},
|
|
115
|
+
exitOnError: false,
|
|
116
|
+
run: async (task) => {
|
|
117
|
+
const mirrorConfig = (0, config_1.findRepositoryOrFail)(this.config, repo2);
|
|
118
|
+
const mirrorRepo = (0, RepositoryFactory_1.createRepo)(mirrorConfig);
|
|
119
|
+
(0, config_1.ensureSameRepositoryType)(sourceRepoConfig, mirrorConfig);
|
|
120
|
+
const currentCopies = await mirrorRepo.fetchSnapshots({
|
|
121
|
+
options: {
|
|
122
|
+
ids: [snapshot.id],
|
|
123
|
+
packageNames: [snapshot.packageName],
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
if (currentCopies.length)
|
|
127
|
+
return task.skip(`Already exists at ${mirrorConfig.name}`);
|
|
128
|
+
if (this.config.minFreeDiskSpace)
|
|
129
|
+
await mirrorRepo.ensureFreeDiskSpace(mirrorConfig.config, this.config.minFreeDiskSpace);
|
|
130
|
+
await repo.copy({
|
|
131
|
+
mirrorRepositoryConfig: mirrorConfig.config,
|
|
132
|
+
options: { verbose: this.options.verbose },
|
|
133
|
+
package: { name: snapshot.packageName },
|
|
134
|
+
snapshot,
|
|
135
|
+
onProgress: (p) => pm.update(p, (d) => (task.output = d)),
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
})));
|
|
139
|
+
},
|
|
140
|
+
}))
|
|
141
|
+
.exec();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.CopyAction = CopyAction;
|
package/Action/InitAction.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { ConfigType } from "../Config/Config";
|
|
2
2
|
import { IfRequireKeys } from "../utils/ts";
|
|
3
|
-
export type
|
|
3
|
+
export type InitActionOptions = {
|
|
4
4
|
repositoryNames?: string[];
|
|
5
5
|
repositoryTypes?: string[];
|
|
6
6
|
verbose?: boolean;
|
|
7
7
|
};
|
|
8
8
|
export declare class InitAction<TRequired extends boolean = true> {
|
|
9
9
|
readonly config: ConfigType;
|
|
10
|
-
readonly options: IfRequireKeys<TRequired,
|
|
11
|
-
constructor(config: ConfigType, options: IfRequireKeys<TRequired,
|
|
10
|
+
readonly options: IfRequireKeys<TRequired, InitActionOptions>;
|
|
11
|
+
constructor(config: ConfigType, options: IfRequireKeys<TRequired, InitActionOptions>);
|
|
12
12
|
exec(): Promise<{
|
|
13
13
|
repositoryName: string;
|
|
14
14
|
repositoryType: string;
|
package/Action/InitAction.js
CHANGED
|
@@ -12,19 +12,19 @@ class InitAction {
|
|
|
12
12
|
}
|
|
13
13
|
async exec() {
|
|
14
14
|
const result = [];
|
|
15
|
-
for (const
|
|
16
|
-
if (!(0, config_1.filterRepository)(
|
|
15
|
+
for (const repoConfig of this.config.repositories) {
|
|
16
|
+
if (!(0, config_1.filterRepository)(repoConfig, "init"))
|
|
17
17
|
continue;
|
|
18
18
|
if (this.options.repositoryNames &&
|
|
19
|
-
!this.options.repositoryNames.includes(
|
|
19
|
+
!this.options.repositoryNames.includes(repoConfig.name))
|
|
20
20
|
continue;
|
|
21
21
|
if (this.options.repositoryTypes &&
|
|
22
|
-
!this.options.repositoryTypes.includes(
|
|
22
|
+
!this.options.repositoryTypes.includes(repoConfig.type))
|
|
23
23
|
continue;
|
|
24
|
-
const
|
|
24
|
+
const repo = (0, RepositoryFactory_1.createRepo)(repoConfig);
|
|
25
25
|
let initError = null;
|
|
26
26
|
try {
|
|
27
|
-
await
|
|
27
|
+
await repo.init({
|
|
28
28
|
options: this.options,
|
|
29
29
|
});
|
|
30
30
|
}
|
|
@@ -32,9 +32,9 @@ class InitAction {
|
|
|
32
32
|
initError = error;
|
|
33
33
|
}
|
|
34
34
|
result.push({
|
|
35
|
-
repositoryName:
|
|
36
|
-
repositoryType:
|
|
37
|
-
repositorySource:
|
|
35
|
+
repositoryName: repoConfig.name,
|
|
36
|
+
repositoryType: repoConfig.type,
|
|
37
|
+
repositorySource: repo.getSource(),
|
|
38
38
|
error: initError,
|
|
39
39
|
});
|
|
40
40
|
}
|
package/Action/PruneAction.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ConfigType } from "../Config/Config";
|
|
2
2
|
import { RepositoryConfigType } from "../Config/RepositoryConfig";
|
|
3
3
|
import { IfRequireKeys } from "../utils/ts";
|
|
4
|
-
import {
|
|
5
|
-
export type
|
|
4
|
+
import { ExtendedSnapshot, SnapshotsActionOptions } from "./SnapshotsAction";
|
|
5
|
+
export type PruneActionsOptions = {
|
|
6
6
|
ids?: string[];
|
|
7
7
|
packageNames?: string[];
|
|
8
8
|
repositoryNames?: string[];
|
|
@@ -16,22 +16,22 @@ export type PruneActionsOptionsType = {
|
|
|
16
16
|
keepMonthly?: number;
|
|
17
17
|
keepYearly?: number;
|
|
18
18
|
verbose?: boolean;
|
|
19
|
-
groupBy?:
|
|
19
|
+
groupBy?: SnapshotsActionOptions["groupBy"];
|
|
20
20
|
dryRun?: boolean;
|
|
21
21
|
longId?: boolean;
|
|
22
22
|
returnsAll?: boolean;
|
|
23
23
|
};
|
|
24
|
-
export type
|
|
24
|
+
export type PruneResult = {
|
|
25
25
|
total: number;
|
|
26
26
|
prune: number;
|
|
27
|
-
snapshots: (
|
|
27
|
+
snapshots: (ExtendedSnapshot & {
|
|
28
28
|
exclusionReasons: string[];
|
|
29
29
|
})[];
|
|
30
30
|
};
|
|
31
31
|
export declare class PruneAction<TRequired extends boolean = true> {
|
|
32
32
|
readonly config: ConfigType;
|
|
33
|
-
readonly options: IfRequireKeys<TRequired,
|
|
34
|
-
constructor(config: ConfigType, options: IfRequireKeys<TRequired,
|
|
35
|
-
confirm(snapshots:
|
|
36
|
-
exec(): Promise<
|
|
33
|
+
readonly options: IfRequireKeys<TRequired, PruneActionsOptions>;
|
|
34
|
+
constructor(config: ConfigType, options: IfRequireKeys<TRequired, PruneActionsOptions>);
|
|
35
|
+
confirm(snapshots: PruneResult["snapshots"]): Promise<void>;
|
|
36
|
+
exec(): Promise<PruneResult>;
|
|
37
37
|
}
|
package/Action/PruneAction.js
CHANGED
|
@@ -16,8 +16,8 @@ class PruneAction {
|
|
|
16
16
|
const repository = (0, object_1.groupBy)(this.config.repositories, "name", true);
|
|
17
17
|
for (const snapshot of snapshots) {
|
|
18
18
|
if (!snapshot.exclusionReasons?.length) {
|
|
19
|
-
const
|
|
20
|
-
await
|
|
19
|
+
const repo = (0, RepositoryFactory_1.createRepo)(repository[snapshot.repositoryName]);
|
|
20
|
+
await repo.prune({
|
|
21
21
|
snapshot: snapshot,
|
|
22
22
|
options: { verbose: this.options.verbose },
|
|
23
23
|
});
|
|
@@ -25,11 +25,22 @@ class PruneAction {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
async exec() {
|
|
28
|
-
const snapshotsAction = new SnapshotsAction_1.SnapshotsAction(this.config,
|
|
28
|
+
const snapshotsAction = new SnapshotsAction_1.SnapshotsAction(this.config, {
|
|
29
|
+
groupBy: this.options.groupBy,
|
|
30
|
+
ids: this.options.ids,
|
|
31
|
+
packageNames: this.options.packageNames,
|
|
32
|
+
repositoryNames: this.options.repositoryNames,
|
|
33
|
+
repositoryTypes: this.options.repositoryTypes,
|
|
34
|
+
tags: this.options.tags,
|
|
35
|
+
verbose: this.options.verbose,
|
|
36
|
+
});
|
|
29
37
|
const snapshots = await snapshotsAction.exec("prune");
|
|
30
38
|
const snapshotsDeleted = [];
|
|
31
39
|
const reasons = {};
|
|
32
|
-
const
|
|
40
|
+
const idFilter = {
|
|
41
|
+
id: this.options.ids,
|
|
42
|
+
};
|
|
43
|
+
const keepFilter = {
|
|
33
44
|
last: this.options.keepLast,
|
|
34
45
|
lastMinutely: this.options.keepMinutely,
|
|
35
46
|
lastHourly: this.options.keepHourly,
|
|
@@ -38,25 +49,30 @@ class PruneAction {
|
|
|
38
49
|
lastWeekly: this.options.keepWeekly,
|
|
39
50
|
lastYearly: this.options.keepYearly,
|
|
40
51
|
};
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
const hasIdFilter = Object.values(idFilter).some((v) => typeof v !== "undefined");
|
|
53
|
+
const hasKeepFilter = Object.values(keepFilter).some((v) => typeof v !== "undefined");
|
|
54
|
+
if (hasIdFilter && hasKeepFilter)
|
|
55
|
+
throw new Error(`Snapshot id filter can not be used with 'keep' filters`);
|
|
56
|
+
const usePrunePolicyConfig = !hasKeepFilter && this.options.groupBy?.includes("packageName");
|
|
57
|
+
const keepSnapshots = hasKeepFilter
|
|
58
|
+
? (0, snapshot_1.groupAndFilter)(snapshots, this.options.groupBy, usePrunePolicyConfig
|
|
59
|
+
? (groupedSnapshots) => {
|
|
60
|
+
const [firstSnapshot] = groupedSnapshots;
|
|
61
|
+
const packageName = firstSnapshot.packageName;
|
|
62
|
+
const config = this.config.packages.find((pkg) => pkg.name === packageName);
|
|
63
|
+
const prunePolicy = config?.prunePolicy ?? {};
|
|
64
|
+
return {
|
|
65
|
+
last: prunePolicy.keepLast,
|
|
66
|
+
lastMinutely: prunePolicy.keepMinutely,
|
|
67
|
+
lastHourly: prunePolicy.keepHourly,
|
|
68
|
+
lastDaily: prunePolicy.keepDaily,
|
|
69
|
+
lastMonthly: prunePolicy.keepMonthly,
|
|
70
|
+
lastWeekly: prunePolicy.keepWeekly,
|
|
71
|
+
lastYearly: prunePolicy.keepYearly,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
: keepFilter, reasons)
|
|
75
|
+
: [];
|
|
60
76
|
const result = {
|
|
61
77
|
total: snapshots.length,
|
|
62
78
|
prune: 0,
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { ConfigType } from "../Config/Config";
|
|
2
2
|
import { PackageConfigType } from "../Config/PackageConfig";
|
|
3
|
-
import {
|
|
4
|
-
import { SnapshotResultType } from "../Repository/RepositoryAbstract";
|
|
5
|
-
import { RestoreSessionManager } from "../SessionManager/RestoreSessionManager";
|
|
3
|
+
import { Snapshot } from "../Repository/RepositoryAbstract";
|
|
6
4
|
import { TaskAbstract } from "../Task/TaskAbstract";
|
|
5
|
+
import { DataFormat } from "../utils/DataFormat";
|
|
6
|
+
import { Listr3TaskResultEnd } from "../utils/list";
|
|
7
|
+
import { Progress } from "../utils/progress";
|
|
8
|
+
import { Streams } from "../utils/stream";
|
|
9
|
+
import { GargabeCollector } from "../utils/temp";
|
|
7
10
|
import { IfRequireKeys } from "../utils/ts";
|
|
8
|
-
export type
|
|
11
|
+
export type RestoreActionOptions = {
|
|
9
12
|
snapshotId: string;
|
|
10
13
|
tags?: string[];
|
|
11
14
|
packageNames?: string[];
|
|
@@ -15,32 +18,54 @@ export type RestoreActionOptionsType = {
|
|
|
15
18
|
repositoryTypes?: string[];
|
|
16
19
|
verbose?: boolean;
|
|
17
20
|
restorePath?: boolean;
|
|
21
|
+
tty?: "auto" | boolean;
|
|
22
|
+
progress?: "auto" | "interval" | boolean;
|
|
23
|
+
progressInterval?: number;
|
|
24
|
+
streams?: Streams;
|
|
18
25
|
};
|
|
19
|
-
type
|
|
26
|
+
type RestoreSnapshot = Snapshot & {
|
|
20
27
|
repositoryName: string;
|
|
21
28
|
};
|
|
22
|
-
type
|
|
29
|
+
type Context = {
|
|
30
|
+
snapshots: {
|
|
31
|
+
id: string;
|
|
32
|
+
packages: number;
|
|
33
|
+
};
|
|
34
|
+
task: {
|
|
35
|
+
taskName: string;
|
|
36
|
+
packageName: string;
|
|
37
|
+
};
|
|
38
|
+
restore: RestoreSnapshot;
|
|
39
|
+
};
|
|
23
40
|
export declare class RestoreAction<TRequired extends boolean = true> {
|
|
24
41
|
readonly config: ConfigType;
|
|
25
|
-
readonly options: IfRequireKeys<TRequired,
|
|
42
|
+
readonly options: IfRequireKeys<TRequired, RestoreActionOptions>;
|
|
26
43
|
protected taskErrors: Record<string, Error[]>;
|
|
27
44
|
protected repoErrors: Record<string, Error[]>;
|
|
28
|
-
constructor(config: ConfigType, options: IfRequireKeys<TRequired,
|
|
29
|
-
protected
|
|
30
|
-
protected
|
|
31
|
-
protected
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
tmpDirs: string[];
|
|
40
|
-
}>;
|
|
41
|
-
protected getError(pkg: PackageConfigType): Error | undefined;
|
|
42
|
-
exec(session: RestoreSessionManager): Promise<{
|
|
43
|
-
errors: Error[];
|
|
45
|
+
constructor(config: ConfigType, options: IfRequireKeys<TRequired, RestoreActionOptions>);
|
|
46
|
+
protected findSnapshots(): Promise<RestoreSnapshot[]>;
|
|
47
|
+
protected groupSnapshots(snapshots: RestoreSnapshot[]): RestoreSnapshot[];
|
|
48
|
+
protected restore(data: {
|
|
49
|
+
pkg: PackageConfigType;
|
|
50
|
+
task: TaskAbstract | undefined;
|
|
51
|
+
snapshot: RestoreSnapshot;
|
|
52
|
+
gc: GargabeCollector;
|
|
53
|
+
onProgress: (progress: Progress) => void;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
snapshotPath: string | undefined;
|
|
44
56
|
}>;
|
|
57
|
+
dataFormat(result: Listr3TaskResultEnd<Context>[], options?: {
|
|
58
|
+
streams?: Streams;
|
|
59
|
+
verbose?: number;
|
|
60
|
+
}): DataFormat;
|
|
61
|
+
exec(): Promise<({
|
|
62
|
+
key: "summary";
|
|
63
|
+
keyIndex?: string | undefined;
|
|
64
|
+
data: {
|
|
65
|
+
errors: number;
|
|
66
|
+
};
|
|
67
|
+
elapsed: number;
|
|
68
|
+
error?: Error | undefined;
|
|
69
|
+
} | import("../utils/list").Listr3TaskResult<Context>)[]>;
|
|
45
70
|
}
|
|
46
71
|
export {};
|