Skip to content

Commit 771ecb2

Browse files
authored
fix: add bin wrapper and resolve Nx project discovery (#1270)
1 parent 9a288ee commit 771ecb2

File tree

8 files changed

+43
-13
lines changed

8 files changed

+43
-13
lines changed

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export default tseslint.config(
166166
},
167167
{
168168
// in bin files, imports with side effects are allowed
169-
files: ['**/bin/**/*.ts', '**/bin/**/*.js'],
169+
files: ['**/bin/**/*.ts', '**/bin/**/*.js', '**/bin.js'],
170170
rules: {
171171
'import/no-unassigned-import': 'off',
172172
},

nx.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
"outputPath": "{projectRoot}/dist",
7676
"main": "{projectRoot}/src/index.ts",
7777
"tsConfig": "{projectRoot}/tsconfig.lib.json",
78-
"assets": ["{projectRoot}/*.md"]
78+
"assets": ["{projectRoot}/*.md", "{projectRoot}/bin.js"]
7979
}
8080
},
8181
"unit-test": {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
* By tracking this file in git with executable permissions (+x), we ensure
99
* the CLI remains executable after npm publish without needing post-install scripts.
1010
*/
11-
import '../src/index.js';
11+
import './src/index.js';

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
},
4040
"type": "module",
4141
"bin": {
42-
"code-pushup": "./bin/index.js"
42+
"code-pushup": "./bin.js"
4343
},
4444
"engines": {
4545
"node": ">=20"

packages/cli/project.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
"sourceRoot": "packages/cli/src",
55
"projectType": "library",
66
"targets": {
7-
"build": {
8-
"options": {
9-
"assets": ["{projectRoot}/*.md", "{projectRoot}/bin/*"]
10-
}
11-
},
7+
"build": {},
128
"lint": {},
139
"unit-test": {},
1410
"int-test": {},

packages/create-cli/bin.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* This file serves as the CLI entry point.
5+
*
6+
* We use a separate bin file (instead of pointing directly to src/index.js)
7+
* because TypeScript build processes don't preserve file permissions.
8+
* By tracking this file in git with executable permissions (+x), we ensure
9+
* the CLI remains executable after npm publish without needing post-install scripts.
10+
*/
11+
import './src/index.js';

packages/create-cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@code-pushup/create-cli",
33
"version": "0.119.0",
44
"license": "MIT",
5-
"bin": "index.js",
5+
"bin": "./bin.js",
66
"homepage": "https://github.com/code-pushup/cli/tree/main/packages/create-cli#readme",
77
"bugs": {
88
"url": "https://github.com/code-pushup/cli/issues?q=is%3Aissue%20state%3Aopen%20type%3ABug%20label%3A\"🧩%20create-cli\""

packages/create-cli/src/lib/setup/monorepo.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { select } from '@inquirer/prompts';
2+
import { createRequire } from 'node:module';
23
import path from 'node:path';
34
import {
45
MONOREPO_TOOL_DETECTORS,
@@ -8,9 +9,9 @@ import {
89
hasScript,
910
listPackages,
1011
listWorkspaces,
11-
loadNxProjectGraph,
1212
logger,
1313
readPnpmWorkspacePatterns,
14+
stringifyError,
1415
toUnixPath,
1516
} from '@code-pushup/utils';
1617
import type {
@@ -83,7 +84,15 @@ export async function listProjects(
8384
}
8485

8586
async function listNxProjects(cwd: string): Promise<WizardProject[]> {
86-
const graph = await loadNxProjectGraph();
87+
const require = createRequire(path.join(cwd, 'package.json'));
88+
const { readCachedProjectGraph, createProjectGraphAsync } =
89+
require('@nx/devkit') as typeof import('@nx/devkit');
90+
91+
const graph = await loadProjectGraph(
92+
readCachedProjectGraph,
93+
createProjectGraphAsync,
94+
);
95+
8796
return Object.values(graph.nodes).map(({ name, data }) => ({
8897
name,
8998
directory: path.join(cwd, data.root),
@@ -133,7 +142,7 @@ async function addNxTarget(
133142
return false;
134143
}
135144
const config = JSON.parse(raw);
136-
if (config.targets[TASK_NAME] != null) {
145+
if (config.targets?.[TASK_NAME] != null) {
137146
return true;
138147
}
139148
const updated = {
@@ -180,3 +189,17 @@ function toProject(cwd: string, pkg: WorkspacePackage): WizardProject {
180189
relativeDir: toUnixPath(path.relative(cwd, pkg.directory)),
181190
};
182191
}
192+
193+
async function loadProjectGraph(
194+
readCached: typeof import('@nx/devkit').readCachedProjectGraph,
195+
createAsync: typeof import('@nx/devkit').createProjectGraphAsync,
196+
) {
197+
try {
198+
return readCached();
199+
} catch (error) {
200+
logger.warn(
201+
`Could not read cached project graph, falling back to async creation.\n${stringifyError(error)}`,
202+
);
203+
return createAsync({ exitOnError: false });
204+
}
205+
}

0 commit comments

Comments
 (0)