Skip to content

Commit

Permalink
fix(yarn-install): remove folder on ghost download error
Browse files Browse the repository at this point in the history
refs #726
- if an error occurs when installing the Ghost code during install or update, we remove the versions folder so that Ghost doesn't treat it as successfully installed
  • Loading branch information
acburdine committed May 26, 2018
1 parent 105bde4 commit c96a768
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 5 deletions.
20 changes: 15 additions & 5 deletions lib/tasks/yarn-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const subTasks = {
file.path = file.path.replace('package/', '');
return file;
}
}).catch((error) => {
// Clean up the install folder since the decompress failed
fs.removeSync(ctx.installPath);
return Promise.reject(error);
});
});
}
Expand All @@ -73,11 +77,17 @@ module.exports = function yarnInstall(ui, zipFile) {

tasks.push({
title: 'Installing dependencies',
task: (ctx) => yarn(['install', '--no-emoji', '--no-progress'], {
cwd: ctx.installPath,
env: {NODE_ENV: 'production'},
observe: true
})
task: (ctx) => {
return yarn(['install', '--no-emoji', '--no-progress'], {
cwd: ctx.installPath,
env: {NODE_ENV: 'production'},
observe: true
}).catch((error) => {
// Add error catcher so we can cleanup the install path if an error occurs
fs.removeSync(ctx.installPath);
return Promise.reject(error);
});
}
});

return ui.listr(tasks, false);
Expand Down
64 changes: 64 additions & 0 deletions test/unit/tasks/yarn-install-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,41 @@ describe('Unit: Tasks > yarn-install', function () {
});
});

it('catches errors from yarn and cleans up install folder', function () {
const yarnStub = sinon.stub().rejects(new Error('an error occurred'));
const yarnInstall = proxyquire(modulePath, {
'../utils/yarn': yarnStub
});
const subTasks = yarnInstall.subTasks;
const env = setupTestFolder();
const ctx = {installPath: env.dir};
const listrStub = sinon.stub().callsFake((tasks) => {
expect(tasks).to.have.length(3);

return Promise.each(tasks, (task) => task.task(ctx));
});

const distTaskStub = sinon.stub(subTasks, 'dist').resolves();
const downloadTaskStub = sinon.stub(subTasks, 'download');

return yarnInstall({listr: listrStub}).then(() => {
expect(false, 'error should have been thrown').to.be.true;
}).catch((error) => {
expect(error.message).to.equal('an error occurred');
expect(listrStub.calledOnce).to.be.true;
expect(distTaskStub.calledOnce).to.be.true;
expect(downloadTaskStub.calledOnce).to.be.true;
expect(yarnStub.calledOnce).to.be.true;
expect(yarnStub.args[0][0]).to.deep.equal(['install', '--no-emoji', '--no-progress']);
expect(yarnStub.args[0][1]).to.deep.equal({
cwd: env.dir,
env: {NODE_ENV: 'production'},
observe: true
});
expect(fs.existsSync(env.dir)).to.be.false;
});
});

describe('dist subtask', function () {
it('rejects if yarn util returns invalid json', function () {
const yarnStub = sinon.stub().resolves({stdout: 'not json'});
Expand Down Expand Up @@ -253,5 +288,34 @@ describe('Unit: Tasks > yarn-install', function () {
expect(mapResult).to.deep.equal([{path: 'index.js'}, {path: 'package.json'}, {path: 'yarn.lock'}]);
});
});

it('catches errors from decompress and cleans up the install folder', function () {
const env = setupTestFolder();
const downloadStub = sinon.stub().resolves({downloadedData: true});
const shasumStub = sinon.stub().returns('asdf1234');
const decompressStub = sinon.stub().rejects(new Error('an error occurred'));
const downloadTask = proxyquire(modulePath, {
download: downloadStub,
shasum: shasumStub,
decompress: decompressStub
}).subTasks.download;
const ctx = {
tarball: 'something.tgz',
shasum: 'asdf1234',
installPath: path.join(env.dir, 'versions/1.0.0')
};

return downloadTask(ctx).then(() => {
expect(false, 'Error should have been thrown').to.be.true;
}).catch((error) => {
expect(error.message).to.equal('an error occurred');
expect(downloadStub.calledOnce).to.be.true;
expect(downloadStub.calledWithExactly('something.tgz'));
expect(shasumStub.calledOnce).to.be.true;
expect(shasumStub.calledWithExactly({downloadedData: true})).to.be.true;
expect(decompressStub.calledOnce).to.be.true;
expect(fs.existsSync(ctx.installPath)).to.be.false;
});
});
});
});

0 comments on commit c96a768

Please sign in to comment.