Skip to content

Commit 08b45ad

Browse files
authored
refactor(cli): resolve package.json files directly (#312)
1 parent 18a484e commit 08b45ad

File tree

1 file changed

+60
-24
lines changed

1 file changed

+60
-24
lines changed

packages/cli/index.ts

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import ignore from "ignore";
1818
import "./environments";
1919
import pkg from "./package.json" with { type: "json" };
2020
import { isBinaryFile } from "isbinaryfile";
21-
import { readPackageJSON, writePackageJSON } from "pkg-types";
21+
import { writePackageJSON, type PackageJson } from "pkg-types";
2222
import { createDefaultTemplate } from "./template";
2323

2424
declare global {
@@ -183,11 +183,12 @@ const main = defineCommand({
183183
};
184184

185185
for (const p of paths) {
186-
if (!(await hasPackageJson(p))) {
186+
const pJsonPath = path.resolve(p, "package.json");
187+
const pJson = await readPackageJson(pJsonPath);
188+
189+
if (!pJson) {
187190
continue;
188191
}
189-
const pJsonPath = path.resolve(p, "package.json");
190-
const pJson = await readPackageJSON(pJsonPath);
191192

192193
if (!pJson.name) {
193194
throw new Error(`"name" field in ${pJsonPath} should be defined`);
@@ -223,22 +224,32 @@ const main = defineCommand({
223224
}
224225

225226
for (const templateDir of templates) {
226-
if (!(await hasPackageJson(templateDir))) {
227+
const pJsonPath = path.resolve(templateDir, "package.json");
228+
const pJsonContents = await tryReadFile(pJsonPath);
229+
const pJson = pJsonContents
230+
? parsePackageJson(pJsonContents)
231+
: null;
232+
233+
if (!pJson || !pJsonContents) {
227234
console.warn(
228235
`skipping ${templateDir} because there's no package.json file`,
229236
);
230237
continue;
231238
}
232-
const pJsonPath = path.resolve(templateDir, "package.json");
233-
const pJson = await readPackageJSON(pJsonPath);
234239

235240
if (!pJson.name) {
236241
throw new Error(`"name" field in ${pJsonPath} should be defined`);
237242
}
238243

239244
console.warn("preparing template:", pJson.name);
240245

241-
const restore = await writeDeps(templateDir, deps, realDeps);
246+
const restore = await writeDeps(
247+
templateDir,
248+
pJsonContents,
249+
pJson,
250+
deps,
251+
realDeps,
252+
);
242253

243254
const gitignorePath = path.join(templateDir, ".gitignore");
244255
const ig = ignore().add("node_modules").add(".git");
@@ -301,31 +312,38 @@ const main = defineCommand({
301312
Awaited<ReturnType<typeof writeDeps>>
302313
>();
303314
for (const p of paths) {
304-
if (!(await hasPackageJson(p))) {
315+
const pJsonPath = path.resolve(p, "package.json");
316+
const pJsonContents = await tryReadFile(pJsonPath);
317+
const pJson = pJsonContents
318+
? parsePackageJson(pJsonContents)
319+
: null;
320+
321+
if (!pJson || !pJsonContents) {
305322
continue;
306323
}
307-
const pJsonPath = path.resolve(p, "package.json");
308-
const pJson = await readPackageJSON(pJsonPath);
309324

310325
if (pJson.private) {
311326
continue;
312327
}
313328

314-
restoreMap.set(p, await writeDeps(p, deps, realDeps));
329+
restoreMap.set(
330+
p,
331+
await writeDeps(p, pJsonContents, pJson, deps, realDeps),
332+
);
315333
}
316334

317335
const shasums: Record<string, string> = {};
318336
for (const p of paths) {
319-
if (!(await hasPackageJson(p))) {
337+
const pJsonPath = path.resolve(p, "package.json");
338+
const pJson = await readPackageJson(pJsonPath);
339+
if (!pJson) {
320340
console.warn(
321341
`skipping ${p} because there's no package.json file`,
322342
);
323343
continue;
324344
}
325-
const pJsonPath = path.resolve(p, "package.json");
326-
try {
327-
const pJson = await readPackageJSON(pJsonPath);
328345

346+
try {
329347
if (!pJson.name) {
330348
throw new Error(
331349
`"name" field in ${pJsonPath} should be defined`,
@@ -526,13 +544,12 @@ async function resolveTarball(pm: "npm" | "pnpm", p: string) {
526544

527545
async function writeDeps(
528546
p: string,
547+
pJsonContents: string,
548+
pJson: PackageJson,
529549
deps: Map<string, string>,
530550
realDeps: Map<string, string> | null,
531551
) {
532552
const pJsonPath = path.resolve(p, "package.json");
533-
const content = await fs.readFile(pJsonPath, "utf-8");
534-
535-
const pJson = await readPackageJSON(pJsonPath);
536553

537554
hijackDeps(deps, pJson.dependencies);
538555
hijackDeps(deps, pJson.devDependencies);
@@ -544,7 +561,7 @@ async function writeDeps(
544561

545562
await writePackageJSON(pJsonPath, pJson);
546563

547-
return () => fs.writeFile(pJsonPath, content);
564+
return () => fs.writeFile(pJsonPath, pJsonContents);
548565
}
549566

550567
function hijackDeps(
@@ -600,11 +617,30 @@ ${instruction}`,
600617
}
601618
}
602619

603-
async function hasPackageJson(p: string) {
620+
async function tryReadFile(p: string) {
621+
try {
622+
return await fs.readFile(p, "utf8");
623+
} catch {
624+
return null;
625+
}
626+
}
627+
628+
async function readPackageJson(p: string) {
629+
const contents = await tryReadFile(p);
630+
if (contents === null) {
631+
return null;
632+
}
633+
try {
634+
return parsePackageJson(contents);
635+
} catch {
636+
return null;
637+
}
638+
}
639+
640+
function parsePackageJson(contents: string) {
604641
try {
605-
await fs.access(path.resolve(p, "package.json"), fs.constants.F_OK);
606-
return true;
642+
return JSON.parse(contents) as PackageJson;
607643
} catch {
608-
return false;
644+
return null;
609645
}
610646
}

0 commit comments

Comments
 (0)