@decohere/devkit 0.0.1-dev.119
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/README.md +14 -0
- package/commonjs/src/cli/action.js +65 -0
- package/commonjs/src/cli/command.js +127 -0
- package/commonjs/src/cli/index.js +61 -0
- package/commonjs/src/cli/module.type.js +18 -0
- package/commonjs/src/cli/options.js +115 -0
- package/commonjs/src/diagnostics/index.js +22 -0
- package/commonjs/src/diagnostics/trace.js +79 -0
- package/commonjs/src/interop/docker/docker.js +54 -0
- package/commonjs/src/interop/errors/interop.error.js +12 -0
- package/commonjs/src/interop/git/git.js +134 -0
- package/commonjs/src/interop/git/git.types.js +4 -0
- package/commonjs/src/interop/index.js +97 -0
- package/commonjs/src/interop/node/index.js +18 -0
- package/commonjs/src/interop/node/node.js +45 -0
- package/commonjs/src/interop/npm/npm.js +231 -0
- package/commonjs/src/interop/npm/npm.types.js +16 -0
- package/commonjs/src/interop/pnpm/pnpm.js +34 -0
- package/commonjs/src/interop/pnpm/pnpm.types.js +4 -0
- package/commonjs/src/interop/shell/shell.argv.js +45 -0
- package/commonjs/src/interop/shell/shell.js +105 -0
- package/commonjs/src/interop/shell/shell.types.js +4 -0
- package/commonjs/src/interop/types/detect-package-manager.js +71 -0
- package/commonjs/src/interop/types/package-manager.js +4 -0
- package/commonjs/src/interop/yarn/yarn.js +34 -0
- package/commonjs/src/interop/yarn/yarn.types.js +4 -0
- package/commonjs/src/io/find-directories.js +21 -0
- package/commonjs/src/io/find-file.js +45 -0
- package/commonjs/src/io/index.js +20 -0
- package/commonjs/src/io/watch.js +261 -0
- package/es6/src/cli/action.js +47 -0
- package/es6/src/cli/command.js +106 -0
- package/es6/src/cli/index.js +4 -0
- package/es6/src/cli/module.type.js +11 -0
- package/es6/src/cli/options.js +76 -0
- package/es6/src/diagnostics/index.js +1 -0
- package/es6/src/diagnostics/trace.js +61 -0
- package/es6/src/interop/docker/docker.js +44 -0
- package/es6/src/interop/errors/interop.error.js +2 -0
- package/es6/src/interop/git/git.js +124 -0
- package/es6/src/interop/git/git.types.js +1 -0
- package/es6/src/interop/index.js +21 -0
- package/es6/src/interop/node/index.js +1 -0
- package/es6/src/interop/node/node.js +35 -0
- package/es6/src/interop/npm/npm.js +180 -0
- package/es6/src/interop/npm/npm.types.js +6 -0
- package/es6/src/interop/pnpm/pnpm.js +24 -0
- package/es6/src/interop/pnpm/pnpm.types.js +1 -0
- package/es6/src/interop/shell/shell.argv.js +35 -0
- package/es6/src/interop/shell/shell.js +95 -0
- package/es6/src/interop/shell/shell.types.js +1 -0
- package/es6/src/interop/types/detect-package-manager.js +50 -0
- package/es6/src/interop/types/package-manager.js +1 -0
- package/es6/src/interop/yarn/yarn.js +24 -0
- package/es6/src/interop/yarn/yarn.types.js +1 -0
- package/es6/src/io/find-directories.js +11 -0
- package/es6/src/io/find-file.js +27 -0
- package/es6/src/io/index.js +3 -0
- package/es6/src/io/watch.js +238 -0
- package/package.json +49 -0
- package/types/src/cli/action.d.ts +36 -0
- package/types/src/cli/command.d.ts +34 -0
- package/types/src/cli/index.d.ts +7 -0
- package/types/src/cli/module.type.d.ts +36 -0
- package/types/src/cli/options.d.ts +28 -0
- package/types/src/diagnostics/index.d.ts +1 -0
- package/types/src/diagnostics/trace.d.ts +10 -0
- package/types/src/interop/docker/docker.d.ts +19 -0
- package/types/src/interop/errors/interop.error.d.ts +2 -0
- package/types/src/interop/git/git.d.ts +16 -0
- package/types/src/interop/git/git.types.d.ts +14 -0
- package/types/src/interop/index.d.ts +14 -0
- package/types/src/interop/node/index.d.ts +1 -0
- package/types/src/interop/node/node.d.ts +5 -0
- package/types/src/interop/npm/npm.d.ts +29 -0
- package/types/src/interop/npm/npm.types.d.ts +24 -0
- package/types/src/interop/pnpm/pnpm.d.ts +9 -0
- package/types/src/interop/pnpm/pnpm.types.d.ts +3 -0
- package/types/src/interop/shell/shell.argv.d.ts +5 -0
- package/types/src/interop/shell/shell.d.ts +6 -0
- package/types/src/interop/shell/shell.types.d.ts +9 -0
- package/types/src/interop/types/detect-package-manager.d.ts +4 -0
- package/types/src/interop/types/package-manager.d.ts +10 -0
- package/types/src/interop/yarn/yarn.d.ts +9 -0
- package/types/src/interop/yarn/yarn.types.d.ts +3 -0
- package/types/src/io/find-directories.d.ts +2 -0
- package/types/src/io/find-file.d.ts +9 -0
- package/types/src/io/index.d.ts +3 -0
- package/types/src/io/watch.d.ts +16 -0
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Devkit
|
|
2
|
+
|
|
3
|
+
The shared base for Decohere's command-line tools: forge, flux, the `decohere` CLI and the scaffolder ([ADR 0015](../../docs/adr/0015-core-devkit-testing.md)). Nothing here runs in a production app, so a production install never pulls in `commander`, `glob` or `picomatch` through it.
|
|
4
|
+
|
|
5
|
+
| Subpath | What it is |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `@decohere/devkit/cli` | The command framework on [commander](https://github.com/tj/commander.js): `DecohereCommand`, `Action`, and the shared options (`--configuration`, `--log-level`, `--env-file`, `--dry-run`, …) |
|
|
8
|
+
| `@decohere/devkit/interop` | Typed wrappers that run `git`, `npm`, `pnpm`, `yarn`, `docker` and `node`, plus package-manager detection |
|
|
9
|
+
| `@decohere/devkit/diagnostics` | `@trace` (method timings when `FORGE_TRACE` is set) and `@timed` (always) |
|
|
10
|
+
| `@decohere/devkit/io` | File search and watch: `findFiles`, `findFile`, `findDirectories`, `watch`, `WatchEvents` |
|
|
11
|
+
|
|
12
|
+
Basic file operations (`fileExists`, `readFile`, `writeFile`, …) and the file types (`FileEx`, `Watcher`) stay in `@decohere/core/io`, where runtime packages can use them without these dependencies.
|
|
13
|
+
|
|
14
|
+
`@trace` reads `FORGE_TRACE` when a method is decorated, and importing it changes nothing. The bins decide the log level: `FORGE_TRACE` makes them log at `trace` unless `--log-level` or a level in the environment says otherwise.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get ActionMap () {
|
|
13
|
+
return ActionMap;
|
|
14
|
+
},
|
|
15
|
+
get ActionResponse () {
|
|
16
|
+
return ActionResponse;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const ActionMap = Symbol("ActionMap");
|
|
20
|
+
class ActionResponse {
|
|
21
|
+
static Success(name, data) {
|
|
22
|
+
return new ActionResponse({
|
|
23
|
+
name,
|
|
24
|
+
data,
|
|
25
|
+
succeeded: true
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
static Skipped(name) {
|
|
29
|
+
return new ActionResponse({
|
|
30
|
+
name,
|
|
31
|
+
skipped: true
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
static Blocking(name) {
|
|
35
|
+
return new ActionResponse({
|
|
36
|
+
name,
|
|
37
|
+
succeeded: true,
|
|
38
|
+
blocking: true
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
static Error(name, messageOrData, data) {
|
|
42
|
+
if (Array.isArray(messageOrData)) {
|
|
43
|
+
const message = messageOrData.filter((r)=>!r.succeeded).map((r)=>r.error ?? "Unknown error").join("\n");
|
|
44
|
+
return new ActionResponse({
|
|
45
|
+
name,
|
|
46
|
+
message,
|
|
47
|
+
data: messageOrData
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return new ActionResponse({
|
|
51
|
+
name,
|
|
52
|
+
message: messageOrData,
|
|
53
|
+
data
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
constructor(data){
|
|
57
|
+
Object.assign(this, data);
|
|
58
|
+
}
|
|
59
|
+
name;
|
|
60
|
+
succeeded = false;
|
|
61
|
+
skipped = false;
|
|
62
|
+
blocking = false;
|
|
63
|
+
message;
|
|
64
|
+
data;
|
|
65
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get CommandError () {
|
|
13
|
+
return CommandError;
|
|
14
|
+
},
|
|
15
|
+
get CommandResponse () {
|
|
16
|
+
return CommandResponse;
|
|
17
|
+
},
|
|
18
|
+
get DecohereCommand () {
|
|
19
|
+
return DecohereCommand;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _commander = require("commander");
|
|
23
|
+
const CommandResponse = {
|
|
24
|
+
success (_ctx, responses) {
|
|
25
|
+
return responses;
|
|
26
|
+
},
|
|
27
|
+
help () {
|
|
28
|
+
return {};
|
|
29
|
+
},
|
|
30
|
+
fromAction (name, response) {
|
|
31
|
+
return {
|
|
32
|
+
[name]: response
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
class CommandError extends Error {
|
|
37
|
+
}
|
|
38
|
+
class DecohereCommand extends _commander.Command {
|
|
39
|
+
get actions() {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
constructor(name, handler){
|
|
43
|
+
super();
|
|
44
|
+
if (typeof name === "string" || typeof name === "function") {
|
|
45
|
+
this.name(this.parseCommandName(name));
|
|
46
|
+
} else {
|
|
47
|
+
this.name(this.parseCommandName(this.constructor));
|
|
48
|
+
if (name) {
|
|
49
|
+
this.registerSubcommand(name, handler);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (handler && !this.commands.length) {
|
|
53
|
+
this.action(handler);
|
|
54
|
+
}
|
|
55
|
+
this.exitOverride();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Whether the command, with these options, runs until it is stopped (`flux serve`,
|
|
59
|
+
* `forge build --watch`). The CLI then listens for SIGINT and SIGTERM from the moment it
|
|
60
|
+
* starts, so a stop during start-up still shuts down cleanly; other commands keep Node's
|
|
61
|
+
* default, where Ctrl+C ends them at once.
|
|
62
|
+
*/ runsUntilStopped(_options) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
async run(actions, options) {
|
|
66
|
+
const responses = await this.runActions(actions, options);
|
|
67
|
+
this.throwOnErrors(responses);
|
|
68
|
+
return CommandResponse.success(options, responses);
|
|
69
|
+
}
|
|
70
|
+
registerSubcommand(commands, onAction) {
|
|
71
|
+
if (typeof commands === "function") {
|
|
72
|
+
const instance = new commands(commands, onAction);
|
|
73
|
+
this.addCommand(instance);
|
|
74
|
+
if (onAction && !instance.commands.length) {
|
|
75
|
+
instance.action(onAction);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
for (const [key, command] of Object.entries(commands)){
|
|
80
|
+
const instance = command instanceof DecohereCommand ? command : new command(key, onAction);
|
|
81
|
+
this.addCommand(instance);
|
|
82
|
+
if (onAction && !instance.commands.length) {
|
|
83
|
+
instance.action(onAction);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async runActions(actions, options) {
|
|
88
|
+
const selectedActions = this.getSelectedActions(actions);
|
|
89
|
+
const responses = {};
|
|
90
|
+
for (const [actionKey, action] of selectedActions){
|
|
91
|
+
responses[actionKey] = await action.run(options);
|
|
92
|
+
}
|
|
93
|
+
return responses;
|
|
94
|
+
}
|
|
95
|
+
getSelectedActions(actions) {
|
|
96
|
+
if (!this.actions.length) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
const actionEntries = Object.entries(actions);
|
|
100
|
+
return this.actions.map((ActionClass)=>{
|
|
101
|
+
const selectedAction = actionEntries.find(([, action])=>action instanceof ActionClass);
|
|
102
|
+
if (!selectedAction) {
|
|
103
|
+
throw new CommandError(`${this.name()} command missing action instance for ${ActionClass.name}`);
|
|
104
|
+
}
|
|
105
|
+
return selectedAction;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
throwOnErrors(responses) {
|
|
109
|
+
const failures = Object.entries(responses).filter(([, response])=>{
|
|
110
|
+
if (!response) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
return !response.succeeded && !response.skipped;
|
|
114
|
+
});
|
|
115
|
+
if (!failures.length) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
throw new CommandError(`${this.name()} command failed. ${failures.map(([actionName, response])=>`${actionName}: ${response?.message ?? "Unknown error"}`).join("\n")}`);
|
|
119
|
+
}
|
|
120
|
+
parseCommandName(stringLike) {
|
|
121
|
+
const command = typeof stringLike === "string" ? stringLike : stringLike.name?.toLowerCase().replace("command", "") ?? "";
|
|
122
|
+
if (command === "") {
|
|
123
|
+
throw new CommandError(`Could not parse command name from ${stringLike.toString()}`);
|
|
124
|
+
}
|
|
125
|
+
return command;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get ActionMap () {
|
|
13
|
+
return _action.ActionMap;
|
|
14
|
+
},
|
|
15
|
+
get ActionResponse () {
|
|
16
|
+
return _action.ActionResponse;
|
|
17
|
+
},
|
|
18
|
+
get CommandError () {
|
|
19
|
+
return _command.CommandError;
|
|
20
|
+
},
|
|
21
|
+
get CommandResponse () {
|
|
22
|
+
return _command.CommandResponse;
|
|
23
|
+
},
|
|
24
|
+
get ConfigFileOption () {
|
|
25
|
+
return _options.ConfigFileOption;
|
|
26
|
+
},
|
|
27
|
+
get ConfigurationOption () {
|
|
28
|
+
return _options.ConfigurationOption;
|
|
29
|
+
},
|
|
30
|
+
get DecohereCommand () {
|
|
31
|
+
return _command.DecohereCommand;
|
|
32
|
+
},
|
|
33
|
+
get DryRunOption () {
|
|
34
|
+
return _options.DryRunOption;
|
|
35
|
+
},
|
|
36
|
+
get EnvFileIfExistsOption () {
|
|
37
|
+
return _options.EnvFileIfExistsOption;
|
|
38
|
+
},
|
|
39
|
+
get EnvFileOption () {
|
|
40
|
+
return _options.EnvFileOption;
|
|
41
|
+
},
|
|
42
|
+
get LogLevelOption () {
|
|
43
|
+
return _options.LogLevelOption;
|
|
44
|
+
},
|
|
45
|
+
get ModuleManifest () {
|
|
46
|
+
return _moduletype.ModuleManifest;
|
|
47
|
+
},
|
|
48
|
+
get NoBuildOptions () {
|
|
49
|
+
return _options.NoBuildOptions;
|
|
50
|
+
},
|
|
51
|
+
get NoCleanOptions () {
|
|
52
|
+
return _options.NoCleanOptions;
|
|
53
|
+
},
|
|
54
|
+
get ProjectOption () {
|
|
55
|
+
return _options.ProjectOption;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const _action = require("./action.js");
|
|
59
|
+
const _command = require("./command.js");
|
|
60
|
+
const _moduletype = require("./module.type.js");
|
|
61
|
+
const _options = require("./options.js");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ModuleManifest", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ModuleManifest;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
class ModuleManifest {
|
|
12
|
+
/** Sub-command classes this module contributes. */ commands = {};
|
|
13
|
+
/** Action classes this module contributes. */ actions = {};
|
|
14
|
+
/** Register infrastructure services into the DI container. */ registerServices(_builder) {}
|
|
15
|
+
/** Lazily create a workspace instance. Return null if this module does not use a workspace. */ createWorkspace(_options) {
|
|
16
|
+
return Promise.resolve(null);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get ConfigFileOption () {
|
|
13
|
+
return ConfigFileOption;
|
|
14
|
+
},
|
|
15
|
+
get ConfigurationOption () {
|
|
16
|
+
return ConfigurationOption;
|
|
17
|
+
},
|
|
18
|
+
get DryRunOption () {
|
|
19
|
+
return DryRunOption;
|
|
20
|
+
},
|
|
21
|
+
get EnvFileIfExistsOption () {
|
|
22
|
+
return EnvFileIfExistsOption;
|
|
23
|
+
},
|
|
24
|
+
get EnvFileOption () {
|
|
25
|
+
return EnvFileOption;
|
|
26
|
+
},
|
|
27
|
+
get LogLevelOption () {
|
|
28
|
+
return LogLevelOption;
|
|
29
|
+
},
|
|
30
|
+
get NoBuildOptions () {
|
|
31
|
+
return NoBuildOptions;
|
|
32
|
+
},
|
|
33
|
+
get NoCleanOptions () {
|
|
34
|
+
return NoCleanOptions;
|
|
35
|
+
},
|
|
36
|
+
get ProjectOption () {
|
|
37
|
+
return ProjectOption;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const _commander = require("commander");
|
|
41
|
+
function parseOptionalBoolean(input) {
|
|
42
|
+
if (typeof input === "boolean") {
|
|
43
|
+
return input;
|
|
44
|
+
}
|
|
45
|
+
const value = input.trim().toLowerCase();
|
|
46
|
+
if ([
|
|
47
|
+
"true",
|
|
48
|
+
"1",
|
|
49
|
+
"yes",
|
|
50
|
+
"on"
|
|
51
|
+
].includes(value)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if ([
|
|
55
|
+
"false",
|
|
56
|
+
"0",
|
|
57
|
+
"no",
|
|
58
|
+
"off"
|
|
59
|
+
].includes(value)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`Invalid boolean value: "${input}". Use true/false.`);
|
|
63
|
+
}
|
|
64
|
+
class ConfigurationOption extends _commander.Option {
|
|
65
|
+
constructor(defaultValue){
|
|
66
|
+
super("--configuration <configuration>", "Configuration name");
|
|
67
|
+
this.default(defaultValue);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
class ConfigFileOption extends _commander.Option {
|
|
71
|
+
constructor(defaultValue = ".decohere.js"){
|
|
72
|
+
super("--config-file <file>", "Path to Decohere config file");
|
|
73
|
+
this.default(defaultValue);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
class LogLevelOption extends _commander.Option {
|
|
77
|
+
constructor(){
|
|
78
|
+
super("--log-level <level>", "Log level (trace, debug, info, warn, error)");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
class EnvFileOption extends _commander.Option {
|
|
82
|
+
constructor(){
|
|
83
|
+
super("--env-file <file>", "Load environment variables from this file before running");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
class EnvFileIfExistsOption extends _commander.Option {
|
|
87
|
+
constructor(){
|
|
88
|
+
super("--env-file-if-exists <file>", "Like --env-file, but skip it when the file is missing");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
class NoCleanOptions extends _commander.Option {
|
|
92
|
+
constructor(defaultValue){
|
|
93
|
+
super("--no-clean", "Will not clean the project directories");
|
|
94
|
+
this.default(defaultValue);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class NoBuildOptions extends _commander.Option {
|
|
98
|
+
constructor(defaultValue){
|
|
99
|
+
super("--no-build", "Will not run the build step");
|
|
100
|
+
this.default(defaultValue);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
class DryRunOption extends _commander.Option {
|
|
104
|
+
constructor(description, defaultValue = false){
|
|
105
|
+
super("--dry-run [dryRun]", description);
|
|
106
|
+
this.default(defaultValue);
|
|
107
|
+
this.preset(true);
|
|
108
|
+
this.argParser(parseOptionalBoolean);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
class ProjectOption extends _commander.Option {
|
|
112
|
+
constructor(){
|
|
113
|
+
super("--project <project>", "Project name to target");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get Trace () {
|
|
13
|
+
return _trace.Trace;
|
|
14
|
+
},
|
|
15
|
+
get timed () {
|
|
16
|
+
return _trace.timed;
|
|
17
|
+
},
|
|
18
|
+
get trace () {
|
|
19
|
+
return _trace.trace;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _trace = require("./trace.js");
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get Trace () {
|
|
13
|
+
return Trace;
|
|
14
|
+
},
|
|
15
|
+
get timed () {
|
|
16
|
+
return timed;
|
|
17
|
+
},
|
|
18
|
+
get trace () {
|
|
19
|
+
return trace;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _types = require("node:util/types");
|
|
23
|
+
const _scribe = require("@decohere/scribe");
|
|
24
|
+
/**
|
|
25
|
+
* Trace mode is toggled with FORGE_TRACE, read when a method is decorated. Raising the log level
|
|
26
|
+
* to see the output is the CLI's job at its entry point: importing this module changes nothing.
|
|
27
|
+
*/ function isTraceEnabled() {
|
|
28
|
+
return process.env.FORGE_TRACE != null;
|
|
29
|
+
}
|
|
30
|
+
function serializeArgs(args) {
|
|
31
|
+
if (args.length === 0) return "";
|
|
32
|
+
return args.map((arg)=>{
|
|
33
|
+
if (Array.isArray(arg)) return `[${arg.map(String).join(", ")}]`;
|
|
34
|
+
const s = String(arg);
|
|
35
|
+
return s.length > 60 ? `${s.slice(0, 57)}...` : s;
|
|
36
|
+
}).join(", ");
|
|
37
|
+
}
|
|
38
|
+
function wrapWithTiming(fn, className, methodName, logLevel) {
|
|
39
|
+
let logger;
|
|
40
|
+
return function(...args) {
|
|
41
|
+
if (logger == null) {
|
|
42
|
+
logger = _scribe.scribe.logger(className);
|
|
43
|
+
}
|
|
44
|
+
const log = logger;
|
|
45
|
+
const label = `${methodName}(${serializeArgs(args)})`;
|
|
46
|
+
const start = performance.now();
|
|
47
|
+
const logDuration = ()=>{
|
|
48
|
+
log[logLevel](`${label}: ${(performance.now() - start).toFixed(2)}ms`);
|
|
49
|
+
};
|
|
50
|
+
const result = fn.apply(this, args);
|
|
51
|
+
if ((0, _types.isPromise)(result)) {
|
|
52
|
+
return result.finally(logDuration);
|
|
53
|
+
}
|
|
54
|
+
logDuration();
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function trace(target, propertyKey, descriptor) {
|
|
59
|
+
if (!isTraceEnabled()) return descriptor;
|
|
60
|
+
const className = target.constructor.name;
|
|
61
|
+
descriptor.value = wrapWithTiming(descriptor.value, className, propertyKey, "trace");
|
|
62
|
+
return descriptor;
|
|
63
|
+
}
|
|
64
|
+
function timed(target, propertyKey, descriptor) {
|
|
65
|
+
const className = target.constructor.name;
|
|
66
|
+
descriptor.value = wrapWithTiming(descriptor.value, className, propertyKey, "info");
|
|
67
|
+
return descriptor;
|
|
68
|
+
}
|
|
69
|
+
function Trace(constructor) {
|
|
70
|
+
if (!isTraceEnabled()) return;
|
|
71
|
+
const className = constructor.name;
|
|
72
|
+
for (const key of Object.getOwnPropertyNames(constructor.prototype)){
|
|
73
|
+
if (key === "constructor") continue;
|
|
74
|
+
const descriptor = Object.getOwnPropertyDescriptor(constructor.prototype, key);
|
|
75
|
+
if (descriptor == null || typeof descriptor.value !== "function") continue;
|
|
76
|
+
descriptor.value = wrapWithTiming(descriptor.value, className, key, "trace");
|
|
77
|
+
Object.defineProperty(constructor.prototype, key, descriptor);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "Docker", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return Docker;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _interoperror = require("../errors/interop.error.js");
|
|
12
|
+
const _shell = require("../shell/shell.js");
|
|
13
|
+
class Docker extends _shell.Shell {
|
|
14
|
+
name = "docker";
|
|
15
|
+
program = "docker";
|
|
16
|
+
async build(contextDir, options = {}) {
|
|
17
|
+
if (contextDir == null || contextDir.trim() === "") {
|
|
18
|
+
throw new _interoperror.InteropError("Docker build context is required");
|
|
19
|
+
}
|
|
20
|
+
const args = [
|
|
21
|
+
"build"
|
|
22
|
+
];
|
|
23
|
+
if (options.dockerfile) {
|
|
24
|
+
args.push("-f", options.dockerfile);
|
|
25
|
+
}
|
|
26
|
+
for (const tag of options.tags ?? []){
|
|
27
|
+
args.push("-t", tag);
|
|
28
|
+
}
|
|
29
|
+
for (const [key, value] of Object.entries(options.buildArgs ?? {})){
|
|
30
|
+
args.push("--build-arg", `${key}=${value}`);
|
|
31
|
+
}
|
|
32
|
+
for (const [id, env] of Object.entries(options.secrets ?? {})){
|
|
33
|
+
args.push("--secret", `id=${id},env=${env}`);
|
|
34
|
+
}
|
|
35
|
+
if (options.noCache) {
|
|
36
|
+
args.push("--no-cache");
|
|
37
|
+
}
|
|
38
|
+
if (options.pull) {
|
|
39
|
+
args.push("--pull");
|
|
40
|
+
}
|
|
41
|
+
args.push(contextDir);
|
|
42
|
+
return await this.run({
|
|
43
|
+
cwd: options.cwd
|
|
44
|
+
}, ...args);
|
|
45
|
+
}
|
|
46
|
+
async push(tag, options = {}) {
|
|
47
|
+
if (tag == null || tag.trim() === "") {
|
|
48
|
+
throw new _interoperror.InteropError("Docker tag is required");
|
|
49
|
+
}
|
|
50
|
+
return await this.run({
|
|
51
|
+
cwd: options.cwd
|
|
52
|
+
}, "push", tag);
|
|
53
|
+
}
|
|
54
|
+
}
|