@smoothbricks/cli 0.4.1 → 0.4.2
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/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +11 -0
- package/dist/monorepo/packs/index.js +2 -0
- package/dist/nx/index.d.ts +4 -0
- package/dist/nx/index.d.ts.map +1 -1
- package/dist/nx/index.js +32 -0
- package/managed/raw/envrc +18 -0
- package/managed/raw/tooling/direnv/setup-environment.ts +131 -0
- package/package.json +2 -2
- package/src/monorepo/managed-files.ts +11 -0
- package/src/monorepo/packs/index.ts +2 -0
- package/src/nx/index.ts +36 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,GAAG,YAAY,CAAC;CACxG;
|
|
1
|
+
{"version":3,"file":"managed-files.d.ts","sourceRoot":"","sources":["../../src/monorepo/managed-files.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,GAAG,YAAY,CAAC;CACxG;AAmGD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,EAAE,CAG/F;AA4KD,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAIxD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQzD"}
|
|
@@ -6,6 +6,11 @@ import { listReleasePackages, readPackageJson } from '../lib/workspace.js';
|
|
|
6
6
|
import { renderCiWorkflowYaml } from './ci-workflow.js';
|
|
7
7
|
import { renderPublishWorkflowYaml } from './publish-workflow.js';
|
|
8
8
|
const managedFiles = [
|
|
9
|
+
{
|
|
10
|
+
kind: 'raw',
|
|
11
|
+
source: 'envrc',
|
|
12
|
+
target: '.envrc',
|
|
13
|
+
},
|
|
9
14
|
{
|
|
10
15
|
kind: 'raw',
|
|
11
16
|
source: 'tooling/direnv/repo-path',
|
|
@@ -18,6 +23,12 @@ const managedFiles = [
|
|
|
18
23
|
target: 'tooling/direnv/github-actions-bootstrap.sh',
|
|
19
24
|
executable: true,
|
|
20
25
|
},
|
|
26
|
+
{
|
|
27
|
+
kind: 'raw',
|
|
28
|
+
source: 'tooling/direnv/setup-environment.ts',
|
|
29
|
+
target: 'tooling/direnv/setup-environment.ts',
|
|
30
|
+
executable: true,
|
|
31
|
+
},
|
|
21
32
|
{
|
|
22
33
|
kind: 'raw',
|
|
23
34
|
source: 'tooling/git-hooks/pre-commit.sh',
|
|
@@ -296,6 +296,8 @@ async function readResolvedTargetsByProject(ctx) {
|
|
|
296
296
|
{
|
|
297
297
|
targets: new Set(project.targets),
|
|
298
298
|
...(project.buildDependsOn ? { buildDependsOn: project.buildDependsOn } : {}),
|
|
299
|
+
...(project.targetExecutors ? { targetExecutors: project.targetExecutors } : {}),
|
|
300
|
+
...(project.targetScripts ? { targetScripts: project.targetScripts } : {}),
|
|
299
301
|
},
|
|
300
302
|
]));
|
|
301
303
|
}
|
package/dist/nx/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export interface ProjectTargets {
|
|
|
2
2
|
project: string;
|
|
3
3
|
targets: string[];
|
|
4
4
|
buildDependsOn?: string[];
|
|
5
|
+
targetExecutors?: Map<string, string>;
|
|
6
|
+
targetScripts?: Map<string, string>;
|
|
5
7
|
}
|
|
6
8
|
export interface CommandInvocation {
|
|
7
9
|
command: string;
|
|
@@ -12,6 +14,8 @@ export declare function nxShowProjectCommand(project: string): CommandInvocation
|
|
|
12
14
|
export declare function nxCacheDirectories(root: string): string[];
|
|
13
15
|
export declare function targetNamesFromNxProjectJson(value: unknown): string[];
|
|
14
16
|
export declare function buildDependsOnFromNxProjectJson(value: unknown): string[] | undefined;
|
|
17
|
+
export declare function targetExecutorsFromNxProjectJson(value: unknown): Map<string, string>;
|
|
18
|
+
export declare function targetScriptsFromNxProjectJson(value: unknown): Map<string, string>;
|
|
15
19
|
export declare function formatProjectTargetLines(projects: ProjectTargets[]): string;
|
|
16
20
|
export declare function projectNamesWithTarget(projects: ProjectTargets[], target: string): string[];
|
|
17
21
|
export declare function projectNamesFromNxShowProjectsOutput(output: string): string[];
|
package/dist/nx/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAOpF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYpF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBlF;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAK3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3F;AAED,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB7E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhG;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAGhF"}
|
package/dist/nx/index.js
CHANGED
|
@@ -25,6 +25,36 @@ export function buildDependsOnFromNxProjectJson(value) {
|
|
|
25
25
|
}
|
|
26
26
|
return build.dependsOn;
|
|
27
27
|
}
|
|
28
|
+
export function targetExecutorsFromNxProjectJson(value) {
|
|
29
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
30
|
+
const executors = new Map();
|
|
31
|
+
if (!targets) {
|
|
32
|
+
return executors;
|
|
33
|
+
}
|
|
34
|
+
for (const [targetName, target] of Object.entries(targets)) {
|
|
35
|
+
if (isRecord(target) && typeof target.executor === 'string') {
|
|
36
|
+
executors.set(targetName, target.executor);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return executors;
|
|
40
|
+
}
|
|
41
|
+
export function targetScriptsFromNxProjectJson(value) {
|
|
42
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
43
|
+
const scripts = new Map();
|
|
44
|
+
if (!targets) {
|
|
45
|
+
return scripts;
|
|
46
|
+
}
|
|
47
|
+
for (const [targetName, target] of Object.entries(targets)) {
|
|
48
|
+
if (!isRecord(target)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const options = recordProperty(target, 'options');
|
|
52
|
+
if (typeof options?.script === 'string') {
|
|
53
|
+
scripts.set(targetName, options.script);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return scripts;
|
|
57
|
+
}
|
|
28
58
|
export function formatProjectTargetLines(projects) {
|
|
29
59
|
return projects
|
|
30
60
|
.flatMap((project) => project.targets.map((target) => `${project.project}:${target}`))
|
|
@@ -108,5 +138,7 @@ async function readProjectTarget(root, project) {
|
|
|
108
138
|
project,
|
|
109
139
|
targets: targetNamesFromNxProjectJson(parsed),
|
|
110
140
|
buildDependsOn: buildDependsOnFromNxProjectJson(parsed),
|
|
141
|
+
targetExecutors: targetExecutorsFromNxProjectJson(parsed),
|
|
142
|
+
targetScripts: targetScriptsFromNxProjectJson(parsed),
|
|
111
143
|
};
|
|
112
144
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Worktrees inherit the real project .envrc once, then stop. The same file is
|
|
2
|
+
# checked out inside .jcode-worktrees, so continuing after source_up_if_exists
|
|
3
|
+
# would run the devenv setup twice while sandbox blocks access to tooling/.
|
|
4
|
+
case "$PWD" in
|
|
5
|
+
*/.jcode-worktrees/*)
|
|
6
|
+
;;
|
|
7
|
+
*)
|
|
8
|
+
source_up_if_exists
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
watch_file tooling/direnv/envrc.sh
|
|
13
|
+
|
|
14
|
+
cd tooling/direnv
|
|
15
|
+
. envrc.sh
|
|
16
|
+
|
|
17
|
+
# Load local extensions and overrides
|
|
18
|
+
source_env_if_exists .envrc-local
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { mkdir, rmdir } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { $ } from 'bun';
|
|
6
|
+
|
|
7
|
+
const devenvRoot = process.env.DEVENV_ROOT;
|
|
8
|
+
const projectRoot = path.resolve(`${devenvRoot}/../..`);
|
|
9
|
+
const startedWithoutNodeModules = !existsSync(path.join(projectRoot, 'node_modules'));
|
|
10
|
+
|
|
11
|
+
class CapturedCommandError extends Error {
|
|
12
|
+
constructor(
|
|
13
|
+
public readonly command: string,
|
|
14
|
+
public readonly exitCode: number,
|
|
15
|
+
public readonly stdout: Uint8Array,
|
|
16
|
+
public readonly stderr: Uint8Array,
|
|
17
|
+
) {
|
|
18
|
+
super(`${command} failed with exit code ${exitCode}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Go to project root
|
|
23
|
+
process.chdir(projectRoot);
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
// Install dependencies first so node_modules/.bin tools are available
|
|
27
|
+
if (process.env.CI) {
|
|
28
|
+
try {
|
|
29
|
+
await runSetupCommand('bun install --frozen-lockfile', $`bun install --frozen-lockfile`, { quiet: false });
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('! Failed to install dependencies with frozen lockfile');
|
|
32
|
+
replayCapturedOutput(error);
|
|
33
|
+
await runSetupCommand('bun install', $`bun install`, { quiet: false });
|
|
34
|
+
console.error('git diff after install:');
|
|
35
|
+
await runSetupCommand('git diff', $`git diff`, { quiet: false, allowNonzero: true });
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
await installLocalDependencies();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Bun selects its resolver mode at process startup. If this process started
|
|
43
|
+
// before node_modules existed, imports below can stay in auto-install mode
|
|
44
|
+
// even after bun install succeeds, so restart once into the real workspace.
|
|
45
|
+
if (startedWithoutNodeModules) {
|
|
46
|
+
await runSetupCommand('restart setup-environment.ts', $`bun --no-install ${import.meta.path}`, { quiet: false });
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!process.env.CI) {
|
|
51
|
+
const { syncRootRuntimeVersions } = await import('@smoothbricks/cli/monorepo/runtime');
|
|
52
|
+
await syncRootRuntimeVersions(projectRoot);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const { applyWorkspaceGitConfig } = await import('@smoothbricks/cli/monorepo/git-config');
|
|
56
|
+
await applyWorkspaceGitConfig(projectRoot);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (error instanceof CapturedCommandError) {
|
|
59
|
+
console.error(`--- ERROR: setup-environment.ts failed while running: ${error.command}`);
|
|
60
|
+
console.error(`exit code: ${error.exitCode}`);
|
|
61
|
+
} else {
|
|
62
|
+
console.error(`--- ERROR: setup-environment.ts failed: ${error}`);
|
|
63
|
+
}
|
|
64
|
+
replayCapturedOutput(error);
|
|
65
|
+
console.error('\n---');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function installLocalDependencies(): Promise<void> {
|
|
70
|
+
// bun install runs the root prepare script, which patches TypeScript with
|
|
71
|
+
// ts-patch. Multiple concurrent direnv activations can otherwise race while
|
|
72
|
+
// mutating the same files under node_modules.
|
|
73
|
+
await withSetupLock(async () => {
|
|
74
|
+
await runSetupCommand('bun install --no-summary', $`bun install --no-summary`);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function runSetupCommand(
|
|
79
|
+
command: string,
|
|
80
|
+
shell: ReturnType<typeof $>,
|
|
81
|
+
options: { quiet?: boolean; allowNonzero?: boolean } = {},
|
|
82
|
+
): Promise<void> {
|
|
83
|
+
const result = await shell
|
|
84
|
+
.quiet(options.quiet ?? true)
|
|
85
|
+
.nothrow()
|
|
86
|
+
.cwd(projectRoot);
|
|
87
|
+
if (result.exitCode !== 0 && options.allowNonzero !== true) {
|
|
88
|
+
throw new CapturedCommandError(command, result.exitCode, result.stdout, result.stderr);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function withSetupLock<T>(fn: () => Promise<T>): Promise<T> {
|
|
93
|
+
const lockDir = path.join(projectRoot, 'tooling/direnv/.devenv/setup-environment.lock');
|
|
94
|
+
await acquireLock(lockDir);
|
|
95
|
+
try {
|
|
96
|
+
return await fn();
|
|
97
|
+
} finally {
|
|
98
|
+
await rmdir(lockDir).catch(() => undefined);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async function acquireLock(lockDir: string): Promise<void> {
|
|
103
|
+
const deadline = Date.now() + 120_000;
|
|
104
|
+
while (true) {
|
|
105
|
+
try {
|
|
106
|
+
await mkdir(lockDir, { recursive: false });
|
|
107
|
+
return;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (!isFileExistsError(error) || Date.now() > deadline) {
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
await Bun.sleep(100);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function isFileExistsError(error: unknown): boolean {
|
|
118
|
+
return error instanceof Error && 'code' in error && error.code === 'EEXIST';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function replayCapturedOutput(error: unknown): void {
|
|
122
|
+
if (!(error instanceof CapturedCommandError)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (error.stdout.length > 0) {
|
|
126
|
+
process.stdout.write(error.stdout);
|
|
127
|
+
}
|
|
128
|
+
if (error.stderr.length > 0) {
|
|
129
|
+
process.stderr.write(error.stderr);
|
|
130
|
+
}
|
|
131
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smoothbricks/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "SmoothBricks monorepo automation CLI",
|
|
6
6
|
"bin": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
],
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
48
|
-
"@smoothbricks/nx-plugin": "0.2.
|
|
48
|
+
"@smoothbricks/nx-plugin": "0.2.5",
|
|
49
49
|
"@smoothbricks/validation": "0.1.1",
|
|
50
50
|
"commander": "^14.0.3",
|
|
51
51
|
"publint": "^0.3.18",
|
|
@@ -38,6 +38,11 @@ interface DeployTargetInfo {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const managedFiles: ManagedFile[] = [
|
|
41
|
+
{
|
|
42
|
+
kind: 'raw',
|
|
43
|
+
source: 'envrc',
|
|
44
|
+
target: '.envrc',
|
|
45
|
+
},
|
|
41
46
|
{
|
|
42
47
|
kind: 'raw',
|
|
43
48
|
source: 'tooling/direnv/repo-path',
|
|
@@ -50,6 +55,12 @@ const managedFiles: ManagedFile[] = [
|
|
|
50
55
|
target: 'tooling/direnv/github-actions-bootstrap.sh',
|
|
51
56
|
executable: true,
|
|
52
57
|
},
|
|
58
|
+
{
|
|
59
|
+
kind: 'raw',
|
|
60
|
+
source: 'tooling/direnv/setup-environment.ts',
|
|
61
|
+
target: 'tooling/direnv/setup-environment.ts',
|
|
62
|
+
executable: true,
|
|
63
|
+
},
|
|
53
64
|
{
|
|
54
65
|
kind: 'raw',
|
|
55
66
|
source: 'tooling/git-hooks/pre-commit.sh',
|
|
@@ -395,6 +395,8 @@ async function readResolvedTargetsByProject(ctx: MonorepoContext): Promise<Map<s
|
|
|
395
395
|
{
|
|
396
396
|
targets: new Set(project.targets),
|
|
397
397
|
...(project.buildDependsOn ? { buildDependsOn: project.buildDependsOn } : {}),
|
|
398
|
+
...(project.targetExecutors ? { targetExecutors: project.targetExecutors } : {}),
|
|
399
|
+
...(project.targetScripts ? { targetScripts: project.targetScripts } : {}),
|
|
398
400
|
},
|
|
399
401
|
]),
|
|
400
402
|
);
|
package/src/nx/index.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface ProjectTargets {
|
|
|
9
9
|
project: string;
|
|
10
10
|
targets: string[];
|
|
11
11
|
buildDependsOn?: string[];
|
|
12
|
+
targetExecutors?: Map<string, string>;
|
|
13
|
+
targetScripts?: Map<string, string>;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface CommandInvocation {
|
|
@@ -42,6 +44,38 @@ export function buildDependsOnFromNxProjectJson(value: unknown): string[] | unde
|
|
|
42
44
|
return build.dependsOn;
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
export function targetExecutorsFromNxProjectJson(value: unknown): Map<string, string> {
|
|
48
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
49
|
+
const executors = new Map<string, string>();
|
|
50
|
+
if (!targets) {
|
|
51
|
+
return executors;
|
|
52
|
+
}
|
|
53
|
+
for (const [targetName, target] of Object.entries(targets)) {
|
|
54
|
+
if (isRecord(target) && typeof target.executor === 'string') {
|
|
55
|
+
executors.set(targetName, target.executor);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return executors;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function targetScriptsFromNxProjectJson(value: unknown): Map<string, string> {
|
|
62
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
63
|
+
const scripts = new Map<string, string>();
|
|
64
|
+
if (!targets) {
|
|
65
|
+
return scripts;
|
|
66
|
+
}
|
|
67
|
+
for (const [targetName, target] of Object.entries(targets)) {
|
|
68
|
+
if (!isRecord(target)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const options = recordProperty(target, 'options');
|
|
72
|
+
if (typeof options?.script === 'string') {
|
|
73
|
+
scripts.set(targetName, options.script);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return scripts;
|
|
77
|
+
}
|
|
78
|
+
|
|
45
79
|
export function formatProjectTargetLines(projects: ProjectTargets[]): string {
|
|
46
80
|
return projects
|
|
47
81
|
.flatMap((project) => project.targets.map((target) => `${project.project}:${target}`))
|
|
@@ -135,5 +169,7 @@ async function readProjectTarget(root: string, project: string): Promise<Project
|
|
|
135
169
|
project,
|
|
136
170
|
targets: targetNamesFromNxProjectJson(parsed),
|
|
137
171
|
buildDependsOn: buildDependsOnFromNxProjectJson(parsed),
|
|
172
|
+
targetExecutors: targetExecutorsFromNxProjectJson(parsed),
|
|
173
|
+
targetScripts: targetScriptsFromNxProjectJson(parsed),
|
|
138
174
|
};
|
|
139
175
|
}
|