Skip to content

Commit 991f605

Browse files
authored
missing files break the build (#1651)
1 parent 7113770 commit 991f605

File tree

22 files changed

+18
-185
lines changed

22 files changed

+18
-185
lines changed

src/build.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {createHash} from "node:crypto";
22
import {copyFile, readFile, rm, stat, writeFile} from "node:fs/promises";
33
import {basename, dirname, extname, join} from "node:path/posix";
44
import type {Config} from "./config.js";
5-
import {CliError, isEnoent} from "./error.js";
5+
import {CliError} from "./error.js";
66
import {getClientPath, prepareOutput} from "./files.js";
77
import {findModule, getLocalModuleHash, getModuleHash, readJavaScript} from "./javascript/module.js";
88
import {transpileModule} from "./javascript/transpile.js";
@@ -176,14 +176,7 @@ export async function build(
176176
// Copy over referenced files, accumulating hashed aliases.
177177
for (const file of files) {
178178
effects.output.write(`${faint("copy")} ${join(root, file)} ${faint("→")} `);
179-
let sourcePath: string;
180-
try {
181-
sourcePath = join(root, await loaders.loadFile(join("/", file), {useStale: true}, effects));
182-
} catch (error) {
183-
if (!isEnoent(error)) throw error;
184-
effects.logger.error(red("error: missing referenced file"));
185-
continue;
186-
}
179+
const sourcePath = join(root, await loaders.loadFile(join("/", file), {useStale: true}, effects));
187180
const contents = await readFile(sourcePath);
188181
const hash = createHash("sha256").update(contents).digest("hex").slice(0, 8);
189182
const alias = applyHash(join("/_file", file), hash);
@@ -242,22 +235,12 @@ export async function build(
242235
};
243236
for (const path of localImports) {
244237
const module = findModule(root, path);
245-
if (!module) {
246-
effects.logger.error(red(`error: import not found: ${path}`));
247-
continue;
248-
}
238+
if (!module) throw new Error(`import not found: ${path}`);
249239
const sourcePath = join(root, module.path);
250240
const importPath = join("_import", module.path);
251241
effects.output.write(`${faint("copy")} ${sourcePath} ${faint("→")} `);
252242
const resolveImport = getModuleResolver(root, path);
253-
let input: string;
254-
try {
255-
input = await readJavaScript(sourcePath);
256-
} catch (error) {
257-
if (!isEnoent(error)) throw error;
258-
effects.logger.error(red("error: missing referenced import"));
259-
continue;
260-
}
243+
const input = await readJavaScript(sourcePath);
261244
const contents = await transpileModule(input, {
262245
root,
263246
path,

test/build-test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ function getHashNormalizer() {
2525
};
2626
}
2727

28+
/** These tests are intended to fail. */
29+
const failureTests = ["missing-file", "missing-import"];
30+
2831
describe("build", () => {
2932
before(() => setCurrentDate(new Date("2024-01-10T16:00:00")));
3033
mockJsDelivr();
@@ -48,14 +51,21 @@ describe("build", () => {
4851
: it)(`${inputRoot}/${name}`, async () => {
4952
const actualDir = join(outputRoot, `${outname}-changed`);
5053
const expectedDir = join(outputRoot, outname);
51-
const generate = !existsSync(expectedDir) && process.env.CI !== "true";
54+
const generate = !existsSync(expectedDir) && !failureTests.includes(outname) && process.env.CI !== "true";
5255
const outputDir = generate ? expectedDir : actualDir;
5356
const normalizeHash = getHashNormalizer();
5457

5558
await rm(actualDir, {recursive: true, force: true});
5659
if (generate) console.warn(`! generating ${expectedDir}`);
5760
const config = {...(await readConfig(undefined, path)), output: outputDir};
58-
await build({config}, new TestEffects(outputDir, join(config.root, ".observablehq", "cache")));
61+
try {
62+
await build({config}, new TestEffects(outputDir, join(config.root, ".observablehq", "cache")));
63+
} catch (error) {
64+
if (!failureTests.includes(outname)) throw error;
65+
await rm(outputDir, {recursive: true, force: true});
66+
return;
67+
}
68+
if (failureTests.includes(outname)) throw new Error(`expected failure: ${outname}`);
5969

6070
// Replace any hashed files in _observablehq with empty files, and
6171
// renumber the hashes so they are sequential. This way we don’t have to

test/files-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ describe("visitFiles(root)", () => {
5555
"files.md",
5656
"observable logo small.png",
5757
"observable logo.png",
58+
"unknown-mime-extension.really",
5859
"subsection/additional-styles.css",
5960
"subsection/file-sub.csv",
6061
"subsection/subfiles.md"

test/input/build/archives.posix/tar.md

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,10 @@ await FileAttachment("static-tar/file.txt").text()
88
await FileAttachment("static-tgz/file.txt").text()
99
```
1010

11-
```js
12-
await FileAttachment("static-tar/does-not-exist.txt").text()
13-
```
14-
1511
```js
1612
await FileAttachment("dynamic-tar/file.txt").text()
1713
```
1814

19-
```js
20-
await FileAttachment("dynamic-tar/does-not-exist.txt").text()
21-
```
22-
2315
```js
2416
await FileAttachment("dynamic-tar-gz/file.txt").text()
2517
```
26-
27-
```js
28-
await FileAttachment("dynamic-tar-gz/does-not-exist.txt").text()
29-
```

test/input/build/archives.posix/zip.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,10 @@
44
await FileAttachment("static/file.txt").text()
55
```
66

7-
```js
8-
await FileAttachment("static/not-found.txt").text()
9-
```
10-
117
```js
128
await FileAttachment("dynamic/file.txt").text()
139
```
1410

15-
```js
16-
await FileAttachment("dynamic/not-found.txt").text()
17-
```
18-
1911
```js
2012
// await FileAttachment("dynamic.zip")
2113
```

test/input/build/archives.win32/tar.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,3 @@ await FileAttachment("static-tar/file.txt").text()
77
```js
88
await FileAttachment("static-tgz/file.txt").text()
99
```
10-
11-
```js
12-
await FileAttachment("static-tar/does-not-exist.txt").text()
13-
```

test/input/build/archives.win32/zip.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,3 @@
33
```js
44
await FileAttachment("static/file.txt").text()
55
```
6-
7-
```js
8-
await FileAttachment("static/not-found.txt").text()
9-
```

test/output/build/archives.posix/tar.html

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@
1616
import {define} from "./_observablehq/client.00000001.js";
1717
import {registerFile} from "./_observablehq/stdlib.00000003.js";
1818

19-
registerFile("./dynamic-tar-gz/does-not-exist.txt", {"name":"./dynamic-tar-gz/does-not-exist.txt","mimeType":"text/plain","path":"./dynamic-tar-gz/does-not-exist.txt"});
2019
registerFile("./dynamic-tar-gz/file.txt", {"name":"./dynamic-tar-gz/file.txt","mimeType":"text/plain","path":"./_file/dynamic-tar-gz/file.c93138d8.txt","lastModified":/* ts */1706742000000,"size":21});
21-
registerFile("./dynamic-tar/does-not-exist.txt", {"name":"./dynamic-tar/does-not-exist.txt","mimeType":"text/plain","path":"./dynamic-tar/does-not-exist.txt"});
2220
registerFile("./dynamic-tar/file.txt", {"name":"./dynamic-tar/file.txt","mimeType":"text/plain","path":"./_file/dynamic-tar/file.c93138d8.txt","lastModified":/* ts */1706742000000,"size":21});
23-
registerFile("./static-tar/does-not-exist.txt", {"name":"./static-tar/does-not-exist.txt","mimeType":"text/plain","path":"./static-tar/does-not-exist.txt"});
2421
registerFile("./static-tar/file.txt", {"name":"./static-tar/file.txt","mimeType":"text/plain","path":"./_file/static-tar/file.c93138d8.txt","lastModified":/* ts */1706742000000,"size":21});
2522
registerFile("./static-tgz/file.txt", {"name":"./static-tgz/file.txt","mimeType":"text/plain","path":"./_file/static-tgz/file.c93138d8.txt","lastModified":/* ts */1706742000000,"size":21});
2623

@@ -36,36 +33,18 @@
3633
))
3734
}});
3835

39-
define({id: "d84cd7fb", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
40-
display(await(
41-
await FileAttachment("./static-tar/does-not-exist.txt").text()
42-
))
43-
}});
44-
4536
define({id: "86bd51aa", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
4637
display(await(
4738
await FileAttachment("./dynamic-tar/file.txt").text()
4839
))
4940
}});
5041

51-
define({id: "95938c22", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
52-
display(await(
53-
await FileAttachment("./dynamic-tar/does-not-exist.txt").text()
54-
))
55-
}});
56-
5742
define({id: "7e5740fd", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
5843
display(await(
5944
await FileAttachment("./dynamic-tar-gz/file.txt").text()
6045
))
6146
}});
6247

63-
define({id: "d0a58efd", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
64-
display(await(
65-
await FileAttachment("./dynamic-tar-gz/does-not-exist.txt").text()
66-
))
67-
}});
68-
6948
</script>
7049
<input id="observablehq-sidebar-toggle" type="checkbox" title="Toggle sidebar">
7150
<label id="observablehq-sidebar-backdrop" for="observablehq-sidebar-toggle"></label>
@@ -89,11 +68,8 @@
8968
<h1 id="tar" tabindex="-1"><a class="observablehq-header-anchor" href="#tar">Tar</a></h1>
9069
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:d5134368:--></div>
9170
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:a0c06958:--></div>
92-
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:d84cd7fb:--></div>
9371
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:86bd51aa:--></div>
94-
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:95938c22:--></div>
9572
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:7e5740fd:--></div>
96-
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:d0a58efd:--></div>
9773
</main>
9874
<footer id="observablehq-footer">
9975
<nav><a rel="next" href="./zip"><span>Zip</span></a></nav>

test/output/build/archives.posix/zip.html

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,20 @@
1717
import {registerFile} from "./_observablehq/stdlib.00000003.js";
1818

1919
registerFile("./dynamic/file.txt", {"name":"./dynamic/file.txt","mimeType":"text/plain","path":"./_file/dynamic/file.c93138d8.txt","lastModified":/* ts */1706742000000,"size":21});
20-
registerFile("./dynamic/not-found.txt", {"name":"./dynamic/not-found.txt","mimeType":"text/plain","path":"./dynamic/not-found.txt"});
2120
registerFile("./static/file.txt", {"name":"./static/file.txt","mimeType":"text/plain","path":"./_file/static/file.d9014c46.txt","lastModified":/* ts */1706742000000,"size":14});
22-
registerFile("./static/not-found.txt", {"name":"./static/not-found.txt","mimeType":"text/plain","path":"./static/not-found.txt"});
2321

2422
define({id: "d3b9d0ee", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
2523
display(await(
2624
await FileAttachment("./static/file.txt").text()
2725
))
2826
}});
2927

30-
define({id: "bab54217", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
31-
display(await(
32-
await FileAttachment("./static/not-found.txt").text()
33-
))
34-
}});
35-
3628
define({id: "11eec300", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
3729
display(await(
3830
await FileAttachment("./dynamic/file.txt").text()
3931
))
4032
}});
4133

42-
define({id: "ee2310f3", inputs: ["FileAttachment","display"], body: async (FileAttachment,display) => {
43-
display(await(
44-
await FileAttachment("./dynamic/not-found.txt").text()
45-
))
46-
}});
47-
4834
define({id: "f9a513d8", body: () => {
4935
// await FileAttachment("dynamic.zip")
5036
}});
@@ -71,9 +57,7 @@
7157
<main id="observablehq-main" class="observablehq">
7258
<h1 id="zip" tabindex="-1"><a class="observablehq-header-anchor" href="#zip">Zip</a></h1>
7359
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:d3b9d0ee:--></div>
74-
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:bab54217:--></div>
7560
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:11eec300:--></div>
76-
<div class="observablehq observablehq--block"><observablehq-loading></observablehq-loading><!--:ee2310f3:--></div>
7761
<div class="observablehq observablehq--block"><!--:f9a513d8:--></div>
7862
</main>
7963
<footer id="observablehq-footer">

0 commit comments

Comments
 (0)