From 862e45eb9987c02cc1b1738890f1b3e9fa9a2b46 Mon Sep 17 00:00:00 2001 From: Duncan Mak Date: Tue, 22 Jul 2025 18:49:10 -0400 Subject: [PATCH 1/5] Add sanitize-filename --- package.json | 5 ++++- yarn.lock | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a8be788f6..506523873 100644 --- a/package.json +++ b/package.json @@ -56,5 +56,8 @@ "prod" ] }, - "packageManager": "yarn@4.9.1" + "packageManager": "yarn@4.9.1", + "dependencies": { + "sanitize-filename": "^1.6.3" + } } diff --git a/yarn.lock b/yarn.lock index 48c906d06..77fa0372d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1822,6 +1822,7 @@ __metadata: lint-staged: "npm:^15.2.10" patch-package: "npm:^6.5.1" prettier: "npm:^2.8.6" + sanitize-filename: "npm:^1.6.3" syncpack: "npm:^9.0.0" ts-node: "npm:^10.9.1" typescript: "npm:~5.0.3" @@ -7610,6 +7611,15 @@ __metadata: languageName: node linkType: hard +"sanitize-filename@npm:^1.6.3": + version: 1.6.3 + resolution: "sanitize-filename@npm:1.6.3" + dependencies: + truncate-utf8-bytes: "npm:^1.0.0" + checksum: 10c0/16ff47556a6e54e228c28db096bedd303da67b030d4bea4925fd71324932d6b02c7b0446f00ad33987b25b6414f24ae968e01a1a1679ce599542e82c4b07eb1f + languageName: node + linkType: hard + "sax@npm:>=0.6.0": version: 1.2.4 resolution: "sax@npm:1.2.4" @@ -8237,6 +8247,15 @@ __metadata: languageName: node linkType: hard +"truncate-utf8-bytes@npm:^1.0.0": + version: 1.0.2 + resolution: "truncate-utf8-bytes@npm:1.0.2" + dependencies: + utf8-byte-length: "npm:^1.0.1" + checksum: 10c0/af2b431fc4314f119b551e5fccfad49d4c0ef82e13ba9ca61be6567801195b08e732ce9643542e8ad1b3df44f3df2d7345b3dd34f723954b6bb43a14584d6b3c + languageName: node + linkType: hard + "ts-node@npm:^10.9.1": version: 10.9.1 resolution: "ts-node@npm:10.9.1" @@ -8475,6 +8494,13 @@ __metadata: languageName: node linkType: hard +"utf8-byte-length@npm:^1.0.1": + version: 1.0.5 + resolution: "utf8-byte-length@npm:1.0.5" + checksum: 10c0/e69bda3299608f4cc75976da9fb74ac94801a58b9ca29fdad03a20ec952e7477d7f226c12716b5f36bd4cff8151d1d152d02ee1df3752f017d4b2c725ce3e47a + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" From 5a9505683570f22e9da37970008af141f94df9af Mon Sep 17 00:00:00 2001 From: Duncan Mak Date: Tue, 22 Jul 2025 18:49:35 -0400 Subject: [PATCH 2/5] Call sanitized before fs.writeFileSync --- packages/hasher/src/TargetHasher.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/hasher/src/TargetHasher.ts b/packages/hasher/src/TargetHasher.ts index cb3f6b7f0..e458d386d 100644 --- a/packages/hasher/src/TargetHasher.ts +++ b/packages/hasher/src/TargetHasher.ts @@ -1,6 +1,7 @@ import type { Target } from "@lage-run/target-graph"; import { hash } from "glob-hasher"; import { globAsync } from "@lage-run/globby"; +import sanitize from "sanitize-filename"; import fs from "fs"; import path from "path"; @@ -230,7 +231,7 @@ export class TargetHasher { writeTargetHashesManifest() { for (const [id, { fileHashes, globalFileHashes }] of Object.entries(this.targetHashesLog)) { - const targetHashesManifestPath = path.join(this.targetHashesDirectory, `${id}.json`); + const targetHashesManifestPath = sanitize(path.join(this.targetHashesDirectory, `${id}.json`)); if (!fs.existsSync(path.dirname(targetHashesManifestPath))) { fs.mkdirSync(path.dirname(targetHashesManifestPath), { recursive: true }); } From efa47f62e5f42d6b9de637aae6a0a2f622bb73d5 Mon Sep 17 00:00:00 2001 From: Duncan Mak Date: Tue, 22 Jul 2025 18:49:47 -0400 Subject: [PATCH 3/5] Add test for sanitize-filename --- packages/hasher/src/__tests__/TargetHasher.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/hasher/src/__tests__/TargetHasher.test.ts b/packages/hasher/src/__tests__/TargetHasher.test.ts index f8411792d..01e0dd090 100644 --- a/packages/hasher/src/__tests__/TargetHasher.test.ts +++ b/packages/hasher/src/__tests__/TargetHasher.test.ts @@ -172,4 +172,15 @@ describe("The main Hasher class", () => { monorepo1.cleanup(); }); + + it("sanitizes target hashes filenames when the target contains special characters", async () => { + const monorepo1 = await setupFixture("monorepo"); + const hasher = new TargetHasher({ root: monorepo1.root, environmentGlob: [] }); + const target = createTarget(monorepo1.root, "package-a", "build:test"); + const hash = await getHash(hasher, target); + + expect(() => hasher.writeTargetHashesManifest()).not.toThrow(); + + monorepo1.cleanup(); + }); }); From 9427e0e7b0bc069354a52349cda5fcf1e2487189 Mon Sep 17 00:00:00 2001 From: Duncan Mak Date: Tue, 22 Jul 2025 18:53:56 -0400 Subject: [PATCH 4/5] move the dependency to the right file --- package.json | 5 +---- packages/hasher/package.json | 1 + yarn.lock | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 506523873..a8be788f6 100644 --- a/package.json +++ b/package.json @@ -56,8 +56,5 @@ "prod" ] }, - "packageManager": "yarn@4.9.1", - "dependencies": { - "sanitize-filename": "^1.6.3" - } + "packageManager": "yarn@4.9.1" } diff --git a/packages/hasher/package.json b/packages/hasher/package.json index 1b931d923..072a39211 100644 --- a/packages/hasher/package.json +++ b/packages/hasher/package.json @@ -22,6 +22,7 @@ "glob-hasher": "^1.4.2", "graceful-fs": "4.2.11", "micromatch": "4.0.8", + "sanitize-filename": "^1.6.3", "workspace-tools": "0.38.3" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 77fa0372d..3e5e7a91c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1804,6 +1804,7 @@ __metadata: glob-hasher: "npm:^1.4.2" graceful-fs: "npm:4.2.11" micromatch: "npm:4.0.8" + sanitize-filename: "npm:^1.6.3" workspace-tools: "npm:0.38.3" languageName: unknown linkType: soft @@ -1822,7 +1823,6 @@ __metadata: lint-staged: "npm:^15.2.10" patch-package: "npm:^6.5.1" prettier: "npm:^2.8.6" - sanitize-filename: "npm:^1.6.3" syncpack: "npm:^9.0.0" ts-node: "npm:^10.9.1" typescript: "npm:~5.0.3" From 1bb59afa284fccc4fd32e0db37ed16520ec66a04 Mon Sep 17 00:00:00 2001 From: Danny van Velzen Date: Thu, 18 Dec 2025 09:48:59 -0800 Subject: [PATCH 5/5] Update packages/hasher/src/TargetHasher.ts Agree with this proposal Co-authored-by: Elizabeth Craig --- packages/hasher/src/TargetHasher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hasher/src/TargetHasher.ts b/packages/hasher/src/TargetHasher.ts index e458d386d..168182feb 100644 --- a/packages/hasher/src/TargetHasher.ts +++ b/packages/hasher/src/TargetHasher.ts @@ -231,7 +231,7 @@ export class TargetHasher { writeTargetHashesManifest() { for (const [id, { fileHashes, globalFileHashes }] of Object.entries(this.targetHashesLog)) { - const targetHashesManifestPath = sanitize(path.join(this.targetHashesDirectory, `${id}.json`)); + const targetHashesManifestPath = path.join(this.targetHashesDirectory, `${sanitize(id)}.json`); if (!fs.existsSync(path.dirname(targetHashesManifestPath))) { fs.mkdirSync(path.dirname(targetHashesManifestPath), { recursive: true }); }