Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/command/use/commands/binder/binder-utils.ts
3593 views
1
/*
2
* binder-utils.ts
3
*
4
* Copyright (C) 2021-2022 Posit Software, PBC
5
*/
6
7
import { md5HashAsync } from "../../../../core/hash.ts";
8
import { projectScratchPath } from "../../../../project/project-scratch.ts";
9
10
import { info, warning } from "../../../../deno_ral/log.ts";
11
import { ensureDirSync, existsSync } from "../../../../deno_ral/fs.ts";
12
import { dirname, join } from "../../../../deno_ral/path.ts";
13
14
import { Confirm } from "cliffy/prompt/mod.ts";
15
16
export const safeFileWriter = (projectDir: string, prompt = true) => {
17
// The index file in the project scratch directory
18
const idxPath = join(projectScratchPath(projectDir), "use", "binder.json");
19
20
// Ensure directory is there
21
ensureDirSync(dirname(idxPath));
22
23
// Read the index, if it is there
24
let fileIndex: Record<string, string> = {};
25
if (existsSync(idxPath)) {
26
fileIndex = JSON.parse(Deno.readTextFileSync(idxPath));
27
}
28
29
return async (projRelativePath: string, contents: string) => {
30
const absPath = join(projectDir, projRelativePath);
31
32
const write = () => {
33
fileIndex[projRelativePath] = hash;
34
Deno.writeTextFileSync(absPath, contents);
35
Deno.writeTextFileSync(idxPath, JSON.stringify(fileIndex, null, 2));
36
info(`[✓] ${projRelativePath}`);
37
};
38
39
const hash = await md5HashAsync(contents);
40
if (existsSync(absPath)) {
41
const lastHash = fileIndex[projRelativePath];
42
const currentContents = Deno.readTextFileSync(absPath);
43
const currentHash = await md5HashAsync(currentContents);
44
45
let writeFile = true;
46
if (!lastHash || lastHash !== currentHash) {
47
// The file exists and wasn't generated, prompt to overwrite
48
if (prompt) {
49
const question = lastHash
50
? `File ${projRelativePath} was modified since last generated. Overwrite?`
51
: `File ${projRelativePath} wasn't created by the this command. Overwrite?`;
52
writeFile = await Confirm.prompt({
53
message: question,
54
});
55
} else {
56
writeFile = false;
57
lastHash
58
? warning(
59
`Skipped ${projRelativePath} - modified since last generated.`,
60
)
61
: warning(
62
`Skipped ${projRelativePath} - wasn't created by the this command.`,
63
);
64
}
65
}
66
67
if (writeFile) {
68
write();
69
}
70
} else {
71
// the file doesn't exists, generate hash and store that, write the file
72
write();
73
}
74
};
75
};
76
77