Skip to content

Commit c3f7998

Browse files
committed
fix(create-symlink): Generate shims for missing bin scripts for Windows
1 parent 03f80b7 commit c3f7998

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

utils/create-symlink/__tests__/create-symlink.test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ describe("create-symlink", () => {
1515
fs.unlink.mockResolvedValue();
1616
fs.symlink.mockResolvedValue();
1717
fs.pathExists.mockResolvedValue(true);
18+
fs.outputFile.mockResolvedValue();
19+
fs.remove.mockResolvedValue();
1820
cmdShim.mockResolvedValue();
1921

2022
if (process.platform !== "win32") {
@@ -86,5 +88,33 @@ describe("create-symlink", () => {
8688
expect(fs.unlink).toHaveBeenLastCalledWith(dst);
8789
expect(fs.symlink).toHaveBeenLastCalledWith(src, dst, type);
8890
});
91+
92+
it("creates stub symlink to executable that doesn't exist yet", async () => {
93+
const src = path.resolve("./packages/package-3/cli.js");
94+
const dst = path.resolve("./packages/package-1/node_modules/.bin/package-3");
95+
const type = "exec";
96+
97+
fs.pathExists.mockResolvedValueOnce(false);
98+
99+
await createSymlink(src, dst, type);
100+
101+
expect(fs.outputFile).toHaveBeenLastCalledWith(src, "");
102+
expect(cmdShim).toHaveBeenLastCalledWith(src, dst);
103+
expect(fs.remove).toHaveBeenLastCalledWith(src);
104+
});
105+
106+
it("does not swallow cmd-shim errors when executable doesn't exist yet", async () => {
107+
cmdShim.mockImplementationOnce(() => Promise.reject(new Error("oh no")));
108+
fs.pathExists.mockResolvedValueOnce(false);
109+
110+
try {
111+
await createSymlink("src", "dst", "exec");
112+
} catch (err) {
113+
expect(err.message).toBe("oh no");
114+
expect(fs.remove).toHaveBeenLastCalledWith("src");
115+
}
116+
117+
expect.hasAssertions();
118+
});
89119
}
90120
});

utils/create-symlink/create-symlink.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,26 @@ function createPosixSymlink(src, dest, _type) {
5050

5151
function createWindowsSymlink(src, dest, type) {
5252
if (type === "exec") {
53-
return cmdShim(src, dest);
53+
// If the src exists, shim directly.
54+
// If the src doesn't exist yet, create a temp src so cmd-shim doesn't explode.
55+
return fs.pathExists(src).then(exists => {
56+
if (exists) {
57+
return cmdShim(src, dest);
58+
}
59+
60+
return fs
61+
.outputFile(src, "")
62+
.then(() => cmdShim(src, dest))
63+
.then(
64+
// fs.remove() never rejects
65+
() => fs.remove(src),
66+
err =>
67+
fs.remove(src).then(() => {
68+
// clean up, but don't swallow error
69+
throw err;
70+
})
71+
);
72+
});
5473
}
5574

5675
return createSymbolicLink(src, dest, type);

0 commit comments

Comments
 (0)