From e97717a0cce9b493e1dddde9e861e9a3866d54cc Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Thu, 10 Oct 2024 15:06:55 +0100 Subject: [PATCH] Added flag to skip gscan checks during boot no issue - bumped gscan version to provide `skipChecks` flag to `check` function - added `optimization:themes:skipBootChecks` config flag defaulting to `false` to maintain current behaviour - updated theme service initialization to use `skipChecks: true` when the config flag is set - we only want to skip the checks during boot in specific cases to improve performance, they are still useful for general development and any production use-cases where themes get edited directly on the server - updated our theme validate module to accept and pass through `skipChecks` option - switched the `isZip` positional argument of `validate.check()` to an options object property to make usage cleaner --- ghost/core/core/server/services/themes/activate.js | 4 ++-- ghost/core/core/server/services/themes/index.js | 5 ++++- ghost/core/core/server/services/themes/validate.js | 12 +++++++----- ghost/core/core/shared/config/defaults.json | 3 +++ ghost/core/package.json | 2 +- .../unit/server/services/themes/validate.test.js | 10 +++++----- yarn.lock | 8 ++++---- 7 files changed, 26 insertions(+), 18 deletions(-) diff --git a/ghost/core/core/server/services/themes/activate.js b/ghost/core/core/server/services/themes/activate.js index 5f9e21ce1e..04a0a50e0a 100644 --- a/ghost/core/core/server/services/themes/activate.js +++ b/ghost/core/core/server/services/themes/activate.js @@ -14,14 +14,14 @@ const messages = { themeCannotBeActivated: '{themeName} cannot be activated because it was not found in the theme directory.' }; -module.exports.loadAndActivate = async (themeName) => { +module.exports.loadAndActivate = async (themeName, options = {}) => { debug('loadAndActivate', themeName); try { // Just read the active theme for now const loadedTheme = await themeLoader.loadOneTheme(themeName); // Validate // @NOTE: this is now the only usage of check, rather than checkSafe... - const checkedTheme = await validate.check(themeName, loadedTheme); + const checkedTheme = await validate.check(themeName, loadedTheme, {skipChecks: options.skipChecks}); if (!validate.canActivate(checkedTheme)) { logging.error(validate.getThemeValidationError('activeThemeHasFatalErrors', themeName, checkedTheme)); diff --git a/ghost/core/core/server/services/themes/index.js b/ghost/core/core/server/services/themes/index.js index 82bb6218f5..31fc013091 100644 --- a/ghost/core/core/server/services/themes/index.js +++ b/ghost/core/core/server/services/themes/index.js @@ -5,6 +5,7 @@ const getJSON = require('./to-json'); const installer = require('./installer'); const validate = require('./validate'); const settingsCache = require('../../../shared/settings-cache'); +const config = require('../../../shared/config'); module.exports = { /* @@ -13,8 +14,10 @@ module.exports = { init: async () => { validate.init(); + const skipChecks = config.get('optimization:themes:skipBootChecks') || false; + const themeName = settingsCache.get('active_theme'); - return activate.loadAndActivate(themeName); + return activate.loadAndActivate(themeName, {skipChecks}); }, /** * Load all inactive themes diff --git a/ghost/core/core/server/services/themes/validate.js b/ghost/core/core/server/services/themes/validate.js index 9f786f067d..1a3741b1be 100644 --- a/ghost/core/core/server/services/themes/validate.js +++ b/ghost/core/core/server/services/themes/validate.js @@ -44,25 +44,27 @@ const getErrorsFromCheckedTheme = function getErrorsFromCheckedTheme(checkedThem }; }; -const check = async function check(themeName, theme, isZip) { +const check = async function check(themeName, theme, options = {}) { debug('Begin: Check'); // gscan can slow down boot time if we require on boot, for now nest the require. const gscan = require('gscan'); const checkedVersion = 'v5'; let checkedTheme; - if (isZip) { + if (options.isZip === true) { debug('zip mode'); checkedTheme = await gscan.checkZip(theme, { keepExtractedDir: true, checkVersion: checkedVersion, - labs: labs.getAll() + labs: labs.getAll(), + skipChecks: options.skipChecks || false }); } else { debug('non-zip mode'); checkedTheme = await gscan.check(theme.path, { checkVersion: checkedVersion, - labs: labs.getAll() + labs: labs.getAll(), + skipChecks: options.skipChecks || false }); } @@ -119,7 +121,7 @@ const getThemeErrors = async function getThemeErrors(themeName) { }; const checkSafe = async function checkSafe(themeName, theme, isZip) { - const checkedTheme = await check(themeName, theme, isZip); + const checkedTheme = await check(themeName, theme, {isZip}); if (canActivate(checkedTheme)) { return checkedTheme; diff --git a/ghost/core/core/shared/config/defaults.json b/ghost/core/core/shared/config/defaults.json index 9595d05ef2..109a1f6ce1 100644 --- a/ghost/core/core/shared/config/defaults.json +++ b/ghost/core/core/shared/config/defaults.json @@ -164,6 +164,9 @@ "threshold": 200, "level": "warn" } + }, + "themes": { + "skipBootChecks": false } }, "imageOptimization": { diff --git a/ghost/core/package.json b/ghost/core/package.json index 8da4f4fd89..99cd9c2c60 100644 --- a/ghost/core/package.json +++ b/ghost/core/package.json @@ -188,7 +188,7 @@ "ghost-storage-base": "1.0.0", "glob": "8.1.0", "got": "11.8.6", - "gscan": "4.43.7", + "gscan": "4.44.0", "human-number": "2.0.4", "image-size": "1.1.1", "intl": "1.2.5", diff --git a/ghost/core/test/unit/server/services/themes/validate.test.js b/ghost/core/test/unit/server/services/themes/validate.test.js index 2471675e90..a685595a14 100644 --- a/ghost/core/test/unit/server/services/themes/validate.test.js +++ b/ghost/core/test/unit/server/services/themes/validate.test.js @@ -45,7 +45,7 @@ describe('Themes', function () { checkZipStub.resolves({}); formatStub.returns({results: {error: []}}); - return validate.check(testTheme.name, testTheme, true) + return validate.check(testTheme.name, testTheme, {isZip: true}) .then((checkedTheme) => { checkZipStub.calledOnce.should.be.true(); checkZipStub.calledWith(testTheme).should.be.true(); @@ -61,7 +61,7 @@ describe('Themes', function () { checkStub.resolves({}); formatStub.returns({results: {error: []}}); - return validate.check(testTheme.name, testTheme, false) + return validate.check(testTheme.name, testTheme, {isZip: false}) .then((checkedTheme) => { checkZipStub.callCount.should.be.equal(0); checkStub.calledOnce.should.be.true(); @@ -91,7 +91,7 @@ describe('Themes', function () { } }); - return validate.check(testTheme.name, testTheme, true) + return validate.check(testTheme.name, testTheme, {isZip: true}) .then((checkedTheme) => { checkZipStub.calledOnce.should.be.true(); checkZipStub.calledWith(testTheme).should.be.true(); @@ -120,7 +120,7 @@ describe('Themes', function () { } }); - return validate.check(testTheme.name, testTheme, false) + return validate.check(testTheme.name, testTheme, {isZip: false}) .then((checkedTheme) => { checkStub.calledOnce.should.be.true(); checkStub.calledWith(testTheme.path).should.be.true(); @@ -135,7 +135,7 @@ describe('Themes', function () { checkZipStub.rejects(new Error('invalid zip file')); formatStub.returns({results: {error: []}}); - return validate.check(testTheme.name, testTheme, true) + return validate.check(testTheme.name, testTheme, {isZip: true}) .then((checkedTheme) => { checkedTheme.should.not.exist(); }).catch((error) => { diff --git a/yarn.lock b/yarn.lock index 8b0ccac03d..4063382088 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18669,10 +18669,10 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw== -gscan@4.43.7: - version "4.43.7" - resolved "https://registry.yarnpkg.com/gscan/-/gscan-4.43.7.tgz#fe39e9db02a770ee0e5a9f67b2129a29ee4b5bbf" - integrity sha512-Y91yFnr4owcmuzCK0PbQUUaqfX8YPYZQQiam3rp5XvfpazQYM4oaWF2AGGPmKXLnQg7m75qHcq+E860GnkQ8QA== +gscan@4.44.0: + version "4.44.0" + resolved "https://registry.yarnpkg.com/gscan/-/gscan-4.44.0.tgz#7f8d9408fa390dd5829aafc98159245277acf42b" + integrity sha512-f+ZLM5FKiJrglzQMkfpgNivJNEJ9+bllVFx972FfkKUV/b/PjE55KlNLJhw+ZxYZVBNM6lbxCsTywOeuvPgFFg== dependencies: "@sentry/node" "^7.73.0" "@tryghost/config" "^0.2.18"