Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/core/devconfig.ts
3562 views
1
/*
2
* devconfig.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { error, info } from "../deno_ral/log.ts";
8
import { join } from "../deno_ral/path.ts";
9
import { ensureDirSync, existsSync } from "../deno_ral/fs.ts";
10
11
import { md5HashSync } from "./hash.ts";
12
13
import { quartoConfig } from "./quarto.ts";
14
import { normalizePath } from "./path.ts";
15
import { isWindows } from "../deno_ral/platform.ts";
16
17
const kDevConfig = "dev-config";
18
19
export interface DevConfig {
20
deno: string;
21
deno_dom: string;
22
pandoc: string;
23
dartsass: string;
24
esbuild: string;
25
typst: string;
26
script: string;
27
importMap: string;
28
}
29
30
export function createDevConfig(
31
deno: string,
32
deno_dom: string,
33
pandoc: string,
34
dartsass: string,
35
esbuild: string,
36
typst: string,
37
scriptDir: string,
38
): DevConfig {
39
const scriptPath = join(scriptDir, "quarto" + (isWindows ? ".cmd" : ""));
40
const srcDir = Deno.env.get("QUARTO_SRC_PATH") ||
41
join(quartoConfig.sharePath(), "../../src");
42
return {
43
deno,
44
deno_dom,
45
pandoc,
46
dartsass,
47
esbuild,
48
typst,
49
script: md5HashSync(Deno.readTextFileSync(scriptPath)),
50
importMap: md5HashSync(
51
Deno.readTextFileSync(
52
join(srcDir, "import_map.json"),
53
),
54
),
55
};
56
}
57
58
export function writeDevConfig(config: DevConfig, binPath: string) {
59
const configPath = join(binPath, "..", "config");
60
ensureDirSync(configPath);
61
Deno.writeTextFileSync(
62
join(configPath, kDevConfig),
63
JSON.stringify(config, undefined, 2),
64
);
65
}
66
67
export function readInstalledDevConfig(): DevConfig | null {
68
const binPath = quartoConfig.binPath();
69
const configPath = join(binPath, "..", "config", kDevConfig);
70
if (existsSync(configPath)) {
71
return JSON.parse(Deno.readTextFileSync(configPath)) as DevConfig;
72
} else {
73
return null;
74
}
75
}
76
77
export function readSourceDevConfig(): DevConfig {
78
const rootDir = Deno.env.get("QUARTO_ROOT") ||
79
join(quartoConfig.sharePath(), "../..");
80
const configurationScript = join(
81
rootDir,
82
"configuration",
83
);
84
const configurationScriptSrc = Deno.readTextFileSync(configurationScript);
85
const readConfig = (key: string) => {
86
const regex = new RegExp(`${key}=(\\S+)`);
87
const match = configurationScriptSrc.match(regex);
88
if (match) {
89
return match[1];
90
} else {
91
return "";
92
}
93
};
94
95
return createDevConfig(
96
readConfig("DENO"),
97
readConfig("DENO_DOM"),
98
readConfig("PANDOC"),
99
readConfig("DARTSASS"),
100
readConfig("ESBUILD"),
101
readConfig("TYPST"),
102
quartoConfig.binPath(),
103
);
104
}
105
106
export function devConfigsEqual(a: DevConfig, b: DevConfig) {
107
return a.deno === b.deno &&
108
a.deno_dom === b.deno_dom &&
109
a.pandoc === b.pandoc &&
110
a.dartsass == b.dartsass &&
111
a.esbuild == b.esbuild &&
112
a.typst === b.typst &&
113
a.script == b.script &&
114
a.importMap === b.importMap;
115
}
116
117
export async function reconfigureQuarto(
118
installed: DevConfig | null,
119
source: DevConfig,
120
) {
121
// Running configuration from within quarto does not work on windows
122
// because deno.exe is running and this lock and prevent reinstallation
123
// So we fail and print comment to run
124
if (isWindows) {
125
error(
126
`Quarto requires reconfiguration to ${
127
reconfigureReason(installed, source)
128
}. Please run \`./configure.cmd\` command.\n`,
129
);
130
return;
131
}
132
// Leaving Windows here if we find a way to reconfigure
133
// to not forget how to call the script
134
const configureScript = isWindows
135
? ["cmd", "/c", ".\\configure.cmd"]
136
: ["./configure.sh"];
137
138
const quartoDir = normalizePath(
139
join(quartoConfig.sharePath(), "..", ".."),
140
);
141
142
const process = new Deno.Command(configureScript[0], {
143
args: configureScript.slice(1),
144
cwd: quartoDir,
145
});
146
147
await process.output();
148
149
info("");
150
error(
151
`Quarto required reconfiguration to ${
152
reconfigureReason(installed, source)
153
}. Please try command again.\n`,
154
);
155
}
156
157
function reconfigureReason(
158
installed: DevConfig | null,
159
source: DevConfig,
160
) {
161
const versionMessage = (dep: string, version: string) => {
162
return `install ${dep} version ${version}`;
163
};
164
if (installed === null || installed.deno !== source.deno) {
165
return versionMessage("Deno", source.deno);
166
} else if (installed.deno_dom !== source.deno_dom) {
167
return versionMessage("Deno Dom", source.deno_dom);
168
} else if (installed.pandoc !== source.pandoc) {
169
return versionMessage("Pandoc", source.pandoc);
170
} else if (installed.dartsass !== source.dartsass) {
171
return versionMessage("Dart Sass", source.dartsass);
172
} else if (installed.esbuild !== source.esbuild) {
173
return versionMessage("Esbuild", source.esbuild);
174
} else if (installed.typst !== source.typst) {
175
return versionMessage("Typst", source.typst);
176
} else if (installed.script !== source.script) {
177
return "update Quarto wrapper script";
178
} else if (
179
installed.importMap !== source.importMap
180
) {
181
return "update dev import map";
182
}
183
}
184
185