From 30be23fec3a99d76f9c61be6875adabf98a926b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 22 Nov 2024 17:48:23 +0100 Subject: [PATCH] =?UTF-8?q?add=20lastModified=20to=20a=20module=E2=80=99s?= =?UTF-8?q?=20hash=20when=20it=20references=20a=20file=20attachment=20(#18?= =?UTF-8?q?37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * when a module references a file attachment, include the file's lastModified timestamp in the module's hash. closes #1836 Note that this allows us to remove from the tests the ts rewrite that we used to do on modules, because their payload’s lastModified is now always set to the fake currentDate injected by the tests. Some tests don't want to use the fake date though! (I hope they never run in parallel?) * clear currentDate in after * prettier --------- Co-authored-by: Mike Bostock --- src/config.ts | 2 +- src/javascript/module.ts | 3 +- src/loader.ts | 2 +- test/build-test.ts | 4 +- test/config-test.ts | 1 + test/deploy-test.ts | 1 + test/input/build/params2/[code]/analytics.js | 3 ++ test/input/build/params2/[code]/data.json.js | 1 + test/input/build/params2/index.md | 5 ++ .../_import/import-test.3349a02d.js | 1 + .../_import/import-test.e7269c4e.js | 1 - .../{test.86a60bc6.js => test.a9a4ef0e.js} | 2 +- test/output/build/data-loaders/index.html | 6 +-- .../{chart.2ce91e05.js => chart.4140747c.js} | 2 +- test/output/build/embed/chart.js | 2 +- .../foo/{foo.666599bc.js => foo.0cc12e18.js} | 4 +- .../{top.c85e149a.js => top.bacf54cc.js} | 6 +-- test/output/build/fetches/foo.html | 4 +- test/output/build/fetches/top.html | 6 +-- .../params2/_file/code/data.015abd7f.json | 1 + .../_import/code/analytics.0d826e00.js | 3 ++ .../params2/_observablehq/client.00000001.js | 0 .../params2/_observablehq/runtime.00000002.js | 0 .../params2/_observablehq/stdlib.00000003.js | 0 .../theme-air,near-midnight.00000004.css | 0 test/output/build/params2/index.html | 46 +++++++++++++++++++ 26 files changed, 83 insertions(+), 23 deletions(-) create mode 100644 test/input/build/params2/[code]/analytics.js create mode 100644 test/input/build/params2/[code]/data.json.js create mode 100644 test/input/build/params2/index.md create mode 100644 test/output/build/data-loaders/_import/import-test.3349a02d.js delete mode 100644 test/output/build/data-loaders/_import/import-test.e7269c4e.js rename test/output/build/data-loaders/_import/{test.86a60bc6.js => test.a9a4ef0e.js} (76%) rename test/output/build/embed/_import/{chart.2ce91e05.js => chart.4140747c.js} (84%) rename test/output/build/fetches/_import/foo/{foo.666599bc.js => foo.0cc12e18.js} (61%) rename test/output/build/fetches/_import/{top.c85e149a.js => top.bacf54cc.js} (57%) create mode 100644 test/output/build/params2/_file/code/data.015abd7f.json create mode 100644 test/output/build/params2/_import/code/analytics.0d826e00.js create mode 100644 test/output/build/params2/_observablehq/client.00000001.js create mode 100644 test/output/build/params2/_observablehq/runtime.00000002.js create mode 100644 test/output/build/params2/_observablehq/stdlib.00000003.js create mode 100644 test/output/build/params2/_observablehq/theme-air,near-midnight.00000004.css create mode 100644 test/output/build/params2/index.html diff --git a/src/config.ts b/src/config.ts index bf063bc46..8e53688ce 100644 --- a/src/config.ts +++ b/src/config.ts @@ -233,7 +233,7 @@ function readPages(root: string, md: MarkdownIt): Page[] { return pages; } -let currentDate: Date | null = null; +export let currentDate: Date | null = null; /** For testing only! */ export function setCurrentDate(date: Date | null): void { diff --git a/src/javascript/module.ts b/src/javascript/module.ts index 46daa8f47..03f5e1f5a 100644 --- a/src/javascript/module.ts +++ b/src/javascript/module.ts @@ -6,6 +6,7 @@ import {extname, join} from "node:path/posix"; import type {Program} from "acorn"; import type {TransformOptions} from "esbuild"; import {transform, transformSync} from "esbuild"; +import {currentDate} from "../config.js"; import {resolveJsrImport} from "../jsr.js"; import {resolveNodeImport} from "../node.js"; import {resolveNpmImport} from "../npm.js"; @@ -199,7 +200,7 @@ export function getFileInfo(root: string, path: string): FileInfo | undefined { const stat = statSync(key); if (!stat.isFile()) return; // ignore non-files accessSync(key, constants.R_OK); // verify that file is readable - mtimeMs = Math.floor(stat.mtimeMs); + mtimeMs = Math.floor((currentDate ?? stat.mtimeMs) as number); size = stat.size; } catch { fileInfoCache.delete(key); // delete stale entry diff --git a/src/loader.ts b/src/loader.ts index 324f1a8e1..8e28ace79 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -300,7 +300,7 @@ export class LoaderResolver { getOutputFileHash(name: string): string { const info = this.getOutputInfo(name); if (!info) throw new Error(`output file not found: ${name}`); - return info.hash; + return createHash("sha256").update(info.hash).update(String(info.mtimeMs)).digest("hex"); } getSourceInfo(name: string): FileInfo | undefined { diff --git a/test/build-test.ts b/test/build-test.ts index da7726f6c..b477d58fd 100644 --- a/test/build-test.ts +++ b/test/build-test.ts @@ -32,6 +32,7 @@ const failureTests = ["missing-file", "missing-import"]; describe("build", () => { before(() => setCurrentDate(new Date("2024-01-10T16:00:00"))); + after(() => setCurrentDate(null)); mockJsDelivr(); mockJsr(); mockDuckDB(); @@ -233,9 +234,6 @@ class TestEffects extends FileBuildEffects { contents = contents.replace(/^(\s* + + +
+ +
+

test

+
+
+ +
+ +