Navigation Menu

Skip to content

Commit

Permalink
fix(create-symlink): Generate shims for missing bin scripts for Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
evocateur committed Jul 22, 2019
1 parent 03f80b7 commit c3f7998
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
30 changes: 30 additions & 0 deletions utils/create-symlink/__tests__/create-symlink.test.js
Expand Up @@ -15,6 +15,8 @@ describe("create-symlink", () => {
fs.unlink.mockResolvedValue();
fs.symlink.mockResolvedValue();
fs.pathExists.mockResolvedValue(true);
fs.outputFile.mockResolvedValue();
fs.remove.mockResolvedValue();
cmdShim.mockResolvedValue();

if (process.platform !== "win32") {
Expand Down Expand Up @@ -86,5 +88,33 @@ describe("create-symlink", () => {
expect(fs.unlink).toHaveBeenLastCalledWith(dst);
expect(fs.symlink).toHaveBeenLastCalledWith(src, dst, type);
});

it("creates stub symlink to executable that doesn't exist yet", async () => {
const src = path.resolve("./packages/package-3/cli.js");
const dst = path.resolve("./packages/package-1/node_modules/.bin/package-3");
const type = "exec";

fs.pathExists.mockResolvedValueOnce(false);

await createSymlink(src, dst, type);

expect(fs.outputFile).toHaveBeenLastCalledWith(src, "");
expect(cmdShim).toHaveBeenLastCalledWith(src, dst);
expect(fs.remove).toHaveBeenLastCalledWith(src);
});

it("does not swallow cmd-shim errors when executable doesn't exist yet", async () => {
cmdShim.mockImplementationOnce(() => Promise.reject(new Error("oh no")));
fs.pathExists.mockResolvedValueOnce(false);

try {
await createSymlink("src", "dst", "exec");
} catch (err) {
expect(err.message).toBe("oh no");
expect(fs.remove).toHaveBeenLastCalledWith("src");
}

expect.hasAssertions();
});
}
});
21 changes: 20 additions & 1 deletion utils/create-symlink/create-symlink.js
Expand Up @@ -50,7 +50,26 @@ function createPosixSymlink(src, dest, _type) {

function createWindowsSymlink(src, dest, type) {
if (type === "exec") {
return cmdShim(src, dest);
// If the src exists, shim directly.
// If the src doesn't exist yet, create a temp src so cmd-shim doesn't explode.
return fs.pathExists(src).then(exists => {
if (exists) {
return cmdShim(src, dest);
}

return fs
.outputFile(src, "")
.then(() => cmdShim(src, dest))
.then(
// fs.remove() never rejects
() => fs.remove(src),
err =>
fs.remove(src).then(() => {
// clean up, but don't swallow error
throw err;
})
);
});
}

return createSymbolicLink(src, dest, type);
Expand Down

0 comments on commit c3f7998

Please sign in to comment.