Skip to content

Commit 43ec49b

Browse files
fix: do not consider ancestor files when initializing a project with a specified name
When initializing a new project (via `wrangler init`) we attempt to reuse files in the current directory, or in an ancestor directory. In particular we look up the directory tree for package.json and tsconfig.json and use those instead of creating new ones. Now we only do this if you do not specify a name for the new Worker. If you do specify a name, we now only consider files in the directory where the Worker will be initialized. Fixes #859
1 parent c4d71cc commit 43ec49b

File tree

3 files changed

+157
-23
lines changed

3 files changed

+157
-23
lines changed

.changeset/quiet-pigs-care.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
fix: do not consider ancestor files when initializing a project with a specified name
6+
7+
When initializing a new project (via `wrangler init`) we attempt to reuse files in the current
8+
directory, or in an ancestor directory. In particular we look up the directory tree for
9+
package.json and tsconfig.json and use those instead of creating new ones.
10+
11+
Now we only do this if you do not specify a name for the new Worker. If you do specify a name,
12+
we now only consider files in the directory where the Worker will be initialized.
13+
14+
Fixes #859

packages/wrangler/src/__tests__/init.test.ts

+110-17
Original file line numberDiff line numberDiff line change
@@ -757,14 +757,18 @@ describe("init", () => {
757757
`);
758758
});
759759

760-
it("should not touch an existing package.json in a target directory", async () => {
760+
it("should not touch an existing package.json in an ancestor directory, when a name is passed", async () => {
761761
mockConfirm(
762762
{
763763
text: "Would you like to use git to manage this Worker?",
764764
result: false,
765765
},
766766
{
767-
text: "Would you like to install wrangler into path/to/worker/package.json?",
767+
text: "No package.json found. Would you like to create one?",
768+
result: true,
769+
},
770+
{
771+
text: "Would you like to install wrangler into path/to/worker/my-worker/package.json?",
768772
result: false,
769773
},
770774
{
@@ -797,7 +801,8 @@ describe("init", () => {
797801
Object {
798802
"debug": "",
799803
"err": "",
800-
"out": "✨ Created path/to/worker/my-worker/wrangler.toml",
804+
"out": "✨ Created path/to/worker/my-worker/wrangler.toml
805+
✨ Created path/to/worker/my-worker/package.json",
801806
"warn": "",
802807
}
803808
`);
@@ -853,14 +858,14 @@ describe("init", () => {
853858
`);
854859
});
855860

856-
it("should offer to install wrangler into a package.json relative to the target directory", async () => {
861+
it("should offer to install wrangler into a package.json relative to the target directory, if no name is provided", async () => {
857862
mockConfirm(
858863
{
859864
text: "Would you like to use git to manage this Worker?",
860865
result: false,
861866
},
862867
{
863-
text: "Would you like to install wrangler into path/to/worker/package.json?",
868+
text: "Would you like to install wrangler into ../package.json?",
864869
result: true,
865870
},
866871
{
@@ -869,7 +874,7 @@ describe("init", () => {
869874
}
870875
);
871876
mockSelect({
872-
text: "Would you like to create a Worker at path/to/worker/my-worker/src/index.js?",
877+
text: "Would you like to create a Worker at src/index.js?",
873878
result: "none",
874879
});
875880
writeFiles({
@@ -879,9 +884,11 @@ describe("init", () => {
879884
},
880885
},
881886
});
887+
setWorkingDirectory("path/to/worker/my-worker");
882888

883-
await runWrangler("init path/to/worker/my-worker");
889+
await runWrangler("init");
884890

891+
setWorkingDirectory("../../../..");
885892
checkFiles({
886893
items: {
887894
"path/to/worker/package.json": {
@@ -898,7 +905,7 @@ describe("init", () => {
898905
Object {
899906
"debug": "",
900907
"err": "",
901-
"out": "✨ Created path/to/worker/my-worker/wrangler.toml
908+
"out": "✨ Created wrangler.toml
902909
✨ Installed wrangler into devDependencies",
903910
"warn": "",
904911
}
@@ -1221,6 +1228,10 @@ describe("init", () => {
12211228
text: "Would you like to use git to manage this Worker?",
12221229
result: false,
12231230
},
1231+
{
1232+
text: "No package.json found. Would you like to create one?",
1233+
result: true,
1234+
},
12241235
{
12251236
text: "Would you like to install wrangler into package.json?",
12261237
result: false,
@@ -1251,6 +1262,7 @@ describe("init", () => {
12511262
"debug": "",
12521263
"err": "",
12531264
"out": "✨ Created my-worker/wrangler.toml
1265+
✨ Created my-worker/package.json
12541266
✨ Created my-worker/tsconfig.json
12551267
✨ Installed @cloudflare/workers-types and typescript into devDependencies",
12561268
"warn": "",
@@ -1359,11 +1371,21 @@ describe("init", () => {
13591371
`);
13601372
});
13611373

