Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/wrong-cwd-build-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"playground-cli": patch
---

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.
39 changes: 39 additions & 0 deletions src/utils/build/detect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,45 @@ describe("detectBuildConfig", () => {
),
).toThrow(BuildDetectError);
});

it("throws a wrong-directory error when package.json is missing entirely", () => {
// A missing package.json almost always means the user is one level
// above their project (e.g. ran `dot mod` then `dot build` from the
// parent). Point them at the cwd, not at editing a package.json that
// isn't there.
expect(() => detectBuildConfig(input({ packageJson: null }))).toThrow(BuildDetectError);
expect(() => detectBuildConfig(input({ packageJson: null }))).toThrow(
/No package\.json found/,
);
});

it("names the project directory in the missing-package.json error", () => {
expect(() =>
detectBuildConfig(input({ packageJson: null, projectDir: "/home/me" })),
).toThrow(/\/home\/me/);
});

it("renders the missing-package.json error cleanly when no projectDir is known", () => {
// The dir name is optional, so the fallback must not leak `undefined`
// or a dangling space before the sentence-ending period.
let message = "";
try {
detectBuildConfig(input({ packageJson: null }));
} catch (err) {
message = (err as Error).message;
}
expect(message).toContain("No package.json found.");
expect(message).not.toMatch(/undefined/);
expect(message).not.toMatch(/ {2}/);
});

it("keeps the generic build-strategy error when package.json exists but is unrecognised", () => {
// package.json IS present — the user is in the right place, we just
// can't infer a build. Keep the original guidance.
expect(() => detectBuildConfig(input({ packageJson: { scripts: {} } }))).toThrow(
/No build strategy detected/,
);
});
});

describe("detectInstallConfig", () => {
Expand Down
19 changes: 19 additions & 0 deletions src/utils/build/detect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export interface DetectInput {
lockfiles: Set<string>;
/** Set of additional config-file basenames (e.g. vite.config.ts). */
configFiles: Set<string>;
/**
* Absolute project root the snapshot was taken from, used only to name the
* directory in the missing-package.json error. Optional so unit tests can
* build inputs without a real path.
*/
projectDir?: string;
}

export class BuildDetectError extends Error {
Expand Down Expand Up @@ -197,6 +203,19 @@ export function detectBuildConfig(input: DetectInput): BuildConfig {
}
}

// No package.json at all almost always means the user is a level above
// their project (e.g. ran `dot mod`, then `dot build` from the parent dir).
// Point them at the directory rather than at editing a package.json that
// isn't there — the generic "add a build script" message sends them to the
// wrong fix.
if (!input.packageJson) {
const where = input.projectDir ? ` in ${input.projectDir}` : "";
throw new BuildDetectError(
`No package.json found${where}. Are you in your project directory? ` +
"cd into it first, or point the command at it with --dir <path>.",
);
}

throw new BuildDetectError(
'No build strategy detected. Add a "build" script to package.json, or install vite/next/typescript.',
);
Expand Down
1 change: 1 addition & 0 deletions src/utils/build/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export function loadDetectInput(projectDir: string): DetectInput {
packageJson,
lockfiles,
configFiles,
projectDir: root,
};
}

Expand Down
Loading