From 8845f9efbd967f6b1eb19e334b15821e5fe90be6 Mon Sep 17 00:00:00 2001 From: kirrg001 Date: Sun, 12 Aug 2018 23:57:17 +0200 Subject: [PATCH] fix(v2): enforce v1 => v2 migration rules with zips refs #759 - helpful for testing - otherwise we allow a direct jump from e.g. 1.20 to 2.0 and this will crash - it will crash because Ghost v2 can't execute v1 migration scripts, because the context/code has changed --- lib/utils/version-from-zip.js | 33 ++++++++++++++++++----- test/fixtures/ghost-2.0.zip | Bin 0 -> 640 bytes test/unit/utils/version-from-zip-spec.js | 23 ++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/ghost-2.0.zip diff --git a/lib/utils/version-from-zip.js b/lib/utils/version-from-zip.js index 4a22f335a..a31a71520 100644 --- a/lib/utils/version-from-zip.js +++ b/lib/utils/version-from-zip.js @@ -5,6 +5,7 @@ const errors = require('../errors'); const semver = require('semver'); const AdmZip = require('adm-zip'); const cliPackage = require('../../package.json'); +const resolveVersion = require('./resolve-version'); module.exports = function versionFromZip(zipPath, currentVersion, force = false) { if (!path.isAbsolute(zipPath)) { @@ -47,11 +48,31 @@ module.exports = function versionFromZip(zipPath, currentVersion, force = false) })); } - if (force && semver.lt(pkg.version, currentVersion)) { - return Promise.reject( - new errors.SystemError('Zip file contains an older release version than what is currently installed.') - ); - } + return resolveVersion(null, currentVersion, true) + .then((latestV1ReleaseVersion) => { + // CASE: if major diff and you are not on the latest v1 + if (currentVersion && semver.major(currentVersion) !== semver.major(pkg.version) && + currentVersion !== latestV1ReleaseVersion) { + return Promise.reject(new errors.SystemError({ + message: 'You are about to migrate to Ghost 2.0. Your blog is not on the latest Ghost 1.0 version.', + help: 'Please run "ghost update --v1".' + })); + } + + if (force && semver.lt(pkg.version, currentVersion)) { + return Promise.reject( + new errors.SystemError('Zip file contains an older release version than what is currently installed.') + ); + } + + return Promise.resolve(pkg.version); + }) + .catch((err) => { + // CASE: you are on latest v1, but you want to manually migrate to v2 using a zip + if (err.message.match(/No valid versions found/) && semver.major(currentVersion) !== semver.major(pkg.version)) { + return Promise.resolve(pkg.version); + } - return Promise.resolve(pkg.version); + throw err; + }); }; diff --git a/test/fixtures/ghost-2.0.zip b/test/fixtures/ghost-2.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..560dc2ca93d4b90b552f355acd8d70edb99e0c83 GIT binary patch literal 640 zcmWIWW@Zs#-~hsuy*$1QNPveyfT18UIXf{uRWGYJKQA z_%qHHNMDq`Dt$pf@M3}VW$B!$kqr?6ZxgPbw49l6v@L;iLxpa*t~f)0H#H^Y?g|Y(8Kcpo(nEDhI9Rt)njx#BUIRqc-5SZ?D?)+76 z9gP#7S5JHD=xOTu`FeWlc!u(Euxakux=BIGC48RW1;&eDe;P7t#Ki#pwgK!Dx-gG|8{UI?T$=keiu-@D`AszzE_20549eJOBUy literal 0 HcmV?d00001 diff --git a/test/unit/utils/version-from-zip-spec.js b/test/unit/utils/version-from-zip-spec.js index 541ac677a..eb8e7e612 100644 --- a/test/unit/utils/version-from-zip-spec.js +++ b/test/unit/utils/version-from-zip-spec.js @@ -24,6 +24,29 @@ describe('Unit: Utils > versionFromZip', function () { }); }); + it('rejects if you are not on the latest v1 release and you are trying to jump to the next major', function () { + const resolveVersionStub = sinon.stub().resolves('1.25.4'); + const versionFromZip = proxyquire(modulePath, { + './resolve-version': resolveVersionStub + }); + + return versionFromZip(path.join(__dirname, '../../fixtures/ghost-2.0.zip'), '1.20.0').then(() => { + expect(false, 'error should have been thrown').to.be.true; + }).catch((error) => { + expect(error).to.be.an.instanceof(errors.SystemError); + expect(error.message).to.match(/You are about to migrate to Ghost 2.0/); + }); + }); + + it('resolves if you are on the latest v1 release and you are trying to jump to the next major', function () { + const resolveVersionStub = sinon.stub().rejects(new Error('No valid versions found.')); + const versionFromZip = proxyquire(modulePath, { + './resolve-version': resolveVersionStub + }); + + return versionFromZip(path.join(__dirname, '../../fixtures/ghost-2.0.zip'), '1.25.4'); + }); + it('rejects if zip file doesn\'t have a .zip extension', function () { const existsStub = sinon.stub().returns(true); const versionFromZip = proxyquire(modulePath, {