diff --git a/packages/infrastructure/lens-link/src/get-symlink-paths.injectable.ts b/packages/infrastructure/lens-link/src/get-symlink-paths.injectable.ts index 8cc0de4339..bf9ce6209a 100644 --- a/packages/infrastructure/lens-link/src/get-symlink-paths.injectable.ts +++ b/packages/infrastructure/lens-link/src/get-symlink-paths.injectable.ts @@ -1,4 +1,4 @@ -import { flatten, map, partition, uniq, uniqBy } from "lodash/fp"; +import { flatten, map, partition, uniq, uniqBy, filter } from "lodash/fp"; import type { PackageJsonAndPath } from "./package-json-and-path"; import { globInjectable } from "./fs/glob.injectable"; import { resolvePathInjectable } from "./path/resolve-path.injectable"; @@ -8,6 +8,7 @@ import { pipeline } from "@ogre-tools/fp"; import { getLensLinkDirectoryInjectable } from "./get-lens-link-directory.injectable"; import path from "path"; import { isFileOrDirectoryInjectable } from "./fs/is-file-or-directory.injectable"; +import { existsInjectable } from "./fs/exists.injectable"; const shouldBeGlobbed = (possibleGlobString: string) => possibleGlobString.includes("*"); const simplifyGlobbing = new RegExp("(\\/\\*\\/\\*\\*|\\/\\*\\*|\\/\\*\\*\\/\\*|\\/\\*)$"); @@ -21,6 +22,7 @@ export const getSymlinkPathsInjectable = getInjectable({ const resolvePath = di.inject(resolvePathInjectable); const getLensLinkDirectory = di.inject(getLensLinkDirectoryInjectable); const isFileOrDirectory = di.inject(isFileOrDirectoryInjectable); + const exists = di.inject(existsInjectable); return async (packageJsons: PackageJsonAndPath[]) => { return pipeline( @@ -46,7 +48,13 @@ export const getSymlinkPathsInjectable = getInjectable({ uniq, - map(async (fileOrDirectory) => { + map(async (fileOrDirectory) => ({ fileOrDirectory, exists: await exists(fileOrDirectory) })), + + awaitAll, + + filter(({ exists }) => exists), + + map(async ({ fileOrDirectory }) => { const target = resolvePath(moduleDirectory, fileOrDirectory); return { diff --git a/packages/infrastructure/lens-link/src/lens-link.test.ts b/packages/infrastructure/lens-link/src/lens-link.test.ts index 0179dfb236..18bf675cb1 100644 --- a/packages/infrastructure/lens-link/src/lens-link.test.ts +++ b/packages/infrastructure/lens-link/src/lens-link.test.ts @@ -198,6 +198,9 @@ describe("lens-link", () => { await ensureEmptyDirectoryMock.resolve(); await ensureEmptyDirectoryMock.resolve(); + await existsMock.resolve(true); + await existsMock.resolve(true); + await isFileOrDirectoryMock.resolve("dir"); await isFileOrDirectoryMock.resolve("dir"); }); @@ -290,6 +293,11 @@ describe("lens-link", () => { beforeEach(async () => { await globMock.resolve(["some-directory-from-glob/some-file-from-glob.txt", "some-duplicate-file"]); + await existsMock.resolve(true); + await existsMock.resolve(true); + await existsMock.resolve(true); + await existsMock.resolve(true); + await isFileOrDirectoryMock.resolve("file"); await isFileOrDirectoryMock.resolve("dir"); await isFileOrDirectoryMock.resolve("dir"); @@ -351,7 +359,7 @@ describe("lens-link", () => { await readJsonFileMock.resolveSpecific(([path]) => path === "/some-directory/some-module/package.json", { name: "some-module", - files: ["some-build-directory", "some-file"], + files: ["some-build-directory", "some-file", "some-non-existing-file.txt"], main: "some-build-directory/index.js", }); @@ -386,84 +394,106 @@ describe("lens-link", () => { expect(createSymlinkMock).not.toHaveBeenCalled(); }); - it("calls for if symlinks to be created are for files or directories", () => { - expect(isFileOrDirectoryMock.mock.calls).toEqual([ - ["/some-directory/some-module/some-build-directory"], - ["/some-directory/some-module/some-file"], - ["/some-other-directory/some-other-module/some-other-build-directory"], + it("calls to detect if file or directory exists", () => { + expect(existsMock.mock.calls).toEqual([ + ["some-build-directory"], + ["some-file"], + ["some-non-existing-file.txt"], + ["some-other-build-directory"], ]); }); - describe("given calls for files or directories resolve", () => { + it("does not check for files and directories yet", () => { + expect(isFileOrDirectoryMock).not.toHaveBeenCalled(); + }); + + describe("when existence of files and directories resolve with some non existing", () => { beforeEach(async () => { - await isFileOrDirectoryMock.resolveSpecific( - ["/some-directory/some-module/some-build-directory"], - "dir", - ); - - await isFileOrDirectoryMock.resolveSpecific(["/some-directory/some-module/some-file"], "file"); - - await isFileOrDirectoryMock.resolveSpecific( - ["/some-other-directory/some-other-module/some-other-build-directory"], - "dir", - ); + await existsMock.resolve(true); + await existsMock.resolve(true); + await existsMock.resolve(false); + await existsMock.resolve(true); }); - it("creates the symlinks", () => { - expect(createSymlinkMock.mock.calls).toEqual([ - [ - "/some-directory/some-module/package.json", - "/some-directory/some-project/node_modules/some-module/package.json", - "file", - ], - - [ - "/some-directory/some-module/some-build-directory", - "/some-directory/some-project/node_modules/some-module/some-build-directory", - "dir", - ], - - [ - "/some-directory/some-module/some-file", - "/some-directory/some-project/node_modules/some-module/some-file", - "file", - ], - - [ - "/some-other-directory/some-other-module/package.json", - "/some-directory/some-project/node_modules/some-other-module/package.json", - "file", - ], - - [ - "/some-other-directory/some-other-module/some-other-build-directory", - "/some-directory/some-project/node_modules/some-other-module/some-other-build-directory", - "dir", - ], + it("calls for if symlinks to be created are for files or directories", () => { + expect(isFileOrDirectoryMock.mock.calls).toEqual([ + ["/some-directory/some-module/some-build-directory"], + ["/some-directory/some-module/some-file"], + ["/some-other-directory/some-other-module/some-other-build-directory"], ]); }); - it("given all symlink creations have not resolved, does not resolve yet", async () => { - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); + describe("given calls for files or directories resolve", () => { + beforeEach(async () => { + await isFileOrDirectoryMock.resolveSpecific( + ["/some-directory/some-module/some-build-directory"], + "dir", + ); - const promiseStatus = await getPromiseStatus(actualPromise); + await isFileOrDirectoryMock.resolveSpecific(["/some-directory/some-module/some-file"], "file"); - expect(promiseStatus.fulfilled).toBe(false); - }); + await isFileOrDirectoryMock.resolveSpecific( + ["/some-other-directory/some-other-module/some-other-build-directory"], + "dir", + ); + }); - it("when symlink creations resolve, ends script", async () => { - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); - createSymlinkMock.resolve(); + it("creates the symlinks", () => { + expect(createSymlinkMock.mock.calls).toEqual([ + [ + "/some-directory/some-module/package.json", + "/some-directory/some-project/node_modules/some-module/package.json", + "file", + ], - const promiseStatus = await getPromiseStatus(actualPromise); + [ + "/some-directory/some-module/some-build-directory", + "/some-directory/some-project/node_modules/some-module/some-build-directory", + "dir", + ], - expect(promiseStatus.fulfilled).toBe(true); + [ + "/some-directory/some-module/some-file", + "/some-directory/some-project/node_modules/some-module/some-file", + "file", + ], + + [ + "/some-other-directory/some-other-module/package.json", + "/some-directory/some-project/node_modules/some-other-module/package.json", + "file", + ], + + [ + "/some-other-directory/some-other-module/some-other-build-directory", + "/some-directory/some-project/node_modules/some-other-module/some-other-build-directory", + "dir", + ], + ]); + }); + + it("given all symlink creations have not resolved, does not resolve yet", async () => { + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + + const promiseStatus = await getPromiseStatus(actualPromise); + + expect(promiseStatus.fulfilled).toBe(false); + }); + + it("when symlink creations resolve, ends script", async () => { + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + createSymlinkMock.resolve(); + + const promiseStatus = await getPromiseStatus(actualPromise); + + expect(promiseStatus.fulfilled).toBe(true); + }); }); }); });