Skip to content

Commit

Permalink
Merge 5ade955 into 4df32ed
Browse files Browse the repository at this point in the history
  • Loading branch information
vikaspotluri123 committed Jan 23, 2020
2 parents 4df32ed + 5ade955 commit 8d02833
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 69 deletions.
5 changes: 3 additions & 2 deletions lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,10 @@ class Command {
}

if (!this.global) {
const checkValidInstall = require('./utils/check-valid-install');
const findValidInstall = require('./utils/find-valid-install');

checkValidInstall(commandName);
// NOTE: we disable recursive searching when the cwd is supplied
findValidInstall(commandName, !argv.dir);
}

if (!this.allowRoot) {
Expand Down
27 changes: 14 additions & 13 deletions lib/utils/check-valid-install.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const chalk = require('chalk');
* directory contains a development install of ghost (e.g. a git clone), and outputs
* a helpful error message if so.
*
* @param {string} name Name of command, will be output if there's an error
* @param {string} name Name of command, will be output if there's an issue
* @returns {bool | null} If the directory contains a valid installation. Returns null for non-deterministic results
*/
function checkValidInstall(name) {
/*
Expand All @@ -21,34 +22,34 @@ function checkValidInstall(name) {
If you are trying to upgrade Ghost LTS to 1.0.0, refer to ${chalk.blue.underline('https://ghost.org/faq/upgrade-to-ghost-1-0/')}.
Otherwise, run \`ghost ${name}\` again within a valid Ghost installation.`);

process.exit(1);
return false;
}

/*
* We assume it's a Ghost development install if 3 things are true:
* 1) package.json exists
* 2) package.json "name" field is "ghost"
* 3) Gruntfile.js exists
*/
* We assume it's a Ghost development install if 3 things are true:
* 1) package.json exists
* 2) package.json "name" field is "ghost"
* 3) Gruntfile.js exists
*/
if (fs.existsSync(path.join(process.cwd(), 'package.json')) &&
fs.readJsonSync(path.join(process.cwd(), 'package.json')).name === 'ghost' &&
fs.existsSync(path.join(process.cwd(), 'Gruntfile.js'))) {
fs.existsSync(path.join(process.cwd(), 'Gruntfile.js'))
) {
console.error(`${chalk.yellow('Ghost-CLI commands do not work inside of a git clone, zip download or with Ghost <1.0.0.')}
Perhaps you meant \`grunt ${name}\`?
Otherwise, run \`ghost ${name}\` again within a valid Ghost installation.`);

process.exit(1);
return false;
}

/*
* Assume it's not a valid CLI install if the `.ghost-cli` file doesn't exist
*/
if (!fs.existsSync(path.join(process.cwd(), '.ghost-cli'))) {
console.error(`${chalk.yellow('Working directory is not a recognisable Ghost installation.')}
Run \`ghost ${name}\` again within a folder where Ghost was installed with Ghost-CLI.`);

process.exit(1);
return null;
}

return true;
}

module.exports = checkValidInstall;
38 changes: 38 additions & 0 deletions lib/utils/find-valid-install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const {dirname} = require('path');
const debug = require('debug')('ghost-cli:find-instance');
const chalk = require('chalk');
const checkValidInstall = require('./check-valid-install');

const isRoot = () => dirname(process.cwd()) === process.cwd();

const die = name => {
console.error(`${chalk.yellow('Working directory is not a recognisable Ghost installation.')}
Run \`ghost ${name}\` again within a folder where Ghost was installed with Ghost-CLI.`);
process.exit(1);
}

function findValidInstallation(name = '', recursive = false) {
while (!isRoot()) {
debug(`Checking valid install: ${process.cwd()}`);
const isValidInstall = checkValidInstall(name);

if (isValidInstall) {
return;
}

if (isValidInstall === false) {
process.exit(1);
}

if (!recursive) {
return die(name);
}

debug(`Going up...`);
process.chdir('..');
}

die(name);
}

module.exports = findValidInstallation;
16 changes: 8 additions & 8 deletions test/unit/command-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,22 +178,22 @@ describe('Unit: Command', function () {
});

