From f38c2a236134a5851740a910ee023ee655b3f228 Mon Sep 17 00:00:00 2001 From: Ben Surgison Date: Wed, 25 Oct 2023 15:10:42 +0100 Subject: [PATCH] Fix plugin update detection --- CHANGELOG.md | 4 ++++ lib/plugins/packages.js | 4 ++-- lib/utils/index.js | 21 ++++++++++++++++++++- lib/utils/utils.test.js | 29 ++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec41f62a17..307f75d747 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Fixes + +- [#2364: Fix plugin update detection](https://github.com/alphagov/govuk-prototype-kit/pull/2364) + ## 13.13.5 ### Fixes diff --git a/lib/plugins/packages.js b/lib/plugins/packages.js index 95b80327b8..1a889e8a72 100644 --- a/lib/plugins/packages.js +++ b/lib/plugins/packages.js @@ -14,7 +14,7 @@ const projectPackage = require(path.join(projectDir, 'package.json')) const config = require('../config') const { getConfigForPackage } = require('../utils/requestHttps') const { getProxyPluginConfig } = require('./plugin-utils') -const { sortByObjectKey } = require('../utils') +const { sortByObjectKey, hasNewVersion } = require('../utils') let packageTrackerInterval @@ -119,7 +119,7 @@ async function refreshPackageInfo (packageName, version) { localVersion = path.resolve(installedPackageVersion.replace('file:', '')) } - const updateAvailable = installed && !installedLocally && !installedFromGithub && installedVersion !== latestVersion + const updateAvailable = installed && !installedLocally && !installedFromGithub && hasNewVersion(installedVersion, latestVersion) const pluginDependencies = pluginConfig?.pluginDependencies ? normaliseDependencies(pluginConfig.pluginDependencies) : undefined diff --git a/lib/utils/index.js b/lib/utils/index.js index 1ffa67d668..cfced2b129 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -268,6 +268,24 @@ function sortByObjectKey (key) { } } +function hasNewVersion (installedVersion, latestVersion) { + const matcher = /^(\d+)\.(\d+)\.(\d+)(.+)?/ + const [, installedMajor, installedMinor, installedPatch, installedSuffix] = installedVersion.match(matcher) + const [, latestMajor, latestMinor, latestPatch, latestSuffix] = latestVersion.match(matcher) + + if (installedMajor < latestMajor) return true + if (installedMajor > latestMajor) return false + if (installedMinor < latestMinor) return true + if (installedMinor > latestMinor) return false + if (installedPatch < latestPatch) return true + if (installedPatch > latestPatch) return false + + if (installedSuffix && latestSuffix) { + return installedSuffix < latestSuffix + } + return !!installedSuffix +} + module.exports = { prototypeAppScripts: scripts, addNunjucksFilters, @@ -282,5 +300,6 @@ module.exports = { sessionFileStoreQuietLogFn, searchAndReplaceFiles, recursiveDirectoryContentsSync, - sortByObjectKey + sortByObjectKey, + hasNewVersion } diff --git a/lib/utils/utils.test.js b/lib/utils/utils.test.js index c54448a790..7bb40c1796 100644 --- a/lib/utils/utils.test.js +++ b/lib/utils/utils.test.js @@ -1,5 +1,6 @@ /* eslint-env jest */ +const { sessionFileStoreQuietLogFn, hasNewVersion } = require('./index') afterEach(() => { jest.useRealTimers() jest.restoreAllMocks() @@ -10,7 +11,6 @@ describe('sessionFileStoreQuietLogFn', () => { jest.spyOn(global.console, 'log').mockImplementation() const SessionFileStore = require('../session-file-store') - const { sessionFileStoreQuietLogFn } = require('./index') jest.useFakeTimers({ doNotFake: ['performance'] }) @@ -26,3 +26,30 @@ describe('sessionFileStoreQuietLogFn', () => { expect(console.log).not.toHaveBeenCalled() }) }) + +describe('hasNewVersion', () => { + [ + { installed: '13.1.0', latest: '13.1.0', result: false }, + { installed: '13.1.1', latest: '13.1.0', result: false }, + { installed: '13.2.0', latest: '13.1.0', result: false }, + { installed: '14.1.0', latest: '13.1.0', result: false }, + { installed: '13.1.0', latest: '13.1.1', result: true }, + { installed: '13.1.0', latest: '13.2.0', result: true }, + { installed: '13.1.0', latest: '14.1.0', result: true }, + { installed: '13.2.4-rc1', latest: '13.2.4-rc1', result: false }, + { installed: '13.2.3-rc1', latest: '13.2.4-rc1', result: true }, + { installed: '13.2.4-rc1', latest: '13.2.4-rc2', result: true }, + { installed: '13.2.4-rc1', latest: '13.2.4', result: true }, + { installed: '13.2.4', latest: '13.2.4-rc1', result: false }, + { installed: '5.0.0-internal.0', latest: '4.7.0', result: false }, + { installed: '4.7.0', latest: '5.0.0-internal.0', result: true }, + { installed: '4.7.0-internal.0', latest: '5.0.0', result: true }, + { installed: '5.0.0', latest: '4.7.0-internal.0', result: false } + ].forEach(({ + installed, + latest, + result + }) => it(`should return ${result} when installed version is ${installed} and latest version is ${latest}`, () => { + expect(hasNewVersion(installed, latest)).toEqual(result) + })) +})