Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/package/src/common/compile-quarto-latexmk.ts
6450 views
1
/*
2
* compile-quarto-latexmk.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*
6
*/
7
import { Command } from "cliffy/command/mod.ts";
8
import { basename, join } from "../../../src/deno_ral/path.ts";
9
import { ensureDirSync } from "../../../src/deno_ral/fs.ts";
10
import { info } from "../../../src/deno_ral/log.ts";
11
12
import { Configuration, readConfiguration } from "../common/config.ts";
13
import { compile, install, updateDenoPath } from "../util/deno.ts";
14
15
export function compileQuartoLatexmkCommand() {
16
return new Command()
17
.name("compile-quarto-latexmk")
18
.description("Builds binary for quarto-latexmk")
19
.option(
20
"-d, --development",
21
"Install for local development",
22
)
23
.option(
24
"-t, --target <target:string>",
25
"The target architecture for the binary (e.g. x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc, x86_64-apple-darwin, aarch64-apple-darwin)",
26
{
27
collect: true,
28
},
29
)
30
.option(
31
"-v, --version <version:string>",
32
"The version number of the compiled executable",
33
)
34
.option(
35
"-n, --name <name:string>",
36
"The name of the compiled executable",
37
)
38
.option(
39
"--description <description...:string>",
40
"The description of the compiled executable",
41
)
42
// deno-lint-ignore no-explicit-any
43
.action(async (args: Record<string, any>) => {
44
const configuration = readConfiguration();
45
info("Using configuration:");
46
info(configuration);
47
info("");
48
49
if (args.development) {
50
await installQuartoLatexmk(configuration);
51
} else {
52
const description = Array.isArray(args.description)
53
? args.description.join(" ")
54
: args.description || "Quarto Latexmk Engine";
55
56
const version = args.version || configuration.version;
57
const name = args.name || "quarto-latexmk";
58
const targets = (args.targets || [Deno.build.target]) as string[];
59
60
await compileQuartoLatexmk(
61
configuration,
62
targets,
63
version,
64
name,
65
description,
66
);
67
}
68
});
69
}
70
71
// Using --allow-all as there is otherwise an issue in Deno 1.46.3 with --allow-read and --allow-write with network drives
72
// https://github.com/quarto-dev/quarto-cli/issues/11332
73
/*
74
const kFlags = [
75
"--allow-read",
76
"--allow-write",
77
"--allow-run",
78
"--allow-env",
79
"--allow-net",
80
];
81
*/
82
const kFlags = ["--allow-all"];
83
84
export async function installQuartoLatexmk(
85
config: Configuration,
86
) {
87
const installPath = await install(
88
entryPointPath(config),
89
["-f", ...kFlags],
90
config,
91
);
92
if (installPath) {
93
updateDenoPath(installPath, config);
94
}
95
}
96
97
export async function compileQuartoLatexmk(
98
config: Configuration,
99
targets: string[],
100
version: string,
101
name: string,
102
description: string,
103
) {
104
const workingTempDir = Deno.makeTempDirSync();
105
try {
106
// If target isn't specified, build for whatever the current architecture is
107
targets = targets || [Deno.build.target];
108
109
// temporarily update the constants to reflect the provided information
110
const metadataPath = metadataFilePath(config);
111
info("Using executable info:");
112
info(`version: ${version}`);
113
info(`name: ${name}`);
114
info(`description: ${description}`);
115
info("");
116
117
// Backup a copy of the source
118
Deno.copyFileSync(
119
metadataPath,
120
join(workingTempDir, basename(metadataPath)),
121
);
122
123
// Generate the proper constants and compile
124
const verRegex = /^(export const kExeVersion = ").*(";)$/gm;
125
const nameRegex = /^(export const kExeName = ").*(";)$/gm;
126
const descRegex = /^(export const kExeDescription = ").*(";)$/gm;
127
128
let contents = Deno.readTextFileSync(metadataPath);
129
contents = contents.replace(verRegex, `$1${version}$2`);
130
contents = contents.replace(nameRegex, `$1${name}$2`);
131
contents = contents.replace(descRegex, `$1${description}$2`);
132
133
Deno.writeTextFileSync(metadataPath, contents);
134
135
for (const target of targets) {
136
const outputName = name || "quarto-latexmk";
137
info(`Compiling for ${target}:`);
138
const outputDir = join(
139
config.directoryInfo.bin,
140
outputName,
141
target,
142
);
143
ensureDirSync(outputDir);
144
const output = join(outputDir, filename(outputName, target));
145
146
await compile(
147
entryPointPath(config),
148
output,
149
[...kFlags],
150
config,
151
);
152
info(output + "\n");
153
}
154
155
// Restore the previously backed up file
156
Deno.copyFileSync(
157
join(workingTempDir, basename(metadataPath)),
158
metadataPath,
159
);
160
} finally {
161
Deno.removeSync(workingTempDir, { recursive: true });
162
}
163
}
164
165
function filename(name: string, target: string) {
166
if (target.match(/.*windows.*/)) {
167
return `${name}.exe`;
168
} else {
169
return name;
170
}
171
}
172
173
function metadataFilePath(config: Configuration) {
174
return join(
175
config.directoryInfo.src,
176
"command",
177
"render",
178
"latexmk",
179
"quarto-latexmk-metadata.ts",
180
);
181
}
182
183
function entryPointPath(config: Configuration) {
184
return join(
185
config.directoryInfo.src,
186
"command",
187
"render",
188
"latexmk",
189
"quarto-latexmk.ts",
190
);
191
}
192
193