Skip to content

Commit ed098be

Browse files
fix(build): distinguish wrong cwd from missing build strategy
detectBuildConfig threw the same 'No build strategy detected' message whether the cwd had no package.json at all or had one with no recognised build. The first case (user one dir above their project, e.g. after `dot mod`) is the common failure and the message sent them to the wrong fix. Split it: when package.json is absent, name the directory and point the user at it (cd in, or --dir <path>); keep the original message for a present-but-unrecognised package.json. Thread an optional projectDir through DetectInput (populated by loadDetectInput) so the error can name the directory while detect.ts stays pure.
1 parent 550091f commit ed098be

4 files changed

Lines changed: 64 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"playground-cli": patch
3+
---
4+
5+
Distinguish a wrong working directory from a genuinely unrecognised project in `dot build` / `dot deploy`. When no `package.json` is found, the error now points at the current directory ("Are you in your project directory? cd into it first, or point the command at it with --dir <path>.") instead of the misleading "No build strategy detected" message that suggested editing a package.json that isn't there.

src/utils/build/detect.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,45 @@ describe("detectBuildConfig", () => {
141141
),
142142
).toThrow(BuildDetectError);
143143
});
144+
145+
it("throws a wrong-directory error when package.json is missing entirely", () => {
146+
// A missing package.json almost always means the user is one level
147+
// above their project (e.g. ran `dot mod` then `dot build` from the
148+
// parent). Point them at the cwd, not at editing a package.json that
149+
// isn't there.
150+
expect(() => detectBuildConfig(input({ packageJson: null }))).toThrow(BuildDetectError);
151+
expect(() => detectBuildConfig(input({ packageJson: null }))).toThrow(
152+
/No package\.json found/,
153+
);
154+
});
155+
156+
it("names the project directory in the missing-package.json error", () => {
157+
expect(() =>
158+
detectBuildConfig(input({ packageJson: null, projectDir: "/home/me" })),
159+
).toThrow(/\/home\/me/);
160+
});
161+
162+
it("renders the missing-package.json error cleanly when no projectDir is known", () => {
163+
// The dir name is optional, so the fallback must not leak `undefined`
164+
// or a dangling space before the sentence-ending period.
165+
let message = "";
166+
try {
167+
detectBuildConfig(input({ packageJson: null }));
168+
} catch (err) {
169+
message = (err as Error).message;
170+
}
171+
expect(message).toContain("No package.json found.");
172+
expect(message).not.toMatch(/undefined/);
173+
expect(message).not.toMatch(/ {2}/);
174+
});
175+
176+
it("keeps the generic build-strategy error when package.json exists but is unrecognised", () => {
177+
// package.json IS present — the user is in the right place, we just
178+
// can't infer a build. Keep the original guidance.
179+
expect(() => detectBuildConfig(input({ packageJson: { scripts: {} } }))).toThrow(
180+
/No build strategy detected/,
181+
);
182+
});
144183
});
145184

146185
describe("detectInstallConfig", () => {

src/utils/build/detect.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ export interface DetectInput {
6161
lockfiles: Set<string>;
6262
/** Set of additional config-file basenames (e.g. vite.config.ts). */
6363
configFiles: Set<string>;
64+
/**
65+
* Absolute project root the snapshot was taken from, used only to name the
66+
* directory in the missing-package.json error. Optional so unit tests can
67+
* build inputs without a real path.
68+
*/
69+
projectDir?: string;
6470
}
6571

6672
export class BuildDetectError extends Error {
@@ -197,6 +203,19 @@ export function detectBuildConfig(input: DetectInput): BuildConfig {
197203
}
198204
}
199205

206+
// No package.json at all almost always means the user is a level above
207+
// their project (e.g. ran `dot mod`, then `dot build` from the parent dir).
208+
// Point them at the directory rather than at editing a package.json that
209+
// isn't there — the generic "add a build script" message sends them to the
210+
// wrong fix.
211+
if (!input.packageJson) {
212+
const where = input.projectDir ? ` in ${input.projectDir}` : "";
213+
throw new BuildDetectError(
214+
`No package.json found${where}. Are you in your project directory? ` +
215+
"cd into it first, or point the command at it with --dir <path>.",
216+
);
217+
}
218+
200219
throw new BuildDetectError(
201220
'No build strategy detected. Add a "build" script to package.json, or install vite/next/typescript.',
202221
);

src/utils/build/runner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export function loadDetectInput(projectDir: string): DetectInput {
6868
packageJson,
6969
lockfiles,
7070
configFiles,
71+
projectDir: root,
7172
};
7273
}
7374

0 commit comments

Comments
 (0)