rbxts-orchestra 0.1.0-dev.1 → 0.1.1
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/dist/run.js +7 -3
- package/dist/src/commands/runScript.js +2 -2
- package/dist/src/commands/runScript.js.map +1 -1
- package/package.json +3 -2
- package/src/commands/index.ts +3 -0
- package/src/commands/runScript.ts +47 -0
- package/src/helpers/release.ts +45 -0
- package/src/helpers/script.ts +64 -0
- package/src/logger.ts +3 -0
- package/src/orchestra/config.ts +117 -0
- package/src/orchestra/index.ts +2 -0
- package/src/orchestra/orchestra.ts +52 -0
package/dist/run.js
CHANGED
|
@@ -32,7 +32,7 @@ var import_yargs = __toESM(require("yargs"));
|
|
|
32
32
|
// package.json
|
|
33
33
|
var package_default = {
|
|
34
34
|
name: "rbxts-orchestra",
|
|
35
|
-
version: "0.1.
|
|
35
|
+
version: "0.1.1",
|
|
36
36
|
description: "A build orchestrator.",
|
|
37
37
|
main: "src/index.ts",
|
|
38
38
|
bin: {
|
|
@@ -44,7 +44,8 @@ var package_default = {
|
|
|
44
44
|
},
|
|
45
45
|
files: [
|
|
46
46
|
"dist",
|
|
47
|
-
"bin/run"
|
|
47
|
+
"bin/run",
|
|
48
|
+
"src"
|
|
48
49
|
],
|
|
49
50
|
scripts: {
|
|
50
51
|
build: "tsup-node && tsc",
|
|
@@ -167,7 +168,10 @@ function builder(yargs2) {
|
|
|
167
168
|
async function handler(argv2) {
|
|
168
169
|
const delimiterIndex = process2.argv.findIndex((arg) => arg == "--");
|
|
169
170
|
const delimitedArgv = delimiterIndex !== -1 ? process2.argv.slice(delimiterIndex + 1) : void 0;
|
|
170
|
-
const orchestra = await Orchestra.fromFileConfig(argv2.config)
|
|
171
|
+
const orchestra = await Orchestra.fromFileConfig(argv2.config).catch(() => {
|
|
172
|
+
logger.error(`Failed to find config file at ${argv2.config}`);
|
|
173
|
+
process2.exit(1);
|
|
174
|
+
});
|
|
171
175
|
await orchestra.runScripts(argv2.script, delimitedArgv).catch((code) => {
|
|
172
176
|
logger.error(`Failed to run script: exit code ${code}`);
|
|
173
177
|
});
|
|
@@ -26,10 +26,10 @@ export function builder(yargs) {
|
|
|
26
26
|
export async function handler(argv) {
|
|
27
27
|
const delimiterIndex = process.argv.findIndex((arg) => arg == "--");
|
|
28
28
|
const delimitedArgv = delimiterIndex !== -1 ? process.argv.slice(delimiterIndex + 1) : undefined;
|
|
29
|
-
const orchestra = await Orchestra.fromFileConfig(argv.config)
|
|
29
|
+
const orchestra = await Orchestra.fromFileConfig(argv.config).catch(() => {
|
|
30
30
|
logger.error(`Failed to find config file at ${argv.config}`);
|
|
31
31
|
process.exit(1);
|
|
32
|
-
})
|
|
32
|
+
});
|
|
33
33
|
await orchestra.runScripts(argv.script, delimitedArgv).catch((code) => {
|
|
34
34
|
logger.error(`Failed to run script: exit code ${code}`);
|
|
35
35
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runScript.js","sourceRoot":"","sources":["../../../src/commands/runScript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAGxC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAOpE,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAC;AACtC,MAAM,CAAC,MAAM,QAAQ,GAAG,iDAAiD,CAAC;AAE1E,MAAM,UAAU,OAAO,CAAC,KAAoB;IAC3C,OAAO,KAAK;SACV,UAAU,CAAC,QAAQ,EAAE;QACrB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,aAAa;KAC1B,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,mCAAmC;QAChD,OAAO,EAAE,GAAG,yBAAyB,EAAE;KACvC,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QACnC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiC;IAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC
|
|
1
|
+
{"version":3,"file":"runScript.js","sourceRoot":"","sources":["../../../src/commands/runScript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AAGxC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAOpE,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAC;AACtC,MAAM,CAAC,MAAM,QAAQ,GAAG,iDAAiD,CAAC;AAE1E,MAAM,UAAU,OAAO,CAAC,KAAoB;IAC3C,OAAO,KAAK;SACV,UAAU,CAAC,QAAQ,EAAE;QACrB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,aAAa;KAC1B,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QACjB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,mCAAmC;QAChD,OAAO,EAAE,GAAG,yBAAyB,EAAE;KACvC,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;QACnC,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiC;IAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACxE,MAAM,CAAC,KAAK,CAAC,iCAAiC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;QACrE,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rbxts-orchestra",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "A build orchestrator.",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
|
-
"bin/run"
|
|
15
|
+
"bin/run",
|
|
16
|
+
"src"
|
|
16
17
|
],
|
|
17
18
|
"scripts": {
|
|
18
19
|
"build": "tsup-node && tsc",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isAbsolute, join } from "node:path";
|
|
2
|
+
import * as process from "node:process";
|
|
3
|
+
import { ArgumentsCamelCase, Argv } from "yargs";
|
|
4
|
+
|
|
5
|
+
import { logger } from "../logger";
|
|
6
|
+
import { Orchestra, ORCHESTRA_CONFIG_FILENAME } from "../orchestra";
|
|
7
|
+
|
|
8
|
+
interface RunArgv {
|
|
9
|
+
script: string;
|
|
10
|
+
config: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const command = "run <script>";
|
|
14
|
+
export const describe = "Runs build scripts for all orchestrated places.";
|
|
15
|
+
|
|
16
|
+
export function builder(yargs: Argv<RunArgv>): Argv {
|
|
17
|
+
return yargs
|
|
18
|
+
.positional("script", {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "script name",
|
|
21
|
+
})
|
|
22
|
+
.option("config", {
|
|
23
|
+
type: "string",
|
|
24
|
+
alias: "c",
|
|
25
|
+
description: "Path to the orchestra config file",
|
|
26
|
+
default: `${ORCHESTRA_CONFIG_FILENAME}`,
|
|
27
|
+
})
|
|
28
|
+
.coerce("config", (value: string) => {
|
|
29
|
+
if (isAbsolute(value)) {
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
return join(process.cwd(), value);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function handler(argv: ArgumentsCamelCase<RunArgv>) {
|
|
37
|
+
const delimiterIndex = process.argv.findIndex((arg) => arg == "--");
|
|
38
|
+
const delimitedArgv = delimiterIndex !== -1 ? process.argv.slice(delimiterIndex + 1) : undefined;
|
|
39
|
+
const orchestra = await Orchestra.fromFileConfig(argv.config).catch(() => {
|
|
40
|
+
logger.error(`Failed to find config file at ${argv.config}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
await orchestra.runScripts(argv.script, delimitedArgv).catch((code) => {
|
|
45
|
+
logger.error(`Failed to run script: exit code ${code}`);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { Environments, Value } from "src/orchestra";
|
|
3
|
+
|
|
4
|
+
export function semverString<E extends Environments>(
|
|
5
|
+
/**
|
|
6
|
+
* The base semver string (e.g `1.0.0`)
|
|
7
|
+
*/
|
|
8
|
+
baseSemver: string,
|
|
9
|
+
/**
|
|
10
|
+
* A list of environments in which to include the short hash of the
|
|
11
|
+
* currently checked out commit in the semver string
|
|
12
|
+
*/
|
|
13
|
+
commitHashEnvironments?: (keyof E)[],
|
|
14
|
+
/**
|
|
15
|
+
* A list of environments in which to include the name of the
|
|
16
|
+
* local user in the semver string
|
|
17
|
+
*/
|
|
18
|
+
userEnvironments?: (keyof E)[],
|
|
19
|
+
): Value<E, string> {
|
|
20
|
+
return (orchestra) => {
|
|
21
|
+
let shortCommitHash, localUsername;
|
|
22
|
+
try {
|
|
23
|
+
localUsername = execSync("whoami", {
|
|
24
|
+
stdio: "pipe",
|
|
25
|
+
})
|
|
26
|
+
.toString()
|
|
27
|
+
.trim();
|
|
28
|
+
shortCommitHash = execSync("git rev-parse --short HEAD", {
|
|
29
|
+
stdio: "pipe",
|
|
30
|
+
})
|
|
31
|
+
.toString()
|
|
32
|
+
.trim();
|
|
33
|
+
} catch {}
|
|
34
|
+
let semver = baseSemver;
|
|
35
|
+
|
|
36
|
+
if (localUsername && userEnvironments?.includes(orchestra.environment)) {
|
|
37
|
+
semver += `-${localUsername}`;
|
|
38
|
+
}
|
|
39
|
+
if (shortCommitHash && commitHashEnvironments?.includes(orchestra.environment)) {
|
|
40
|
+
semver += `+${shortCommitHash}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return semver;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import { resolve } from "path";
|
|
3
|
+
|
|
4
|
+
import { Environments, PlaceConfig, Script, val, Value } from "../orchestra/config";
|
|
5
|
+
import { Orchestra } from "../orchestra/orchestra";
|
|
6
|
+
|
|
7
|
+
interface SpawnConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Whether to wait until the process exits before continuing to the next script
|
|
10
|
+
*/
|
|
11
|
+
waitForExit: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to ignore a non-zero exit code
|
|
14
|
+
*/
|
|
15
|
+
ignoreNonZeroExitCode: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DEFAULT_SPAWN_CONFIG: SpawnConfig = {
|
|
19
|
+
waitForExit: true,
|
|
20
|
+
ignoreNonZeroExitCode: false,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function generateEnv<E extends Environments>(
|
|
24
|
+
orchestra: Orchestra<E>,
|
|
25
|
+
place?: PlaceConfig<E>,
|
|
26
|
+
): Record<string, string | undefined> {
|
|
27
|
+
return {
|
|
28
|
+
...process.env,
|
|
29
|
+
ORCHESTRA_DIR: resolve("."),
|
|
30
|
+
RELEASE_NUMBER: orchestra.resolveConfig(orchestra.config.releaseNumber),
|
|
31
|
+
RELEASE_NAME: orchestra.resolveConfig(orchestra.config.releaseName),
|
|
32
|
+
PLACE_ID: place && orchestra.resolveConfig(place.placeId)?.toString(),
|
|
33
|
+
EXPERIENCE_ID: place && orchestra.resolveConfig(place.experienceId)?.toString(),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function sh<E extends Environments>(cmd: string, config: Partial<SpawnConfig> = {}): Value<E, Script<E>> {
|
|
38
|
+
const fullConfig = {
|
|
39
|
+
...DEFAULT_SPAWN_CONFIG,
|
|
40
|
+
...config,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return val((orchestra, place, argv = []) => {
|
|
44
|
+
return new Promise((resolvePromise, reject) => {
|
|
45
|
+
const child = spawn(`${cmd}`, argv, {
|
|
46
|
+
cwd: place ? resolve(orchestra.resolveConfig(place.rootDir)) : undefined,
|
|
47
|
+
stdio: "inherit",
|
|
48
|
+
env: generateEnv(orchestra, place),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (fullConfig.waitForExit) {
|
|
52
|
+
child.on("exit", (code) => {
|
|
53
|
+
if (code !== 0 && !fullConfig.ignoreNonZeroExitCode) reject(code);
|
|
54
|
+
resolvePromise();
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
resolvePromise();
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export function script<E extends Environments>(path: string, config: Partial<SpawnConfig> = {}): Value<E, Script<E>> {
|
|
63
|
+
return sh(`${resolve(path)}`, config);
|
|
64
|
+
}
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Orchestra } from "./orchestra";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A value that is resolved using the Orchestra context
|
|
5
|
+
*/
|
|
6
|
+
export type Value<E extends Environments, T> = (orchestra: Orchestra<E>) => T;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Allow either a raw value or a computed one
|
|
10
|
+
*/
|
|
11
|
+
export type MaybeValue<E extends Environments, T> = T | Value<E, T>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a MaybeValue at runtime
|
|
15
|
+
*/
|
|
16
|
+
export function resolveValue<E extends Environments, T>(value: MaybeValue<E, T>, orchestra: Orchestra<E>): T {
|
|
17
|
+
return typeof value === "function" ? (value as Value<E, T>)(orchestra) : value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Helper to wrap static values
|
|
22
|
+
*/
|
|
23
|
+
export function val<E extends Environments, T>(value: T): Value<E, T> {
|
|
24
|
+
return () => value;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Environment-based value helper
|
|
29
|
+
*/
|
|
30
|
+
export function env<V extends Record<string, unknown>>(values: V) {
|
|
31
|
+
return <E extends { [K in keyof V]: EnvironmentConfig }>(orchestra: Orchestra<E>): V[keyof V] => {
|
|
32
|
+
return values[orchestra.environment as keyof V];
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type Script<E extends Environments> = (
|
|
37
|
+
orchestra: Orchestra<E>,
|
|
38
|
+
place?: PlaceConfig<E>,
|
|
39
|
+
argv?: string[],
|
|
40
|
+
) => Promise<void> | void;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A configuration for a place managed by an Orchestra
|
|
44
|
+
*/
|
|
45
|
+
export interface PlaceConfig<E extends Environments> {
|
|
46
|
+
rootDir: MaybeValue<E, string>;
|
|
47
|
+
placeId: MaybeValue<E, number>;
|
|
48
|
+
experienceId: MaybeValue<E, number>;
|
|
49
|
+
|
|
50
|
+
scripts: {
|
|
51
|
+
/**
|
|
52
|
+
* A callback that runs when this place is built by the Orchestra
|
|
53
|
+
*/
|
|
54
|
+
[k: string]: MaybeValue<E, Script<E>>;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A configuration for a specific environment within an Orchestra
|
|
60
|
+
*/
|
|
61
|
+
export interface EnvironmentConfig {
|
|
62
|
+
/**
|
|
63
|
+
* Whether to use this environment as the default if no other environments are chosen
|
|
64
|
+
*/
|
|
65
|
+
default?: boolean;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The NODE_ENV value that will result in this environment being chosen
|
|
69
|
+
*/
|
|
70
|
+
nodeEnv?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A list of environments available to an Orchestra
|
|
75
|
+
*/
|
|
76
|
+
export type Environments = {
|
|
77
|
+
[k: string]: EnvironmentConfig;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A configuration for an Orchestra
|
|
82
|
+
*/
|
|
83
|
+
export interface OrchestraConfig<E extends Environments> {
|
|
84
|
+
/**
|
|
85
|
+
* Semantic version
|
|
86
|
+
*/
|
|
87
|
+
releaseNumber: string;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Human-friendly release name
|
|
91
|
+
*/
|
|
92
|
+
releaseName: string;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Available environments
|
|
96
|
+
*/
|
|
97
|
+
environments: E;
|
|
98
|
+
|
|
99
|
+
scripts?: {
|
|
100
|
+
/**
|
|
101
|
+
* Callback that runs before any scripts are run
|
|
102
|
+
*/
|
|
103
|
+
prepare?: MaybeValue<E, Script<E>>;
|
|
104
|
+
} & Record<string, MaybeValue<E, Script<E>>>;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Places in this experience
|
|
108
|
+
*/
|
|
109
|
+
places: [PlaceConfig<E>, ...PlaceConfig<E>[]];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Create an Orchestra config
|
|
114
|
+
*/
|
|
115
|
+
export function orchestraConfig<const E extends Environments>(experience: OrchestraConfig<E>) {
|
|
116
|
+
return experience;
|
|
117
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import { createJiti } from "jiti";
|
|
3
|
+
import { resolve } from "path";
|
|
4
|
+
|
|
5
|
+
import { Environments, MaybeValue, OrchestraConfig, resolveValue } from "./config";
|
|
6
|
+
|
|
7
|
+
const jiti = createJiti(__filename);
|
|
8
|
+
|
|
9
|
+
export const ORCHESTRA_CONFIG_FILENAME = "orchestra.config.ts";
|
|
10
|
+
|
|
11
|
+
export class Orchestra<E extends Environments> {
|
|
12
|
+
public static async fromDirectory(directoryPath: string): Promise<Orchestra<never>> {
|
|
13
|
+
return await Orchestra.fromFileConfig(resolve(directoryPath, ORCHESTRA_CONFIG_FILENAME));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public static async fromFileConfig(filePath: string): Promise<Orchestra<never>> {
|
|
17
|
+
const config = await jiti.import(resolve(filePath), {
|
|
18
|
+
default: true,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return new Orchestra(config as OrchestraConfig<never>);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public readonly environment: keyof E;
|
|
25
|
+
|
|
26
|
+
constructor(public readonly config: OrchestraConfig<E>) {
|
|
27
|
+
for (const [environmentName, environmentConfig] of Object.entries(config.environments)) {
|
|
28
|
+
if (this!.environment) continue;
|
|
29
|
+
const NODE_ENV = process.env.NODE_ENV ?? "unknown";
|
|
30
|
+
if (environmentConfig.default) {
|
|
31
|
+
this.environment = environmentName;
|
|
32
|
+
} else if (NODE_ENV == environmentConfig.nodeEnv) {
|
|
33
|
+
this.environment = environmentName;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
assert(this!.environment, `Orchestra confiag is invalid, no default or otherwise valid environments provided`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async runScripts(scriptName: string, argv?: string[]) {
|
|
40
|
+
await this.resolveConfig(this.config.scripts?.prepare)?.(this, undefined, argv);
|
|
41
|
+
|
|
42
|
+
await this.resolveConfig(this.config.scripts?.[scriptName])?.(this, undefined, argv);
|
|
43
|
+
|
|
44
|
+
for (const place of this.config.places) {
|
|
45
|
+
await this.resolveConfig(place.scripts[scriptName])?.(this, place, argv);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public resolveConfig<T>(config: MaybeValue<E, T>): T {
|
|
50
|
+
return resolveValue(config, this);
|
|
51
|
+
}
|
|
52
|
+
}
|