-
Notifications
You must be signed in to change notification settings - Fork 351
/
Copy pathquarto.ts
139 lines (128 loc) · 4.17 KB
/
quarto.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* env.ts
*
* Copyright (C) 2020-2022 Posit Software, PBC
*/
import { existsSync } from "../deno_ral/fs.ts";
import { extname, join } from "../deno_ral/path.ts";
import { info } from "../deno_ral/log.ts";
import * as colors from "fmt/colors";
import { load as config, LoadOptions as ConfigOptions } from "dotenv";
import { getenv } from "./env.ts";
import { exitWithCleanup } from "./cleanup.ts";
import { onActiveProfileChanged } from "../project/project-profile.ts";
import { onDotenvChanged } from "../quarto-core/dotenv.ts";
import { normalizePath, safeExistsSync } from "./path.ts";
import { buildQuartoPreviewJs } from "./previewjs.ts";
import { isWindows } from "../deno_ral/platform.ts";
export const kLocalDevelopment = "99.9.9";
export interface QuartoConfig {
binPath(): string;
sharePath(): string;
isDebug(): boolean;
}
let dotenvConfig: Record<string, string>;
export const quartoConfig = {
binPath: () => getenv("QUARTO_BIN_PATH"),
toolsPath: () => join(getenv("QUARTO_BIN_PATH"), "tools"),
sharePath: () => getenv("QUARTO_SHARE_PATH"),
srcPath: () =>
getenv("QUARTO_SRC_PATH", "") ||
normalizePath(join(quartoConfig.sharePath(), "../../src")),
isDebug: () => getenv("QUARTO_DEBUG", "false") === "true",
version: () => {
const forceVersion = getenv("QUARTO_FORCE_VERSION", "");
if (forceVersion !== "") {
return forceVersion;
}
const versionPath = join(getenv("QUARTO_SHARE_PATH"), "version");
if (existsSync(versionPath)) {
return Deno.readTextFileSync(versionPath);
} else {
return kLocalDevelopment;
}
},
cliPath: () => {
// full path to quarto, quarto.cmd or quarto.exe depending on OS
const binPath = quartoConfig.binPath();
if (!isWindows) {
return join(binPath, "quarto");
}
// WINDOWS
const cliPath = join(binPath, "quarto.exe");
if (safeExistsSync(cliPath)) {
return cliPath;
}
// we are in dev mode were only quarto.cmd is available
return join(binPath, "quarto.cmd");
},
dotenv: async (forceReload?: boolean): Promise<Record<string, string>> => {
if (forceReload || !dotenvConfig) {
const options: ConfigOptions = {
defaultsPath: join(quartoConfig.sharePath(), "env", "env.defaults"),
// On dev mode only (QUARTO_DEBUG='true'), we load the .env file in root quarto-cli project
envPath: quartoConfig.isDebug()
? join(quartoConfig.sharePath(), "..", "..", ".env")
: null,
// we don't want any `.env.example` o be loaded, especially one from working dir
// https://github.com/quarto-dev/quarto-cli/issues/9262
examplePath: null,
};
dotenvConfig = await config(options);
}
return dotenvConfig;
},
};
export function previewEnsureResources(cleanup?: VoidFunction) {
if (quartoConfig.isDebug()) {
buildPreviewJs(quartoSrcDir(), cleanup);
}
}
export function previewMonitorResources(cleanup?: VoidFunction) {
// active profile changed
onActiveProfileChanged(() => {
terminatePreview("active profile changed", cleanup);
});
// dotenv changed
onDotenvChanged(() => {
terminatePreview("environment variables changed", cleanup);
});
// dev mode only
if (quartoConfig.isDebug()) {
// src code change
const srcDir = quartoSrcDir();
const watcher = Deno.watchFs([srcDir], { recursive: true });
const watchForChanges = async () => {
for await (const event of watcher) {
if (
event.paths.some((path) =>
extname(path).toLowerCase().startsWith(".ts")
)
) {
terminatePreview("quarto src code changed", cleanup);
}
}
};
watchForChanges();
}
}
function terminatePreview(reason: string, cleanup?: VoidFunction) {
info(
colors.bold(
colors.blue(`\n${reason}: preview terminating\n`),
),
);
if (cleanup) {
cleanup();
}
exitWithCleanup(1);
}
function quartoSrcDir() {
return normalizePath(join(quartoConfig.binPath(), "../../../src"));
}
function buildPreviewJs(srcDir: string, cleanup?: VoidFunction) {
const output = buildQuartoPreviewJs(srcDir);
if (!output.success) {
terminatePreview("Error building quarto-preview.js", cleanup);
}
}