describe('_run', function () {
it('calls checkValidInstall when global option is not set', async function () {
const checkValidInstall = sinon.stub();
it('calls findValidInstall when global option is not set', async function () {
const findValidInstall = sinon.stub();
const Command = proxyquire(modulePath, {
'./utils/check-valid-install': checkValidInstall
'./utils/find-valid-install': findValidInstall
});

const TestCommand = class extends Command {};
checkValidInstall.throws();
findValidInstall.throws();

try {
await TestCommand._run('test', {});
throw new Error('checkValidInstall not called');
throw new Error('findValidInstall not called');
} catch (e) {
expect(e.message).to.not.equal('checkValidInstall not called');
expect(checkValidInstall.calledOnce).to.be.true;
expect(checkValidInstall.args[0][0]).to.equal('test');
expect(e.message).to.not.equal('findValidInstall not called');
expect(findValidInstall.calledOnce).to.be.true;
expect(findValidInstall.args[0][0]).to.equal('test');
}
});

Expand Down
65 changes: 19 additions & 46 deletions test/unit/utils/check-valid-install-spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
'use strict';
// @ts-check

const expect = require('chai').expect;
const sinon = require('sinon');
Expand All @@ -11,27 +11,20 @@ describe('Unit: Utils > checkValidInstall', function () {
sinon.restore();
});

it('throws error if config.js present', function () {
it('fails when config.js present', function () {
const existsStub = sinon.stub(fs, 'existsSync');
existsStub.withArgs(sinon.match(/config\.js/)).returns(true);

const exitStub = sinon.stub(process, 'exit').throws();
const errorStub = sinon.stub(console, 'error');

try {
checkValidInstall('test');
throw new Error('should not be thrown');
} catch (e) {
expect(e.message).to.not.equal('should not be thrown');
expect(existsStub.calledOnce).to.be.true;
expect(errorStub.calledOnce).to.be.true;
expect(exitStub.calledOnce).to.be.true;
expect(existsStub.args[0][0]).to.match(/config\.js/);
expect(errorStub.args[0][0]).to.match(/Ghost-CLI only works with Ghost versions >= 1\.0\.0/);
}
expect(checkValidInstall('test')).to.equal(false);
expect(existsStub.calledOnce).to.be.true;
expect(errorStub.calledOnce).to.be.true;
expect(existsStub.args[0][0]).to.match(/config\.js/);
expect(errorStub.args[0][0]).to.match(/Ghost-CLI only works with Ghost versions >= 1\.0\.0/);
});

it('throws error if within a Ghost git clone', function () {
it('fails within a Ghost git clone', function () {
const existsStub = sinon.stub(fs, 'existsSync');
const readJsonStub = sinon.stub(fs, 'readJsonSync');

Expand All @@ -40,58 +33,38 @@ describe('Unit: Utils > checkValidInstall', function () {
existsStub.withArgs(sinon.match(/Gruntfile\.js/)).returns(true);
readJsonStub.returns({name: 'ghost'});

const exitStub = sinon.stub(process, 'exit').throws();
const errorStub = sinon.stub(console, 'error');

try {
checkValidInstall('test');
throw new Error('should not be thrown');
} catch (e) {
expect(e.message).to.not.equal('should not be thrown');
expect(existsStub.calledThrice).to.be.true;
expect(errorStub.calledOnce).to.be.true;
expect(exitStub.calledOnce).to.be.true;
expect(existsStub.args[1][0]).to.match(/package\.json/);
expect(errorStub.args[0][0]).to.match(/Ghost-CLI commands do not work inside of a git clone/);
}
expect(checkValidInstall('test')).to.equal(false);
expect(existsStub.calledThrice).to.be.true;
expect(errorStub.calledOnce).to.be.true;
expect(existsStub.args[1][0]).to.match(/package\.json/);
expect(errorStub.args[0][0]).to.match(/Ghost-CLI commands do not work inside of a git clone/);
});

it('throws error if above two conditions don\'t exit and .ghost-cli file is missing', function () {
it('neither passes nor fails when .ghost-cli file is missing', function () {
const existsStub = sinon.stub(fs, 'existsSync');

existsStub.withArgs(sinon.match(/config\.js/)).returns(false);
existsStub.withArgs(sinon.match(/package\.json/)).returns(false);
existsStub.withArgs(sinon.match(/\.ghost-cli/)).returns(false);

const exitStub = sinon.stub(process, 'exit').throws();
const errorStub = sinon.stub(console, 'error');

try {
checkValidInstall('test');
throw new Error('should not be thrown');
} catch (e) {
expect(e.message).to.not.equal('should not be thrown');
expect(existsStub.calledThrice).to.be.true;
expect(errorStub.calledOnce).to.be.true;
expect(exitStub.calledOnce).to.be.true;
expect(existsStub.args[2][0]).to.match(/\.ghost-cli/);
expect(errorStub.args[0][0]).to.match(/Working directory is not a recognisable Ghost installation/);
}
expect(checkValidInstall('test')).to.equal(null);
expect(existsStub.calledThrice).to.be.true;
expect(existsStub.args[2][0]).to.match(/\.ghost-cli/);
});

it('doesn\'t do anything if all conditions return false', function () {
it('passes in "valid" installation', function () {
const existsStub = sinon.stub(fs, 'existsSync');

existsStub.withArgs(sinon.match(/config\.js/)).returns(false);
existsStub.withArgs(sinon.match(/package\.json/)).returns(false);
existsStub.withArgs(sinon.match(/\.ghost-cli/)).returns(true);

const exitStub = sinon.stub(process, 'exit').throws();
const errorStub = sinon.stub(console, 'error');

checkValidInstall('test');
expect(checkValidInstall('test')).to.equal(true);
expect(existsStub.calledThrice).to.be.true;
expect(errorStub.called).to.be.false;
expect(exitStub.called).to.be.false;
});
});

0 comments on commit 8d02833

Please sign in to comment.