1362-
it("should not touch an existing tsconfig.json in the ancestor of a target directory", async () => {
1363-
mockConfirm({
1364-
text: "Would you like to use git to manage this Worker?",
1365-
result: false,
1366-
});
1374+
it("should not touch an existing tsconfig.json in the ancestor of a target directory, if a name is passed", async () => {
1375+
mockConfirm(
1376+
{
1377+
text: "Would you like to use git to manage this Worker?",
1378+
result: false,
1379+
},
1380+
{
1381+
text: "No package.json found. Would you like to create one?",
1382+
result: true,
1383+
},
1384+
{
1385+
text: "Would you like to use TypeScript?",
1386+
result: true,
1387+
}
1388+
);
13671389
mockSelect({
13681390
text: "Would you like to create a Worker at path/to/worker/my-worker/src/index.ts?",
13691391
result: "fetch",
@@ -1398,10 +1420,13 @@ describe("init", () => {
13981420
"debug": "",
13991421
"err": "",
14001422
"out": "✨ Created path/to/worker/my-worker/wrangler.toml
1423+
✨ Created path/to/worker/my-worker/package.json
1424+
✨ Created path/to/worker/my-worker/tsconfig.json
14011425
✨ Created path/to/worker/my-worker/src/index.ts
1426+
✨ Installed @cloudflare/workers-types and typescript into devDependencies
14021427
1403-
To start developing your Worker, run \`npx wrangler dev\`
1404-
To publish your Worker to the Internet, run \`npx wrangler publish\`",
1428+
To start developing your Worker, run \`cd path/to/worker/my-worker && npm start\`
1429+
To publish your Worker to the Internet, run \`npm run deploy\`",
14051430
"warn": "",
14061431
}
14071432
`);
@@ -1670,7 +1695,7 @@ describe("init", () => {
16701695
result: false,
16711696
},
16721697
{
1673-
text: "Would you like to install wrangler into package.json?",
1698+
text: "Would you like to install wrangler into my-worker/package.json?",
16741699
result: false,
16751700
},
16761701
{
@@ -1681,7 +1706,9 @@ describe("init", () => {
16811706
const PLACEHOLDER = "/* placeholder text */";
16821707
writeFiles({
16831708
items: {
1684-
"package.json": { contents: { name: "test", version: "1.0.0" } },
1709+
"my-worker/package.json": {
1710+
contents: { name: "test", version: "1.0.0" },
1711+
},
16851712
"my-worker/src/index.js": { contents: PLACEHOLDER },
16861713
},
16871714
});
@@ -1806,6 +1833,72 @@ describe("init", () => {
18061833
}
18071834
`);
18081835
});
1836+
1837+
it("should ignore ancestor files (such as wrangler.toml, package.json and tsconfig.json) if a name/path is given", async () => {
1838+
mockConfirm(
1839+
{
1840+
text: "Would you like to use git to manage this Worker?",
1841+
result: false,
1842+
},
1843+
{
1844+
text: "Would you like to use TypeScript?",
1845+
result: true,
1846+
},
1847+
{
1848+
text: "No package.json found. Would you like to create one?",
1849+
result: true,
1850+
},
1851+
{
1852+
text: "Would you like to install the type definitions for Workers into your package.json?",
1853+
result: true,
1854+
}
1855+
);
1856+
mockSelect({
1857+
text: "Would you like to create a Worker at sub/folder/worker/src/index.ts?",
1858+
result: "fetch",
1859+
});
1860+
writeFiles({
1861+
items: {
1862+
"package.json": { contents: { name: "top-level" } },
1863+
"tsconfig.json": { contents: { compilerOptions: {} } },
1864+
"wrangler.toml": wranglerToml({
1865+
name: "top-level",
1866+
compatibility_date: "some-date",
1867+
}),
1868+
},
1869+
});
1870+
1871+
await runWrangler("init sub/folder/worker");
1872+
1873+
// Ancestor files are untouched.
1874+
checkFiles({
1875+
items: {
1876+
"package.json": { contents: { name: "top-level" } },
1877+
"tsconfig.json": {
1878+
contents: { config: { compilerOptions: {} }, error: undefined },
1879+
},
1880+
"wrangler.toml": wranglerToml({
1881+
name: "top-level",
1882+
compatibility_date: "some-date",
1883+
}),
1884+
},
1885+
});
1886+
// New initialized Worker has its own files.
1887+
checkFiles({
1888+
items: {
1889+
"sub/folder/worker/package.json": {
1890+
contents: expect.objectContaining({
1891+
name: "worker",
1892+
}),
1893+
},
1894+
"sub/folder/worker/tsconfig.json": true,
1895+
"sub/folder/worker/wrangler.toml": wranglerToml({
1896+
...MINIMAL_WRANGLER_TOML,
1897+
name: "worker",
1898+
}),
1899+
},
1900+
});
1901+
});
18091902
});
18101903
});
18111904

packages/wrangler/src/index.tsx

+33-6
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,12 @@ function createCLIParser(argv: string[]) {
468468
}
469469
}
470470

471-
let pathToPackageJson = await findUp("package.json", {
472-
cwd: creationDirectory,
473-
});
471+
const isolatedInit = !!args.name;
472+
let pathToPackageJson = await findPath(
473+
isolatedInit,
474+
creationDirectory,
475+
"package.json"
476+
);
474477
let shouldCreatePackageJson = false;
475478

476479
if (!pathToPackageJson) {
@@ -534,9 +537,11 @@ function createCLIParser(argv: string[]) {
534537
}
535538

536539
let isTypescriptProject = false;
537-
let pathToTSConfig = await findUp("tsconfig.json", {
538-
cwd: creationDirectory,
539-
});
540+
let pathToTSConfig = await findPath(
541+
isolatedInit,
542+
creationDirectory,
543+
"tsconfig.json"
544+
);
540545
if (!pathToTSConfig) {
541546
// If there's no tsconfig, offer to create one
542547
// and install @cloudflare/workers-types
@@ -2857,3 +2862,25 @@ function memoizeGetPort(defaultPort: number) {
28572862
return portValue || (portValue = await getPort({ port: defaultPort }));
28582863
};
28592864
}
2865+
2866+
/**
2867+
* Find the path to the given `basename` file from the `cwd`.
2868+
*
2869+
* If `isolatedInit` is true then we only look in the `cwd` directory for the file.
2870+
* Otherwise we also search up the tree.
2871+
*/
2872+
async function findPath(
2873+
isolatedInit: boolean,
2874+
cwd: string,
2875+
basename: string
2876+
): Promise<string | undefined> {
2877+
if (isolatedInit) {
2878+
return fs.existsSync(path.resolve(cwd, basename))
2879+
? path.resolve(cwd, basename)
2880+
: undefined;
2881+
} else {
2882+
return await findUp(basename, {
2883+
cwd: cwd,
2884+
});
2885+
}
2886+
}

0 commit comments

Comments
 (0)