Skip to content

Commit

Permalink
feat(flags): add global dir option
Browse files Browse the repository at this point in the history
Add ability to specify which directory Ghost should run in

refs + closes #538
  • Loading branch information
vikaspotluri123 authored and acburdine committed Jul 13, 2018
1 parent 975049c commit e9ec39a
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 39 deletions.
5 changes: 4 additions & 1 deletion lib/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ const bootstrap = {
// TODO: evaluate if `wrap` is actually needed?
yargs.wrap(Math.min(100, yargs.terminalWidth()))
.epilogue('For more information, see our docs at https://docs.ghost.org/v1/docs/ghost-cli')
.option('D', {
.option('d', {
alias: 'dir',
describe: 'Folder to run command in'
}).option('D', {
alias: 'development',
describe: 'Run in development mode',
type: 'boolean'
Expand Down
46 changes: 36 additions & 10 deletions lib/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,42 @@ class Command {
* @method run
* @private
*/
static _run(commandName, argv, extensions) {
static _run(commandName, argv = {}, extensions) {
debug('running command prep');
// Set process title
process.title = `ghost ${commandName}`;

// Create CLI-wide UI & System instances
const ui = new UI({
verbose: argv.verbose,
allowPrompt: argv.prompt
});

// This needs to run before the installation check
if (argv.dir) {
debug('Directory specified, attempting to update');
const path = require('path');
const dir = path.resolve(argv.dir);
try {
if (this.ensureDir) {
const {ensureDirSync} = require('fs-extra');
ensureDirSync(dir);
}

process.chdir(dir);
} catch (error) {
/* istanbul ignore next */
const err = error.message || error.code || error;
ui.log(`Unable to use "${dir}" (error ${err}). Please fix the issue and try again.`, 'red', true);
process.exit(1);
}
/* istanbul ignore next */
// In order to keep the rest of the function from running, chdir / exit is stubbed to
// throw an error in the tests so this line is technically unreachable. Since it's only
// a debug statement, we're not going to worry about it
debug('Finished updating directory');
}

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

Expand All @@ -120,15 +155,6 @@ class Command {
checkRootUser(commandName);
}

// Set process title
process.title = `ghost ${commandName}`;
const verbose = argv.verbose;

// Create CLI-wide UI & System instances
const ui = new UI({
verbose: verbose,
allowPrompt: argv.prompt
});
const system = new System(ui, extensions);

// Set the initial environment based on args or NODE_ENV
Expand Down
9 changes: 1 addition & 8 deletions lib/commands/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@ class InstallCommand extends Command {
const yarnInstall = require('../tasks/yarn-install');
const ensureStructure = require('../tasks/ensure-structure');

// Dir was specified, so we make sure it exists and chdir into it.
if (argv.dir) {
const dir = path.resolve(argv.dir);

fs.ensureDirSync(dir);
process.chdir(dir);
}

let version = argv.version;
const filesInDir = fs.readdirSync(process.cwd());

Expand Down Expand Up @@ -144,5 +136,6 @@ InstallCommand.options = {
}
};
InstallCommand.checkVersion = true;
InstallCommand.ensureDir = true;

module.exports = InstallCommand;
41 changes: 41 additions & 0 deletions test/unit/command-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,47 @@ describe('Unit: Command', function () {
}
});

it('Changes directory if needed', function () {
sinon.stub(process, 'exit').throws(new Error('exit_stub'));
const outStub = sinon.stub(process.stderr, 'write');
const chdirStub = sinon.stub(process, 'chdir').throws(new Error('chdir_stub'));
const Command = require(modulePath);
class TestCommand extends Command {}

try {
TestCommand._run('test', {dir: '/path/to/ghost', verbose: true});
throw new Error('Should have errored');
} catch (error) {
expect(error).to.be.ok;
expect(error.message).to.equal('exit_stub');
expect(chdirStub.calledOnce).to.be.true;
expect(chdirStub.args[0][0]).to.equal('/path/to/ghost');
expect(outStub.calledOnce).to.be.true;
expect(outStub.args[0][0]).to.match(/chdir_stub/);
}
});

it('Creates & changes into directory if needed', function () {
sinon.stub(process.stderr, 'write');
sinon.stub(process, 'exit').throws(new Error('exit_stub'));
sinon.stub(process, 'chdir').throws(new Error('chdir_stub'));
const fs = require('fs-extra');
const fsStub = sinon.stub(fs, 'ensureDirSync');
const Command = require(modulePath);
class TestCommand extends Command {}
TestCommand.ensureDir = true;

try {
TestCommand._run('test', {dir: '/path/to/ghost', verbose: true});
throw new Error('Should have errored');
} catch (error) {
expect(error).to.be.ok;
expect(error.message).to.equal('exit_stub');
expect(fsStub.calledOnce).to.be.true;
expect(fsStub.args[0][0]).to.equal('/path/to/ghost');
}
});

it('loads system and ui dependencies, calls run method', function () {
const uiStub = sinon.stub().returns({ui: true});
const setEnvironmentStub = sinon.stub();
Expand Down
20 changes: 0 additions & 20 deletions test/unit/commands/install-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,6 @@ describe('Unit: Commands > Install', function () {
sinon.restore();
})

it('creates dir and changes into it if --dir option is passed', function () {
const chdirStub = sinon.stub(process, 'chdir').throws();
const ensureDirStub = sinon.stub();

const InstallCommand = proxyquire(modulePath, {
'fs-extra': {ensureDirSync: ensureDirStub}
});
const testInstance = new InstallCommand({}, {});

try {
testInstance.run({dir: '/some/dir'});
} catch (e) {
// ignore error, chdir is supposed to throw the error
expect(ensureDirStub.calledOnce).to.be.true;
expect(ensureDirStub.calledWithExactly('/some/dir')).to.be.true;
expect(chdirStub.calledOnce).to.be.true;
expect(chdirStub.calledWithExactly('/some/dir')).to.be.true;
}
});

it('rejects if directory is not empty', function () {
const readdirStub = sinon.stub().returns([
'.ghost-cli',
Expand Down

0 comments on commit e9ec39a

Please sign in to comment.