Skip to content

Commit e0cb9ea

Browse files
authored
Merge pull request #11968 from quarto-dev/feature/project-cache
[feat] typescript - projects have a persistent disk cache
2 parents a5b92f9 + 60294d0 commit e0cb9ea

File tree

24 files changed

+439
-78
lines changed

24 files changed

+439
-78
lines changed

src/command/preview/cmd.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ export const previewCommand = new Command()
278278
// get project and preview format
279279
const nbContext = notebookContext();
280280
const project = (await projectContext(dirname(file), nbContext)) ||
281-
singleFileProjectContext(file, nbContext);
281+
(await singleFileProjectContext(file, nbContext));
282282
const formats = await (async () => {
283283
const services = renderServices(nbContext);
284284
try {

src/command/preview/preview.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ export async function previewFormat(
373373
return format;
374374
}
375375
const nbContext = notebookContext();
376-
project = project || singleFileProjectContext(file, nbContext);
376+
project = project || (await singleFileProjectContext(file, nbContext));
377377
formats = formats ||
378378
await withRenderServices(
379379
nbContext,
@@ -485,6 +485,8 @@ export async function renderForPreview(
485485
[],
486486
));
487487

488+
renderResult.context.cleanup();
489+
488490
return {
489491
file,
490492
format: renderResult.files[0].format,

src/command/publish/cmd.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ async function createPublishOptions(
339339

340340
// check for directory (either website or single-file project)
341341
const project = (await projectContext(path, nbContext)) ||
342-
singleFileProjectContext(path, nbContext);
342+
(await singleFileProjectContext(path, nbContext));
343343
if (Deno.statSync(path).isDirectory) {
344344
if (projectIsWebsite(project)) {
345345
input = project;

src/command/render/cmd.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ export const renderCommand = new Command()
245245
const services = renderServices(notebookContext());
246246
try {
247247
renderResultInput = relative(Deno.cwd(), walk.path) || ".";
248+
if (renderResult) {
249+
renderResult.context.cleanup();
250+
}
248251
renderResult = await render(renderResultInput, {
249252
services,
250253
flags,
@@ -255,6 +258,7 @@ export const renderCommand = new Command()
255258

256259
// check for error
257260
if (renderResult.error) {
261+
renderResult.context.cleanup();
258262
throw renderResult.error;
259263
}
260264
} finally {
@@ -275,6 +279,10 @@ export const renderCommand = new Command()
275279
if (finalOutput) {
276280
info("Output created: " + finalOutput + "\n");
277281
}
282+
283+
if (renderResult) {
284+
renderResult.context.cleanup();
285+
}
278286
}
279287
} else {
280288
throw new Error(`No valid input files passed to render`);

src/command/render/pandoc-html.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ export async function resolveSassBundles(
5353
inputDir: string,
5454
extras: FormatExtras,
5555
format: Format,
56-
temp: TempContext,
5756
project: ProjectContext,
5857
) {
5958
extras = cloneDeep(extras);
@@ -159,11 +158,11 @@ export async function resolveSassBundles(
159158

160159
for (const target of targets) {
161160
let cssPath: string | undefined;
162-
cssPath = await compileSass(target.bundles, temp);
161+
cssPath = await compileSass(target.bundles, project);
163162
// First, Clean CSS
164163
cleanSourceMappingUrl(cssPath);
165164
// look for a sentinel 'dark' value, extract variables
166-
const cssResult = await processCssIntoExtras(cssPath, extras, temp);
165+
const cssResult = await processCssIntoExtras(cssPath, extras, project);
167166
cssPath = cssResult.path;
168167

169168
// it can happen that processing generate an empty css file (e.g quarto-html deps with Quarto CSS variables)
@@ -261,7 +260,7 @@ export async function resolveSassBundles(
261260
inputDir,
262261
extras,
263262
format,
264-
temp,
263+
project,
265264
hasDarkStyles ? "light" : "default",
266265
defaultStyle,
267266
);
@@ -272,7 +271,7 @@ export async function resolveSassBundles(
272271
inputDir,
273272
extras,
274273
format,
275-
temp,
274+
project,
276275
"dark",
277276
defaultStyle,
278277
);
@@ -291,7 +290,7 @@ async function resolveQuartoSyntaxHighlighting(
291290
inputDir: string,
292291
extras: FormatExtras,
293292
format: Format,
294-
temp: TempContext,
293+
project: ProjectContext,
295294
style: "dark" | "light" | "default",
296295
defaultStyle?: "dark" | "light",
297296
) {
@@ -381,7 +380,7 @@ async function resolveQuartoSyntaxHighlighting(
381380
rules: rules.join("\n"),
382381
},
383382
}],
384-
temp,
383+
project,
385384
false,
386385
);
387386

@@ -500,8 +499,9 @@ interface CSSResult {
500499
async function processCssIntoExtras(
501500
cssPath: string,
502501
extras: FormatExtras,
503-
temp: TempContext,
502+
project: ProjectContext,
504503
): Promise<CSSResult> {
504+
const { temp } = project;
505505
extras.html = extras.html || {};
506506

507507
const css = Deno.readTextFileSync(cssPath);

src/command/render/pandoc.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,6 @@ export async function runPandoc(
536536
options.format,
537537
cwd,
538538
options.libDir,
539-
options.services.temp,
540539
dependenciesFile,
541540
options.project,
542541
);
@@ -963,9 +962,6 @@ export async function runPandoc(
963962
// filter results json file
964963
const filterResultsFile = options.services.temp.createFile();
965964

966-
// timing results json file
967-
const timingResultsFile = options.services.temp.createFile();
968-
969965
const writerKeys: ("to" | "writer")[] = ["to", "writer"];
970966
for (const key of writerKeys) {
971967
if (allDefaults[key]?.match(/[.]lua$/)) {
@@ -1397,7 +1393,6 @@ async function resolveExtras(
13971393
format: Format,
13981394
inputDir: string,
13991395
libDir: string,
1400-
temp: TempContext,
14011396
dependenciesFile: string,
14021397
project: ProjectContext,
14031398
) {
@@ -1415,7 +1410,6 @@ async function resolveExtras(
14151410
inputDir,
14161411
extras,
14171412
format,
1418-
temp,
14191413
project,
14201414
);
14211415

src/command/render/render-contexts.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ import {
8989
import { ExtensionContext } from "../../extension/types.ts";
9090
import { NotebookContext } from "../../render/notebook/notebook-types.ts";
9191

92+
// we can't naively ld.cloneDeep everything
93+
// because that destroys class instances
94+
// with private members
95+
//
96+
// Currently, that's ProjectContext.
97+
//
98+
// TODO: Ideally, we shouldn't be copying the RenderContext at all.
99+
export function copyRenderContext(
100+
context: RenderContext,
101+
): RenderContext {
102+
return {
103+
...ld.cloneDeep(context),
104+
project: context.project,
105+
};
106+
}
92107
export async function resolveFormatsFromMetadata(
93108
metadata: Metadata,
94109
input: string,
@@ -741,20 +756,17 @@ export async function projectMetadataForInputFile(
741756
input: string,
742757
project: ProjectContext,
743758
): Promise<Metadata> {
744-
// don't mutate caller
745-
project = ld.cloneDeep(project) as ProjectContext;
746-
747759
if (project.dir && project.config) {
748760
// If there is directory and configuration information
749761
// process paths
750762
return toInputRelativePaths(
751763
projectType(project.config?.project?.[kProjectType]),
752764
project.dir,
753765
dirname(input),
754-
project.config,
766+
ld.cloneDeep(project.config),
755767
) as Metadata;
756768
} else {
757769
// Just return the config or empty metadata
758-
return project.config || {};
770+
return ld.cloneDeep(project.config) || {};
759771
}
760772
}

src/command/render/render-files.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import { outputRecipe } from "./output.ts";
4848

4949
import { renderPandoc } from "./render.ts";
5050
import { PandocRenderCompletion, RenderServices } from "./types.ts";
51-
import { renderContexts } from "./render-contexts.ts";
51+
import { copyRenderContext, renderContexts } from "./render-contexts.ts";
5252
import { renderProgress } from "./render-info.ts";
5353
import {
5454
ExecutedFile,
@@ -503,7 +503,7 @@ async function renderFileInternal(
503503

504504
for (const format of Object.keys(contexts)) {
505505
pushTiming("render-context");
506-
const context = ld.cloneDeep(contexts[format]) as RenderContext; // since we're going to mutate it...
506+
const context = copyRenderContext(contexts[format]); // since we're going to mutate it...
507507

508508
// disquality some documents from server: shiny
509509
if (isServerShiny(context.format) && context.project) {

src/command/render/render-shared.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { kTextPlain } from "../../core/mime.ts";
3333
import { normalizePath } from "../../core/path.ts";
3434
import { notebookContext } from "../../render/notebook/notebook-context.ts";
3535
import { singleFileProjectContext } from "../../project/types/single-file/single-file.ts";
36+
import { assert } from "testing/asserts";
3637

3738
export async function render(
3839
path: string,
@@ -95,8 +96,9 @@ export async function render(
9596
// validate that we didn't get any project-only options
9697
validateDocumentRenderFlags(options.flags);
9798

99+
assert(!context, "Expected no context here");
98100
// NB: singleFileProjectContext is currently not fully-featured
99-
context = singleFileProjectContext(path, nbContext, options.flags);
101+
context = await singleFileProjectContext(path, nbContext, options.flags);
100102

101103
// otherwise it's just a file render
102104
const result = await renderFiles(

src/command/render/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export interface RenderResourceFiles {
102102
}
103103

104104
export interface RenderResult {
105-
context?: ProjectContext;
105+
context: ProjectContext;
106106
baseDir?: string;
107107
outputDir?: string;
108108
files: RenderResultFile[];

0 commit comments

Comments
 (0)