Skip to content

Commit

Permalink
don't clobber an existing file when building the site
Browse files Browse the repository at this point in the history
closes #1367
supersedes #1369
supersedes #1373
  • Loading branch information
Fil committed May 21, 2024
1 parent 3578dff commit fc1caff
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/build.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {createHash} from "node:crypto";
import {existsSync} from "node:fs";
import {access, constants, copyFile, readFile, stat, writeFile} from "node:fs/promises";
import {access, constants, copyFile, readFile, realpath, stat, writeFile} from "node:fs/promises";
import {basename, dirname, extname, join} from "node:path/posix";
import type {Config} from "./config.js";
import {CliError, isEnoent} from "./error.js";
import {getClientPath, prepareOutput, visitMarkdownFiles} from "./files.js";
import {getClientPath, maybeStat, prepareOutput, visitMarkdownFiles} from "./files.js";
import {getModuleHash} from "./javascript/module.js";
import {transpileModule} from "./javascript/transpile.js";
import type {Logger, Writer} from "./logger.js";
Expand Down Expand Up @@ -345,13 +345,25 @@ export class FileBuildEffects implements BuildEffects {
async copyFile(sourcePath: string, outputPath: string): Promise<void> {
const destination = join(this.outputRoot, outputPath);
this.logger.log(destination);
await noClobber(destination);
await prepareOutput(destination);
await copyFile(sourcePath, destination);
}
async writeFile(outputPath: string, contents: string | Buffer): Promise<void> {
const destination = join(this.outputRoot, outputPath);
this.logger.log(destination);
await noClobber(destination);
await prepareOutput(destination);
await writeFile(destination, contents);
}
}

// Asserts that the destination file is not already present. This can happen if
// the same file is referenced with inconsistent naming (e.g. upper vs.
// lowercase), and would result in a broken site.
async function noClobber(path) {
if (await maybeStat(path)) {
const real = (await realpath(path)).slice((await realpath(".")).length + 1);
throw new Error(`${faint("File name conflict over")} ${real}.`);
}
}

0 comments on commit fc1caff

Please sign in to comment.