From be4108a573790044900a069ec4b6608e656c1479 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Mon, 15 Jun 2026 15:50:25 +0100 Subject: [PATCH] add glob matching to isExtraneousFile (#34633) GitOrigin-RevId: f12aedb52195cfc9e3254936f1db6189f49c3f37 --- services/clsi/app/js/ResourceWriter.js | 10 ++++++++ services/clsi/config/settings.defaults.cjs | 1 + services/clsi/package.json | 1 + .../clsi/test/unit/js/ResourceWriter.test.js | 24 +++++++++++++++++++ yarn.lock | 3 ++- 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/services/clsi/app/js/ResourceWriter.js b/services/clsi/app/js/ResourceWriter.js index 61cab57625..dfacceafe2 100644 --- a/services/clsi/app/js/ResourceWriter.js +++ b/services/clsi/app/js/ResourceWriter.js @@ -23,9 +23,15 @@ import Metrics from '@overleaf/metrics' import logger from '@overleaf/logger' import settings from '@overleaf/settings' import ClsiMetrics from './Metrics.js' +import { Minimatch } from 'minimatch' const { shouldSkipMetrics } = ClsiMetrics +// Additional file patterns to keep between compiles +const preciousFileMatcher = new Minimatch(settings.preciousFilePattern, { + dot: true, +}) + let ResourceWriter const parallelFileDownloads = settings.parallelFileDownloads || 1 @@ -265,6 +271,10 @@ export default ResourceWriter = { // Epstopdf generated files shouldDelete = false } + // Keep additional precious files and directories + if (shouldDelete && preciousFileMatcher.match(path)) { + shouldDelete = false + } if ( path === 'output.tar.gz' || path === 'output.synctex.gz' || diff --git a/services/clsi/config/settings.defaults.cjs b/services/clsi/config/settings.defaults.cjs index 0235d72960..70c84d3201 100644 --- a/services/clsi/config/settings.defaults.cjs +++ b/services/clsi/config/settings.defaults.cjs @@ -35,6 +35,7 @@ module.exports = { process.env.PDFTOCAIRO_IMAGE || 'quay.io/sharelatex/pdftocairo:24.02', enablePdfConversions: process.env.ENABLE_PDF_CONVERSIONS === 'true', maxUploadSize: 50 * 1024 * 1024, + preciousFilePattern: process.env.PRECIOUS_FILE_PATTERN || '', internal: { clsi: { diff --git a/services/clsi/package.json b/services/clsi/package.json index 97e7a1d0d5..e2bcc927ed 100644 --- a/services/clsi/package.json +++ b/services/clsi/package.json @@ -31,6 +31,7 @@ "dockerode": "^4.0.9", "express": "4.22.1", "lodash": "^4.18.1", + "minimatch": "^10.2.5", "multer": "2.1.1", "overleaf-editor-core": "workspace:*", "p-limit": "^3.1.0", diff --git a/services/clsi/test/unit/js/ResourceWriter.test.js b/services/clsi/test/unit/js/ResourceWriter.test.js index 29bfbbeb5d..c32b96be01 100644 --- a/services/clsi/test/unit/js/ResourceWriter.test.js +++ b/services/clsi/test/unit/js/ResourceWriter.test.js @@ -19,6 +19,12 @@ describe('ResourceWriter', () => { }), })) + vi.doMock('@overleaf/settings', () => ({ + default: (ctx.settings = { + preciousFilePattern: '{keepdir/**,.other/keepdir/**}', + }), + })) + vi.doMock('../../../app/js/ResourceStateManager', () => ({ default: (ctx.ResourceStateManager = {}), })) @@ -246,6 +252,12 @@ describe('ResourceWriter', () => { { path: 'output.stderr', }, + { + path: 'keepdir/file', + }, + { + path: '.other/keepdir/.subdir/file', + }, ] ctx.resources = 'mock-resources' ctx.request = { @@ -297,6 +309,18 @@ describe('ResourceWriter', () => { .should.equal(true) }) + it('should not delete additionally specified files', ctx => { + return ctx.ResourceWriter._deleteFileIfNotDirectory + .calledWith(path.join(ctx.basePath, 'keepdir/file')) + .should.equal(false) + }) + + it('should not delete additionally specified hidden files', ctx => { + return ctx.ResourceWriter._deleteFileIfNotDirectory + .calledWith(path.join(ctx.basePath, '.other/keepdir/.subdir/file')) + .should.equal(false) + }) + it('should not delete the extra aux files', ctx => { return ctx.ResourceWriter._deleteFileIfNotDirectory .calledWith(path.join(ctx.basePath, 'extra.aux')) diff --git a/yarn.lock b/yarn.lock index d9666480d3..a225015327 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6531,6 +6531,7 @@ __metadata: express: "npm:4.22.1" form-data: "npm:^4.0.5" lodash: "npm:^4.18.1" + minimatch: "npm:^10.2.5" mocha: "npm:^11.1.0" mocha-junit-reporter: "npm:^2.2.1" mocha-multi-reporters: "npm:^1.5.1" @@ -24476,7 +24477,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.1.1, minimatch@npm:^10.2.1, minimatch@npm:^10.2.2, minimatch@npm:^10.2.4": +"minimatch@npm:^10.1.1, minimatch@npm:^10.2.1, minimatch@npm:^10.2.2, minimatch@npm:^10.2.4, minimatch@npm:^10.2.5": version: 10.2.5 resolution: "minimatch@npm:10.2.5" dependencies: