Skip to content

Commit

Permalink
Merge pull request #34 from nkbt/find-local
Browse files Browse the repository at this point in the history
[#33] Search for packages locally
  • Loading branch information
Eric Elliott committed Sep 1, 2015
2 parents 781c0f3 + a2bd751 commit df7e3d8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 48 deletions.
7 changes: 5 additions & 2 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
import 'babel/polyfill';
import nomnom from 'nomnom';
import cloverfield from './cloverfield';
import findScaffolds from './find-scaffolds';
import {findGlobal, findLocal} from './find-scaffolds';
import buildCommand from './commands/build';
import npm from 'npm';


const parser = nomnom();


Promise.all([
findScaffolds()
Promise.all([findLocal(npm)(), findGlobal(npm)()])
.catch(console.error.bind(console))
// Prefer local packages over global
.then(([local, global]) => ({...global, ...local}))
.then(buildCommand)
])
.then(cloverfield(parser))
Expand Down
10 changes: 8 additions & 2 deletions lib/commands/build.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import path from 'path';

export default scaffolds => {
const command = 'build';

Expand All @@ -12,8 +14,12 @@ export default scaffolds => {
}
};

const callback = ({scaffold, ...opts}) =>
require(scaffolds[scaffold])(opts);
const callback = ({scaffold, ...opts}) => {
const packageJson = require(path.join(scaffolds[scaffold], 'package.json'));
const cli = require(path.join(scaffolds[scaffold], packageJson.main));

return cli(opts);
};

const help = 'Build a new package from a Cloverfield scaffold';

Expand Down
21 changes: 11 additions & 10 deletions lib/find-scaffolds.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import npm from 'npm';


const isScaffold = ({keywords = [], name = ''}) =>
const isScaffold = ({keywords = [], name}) => name && (
name.substr(0, 3) === 'cf-' ||
keywords.indexOf('cloverfield-scaffold') !== -1 ||
keywords.indexOf('cloverfield') !== -1 && keywords.indexOf('scaffold') !== -1;
keywords.indexOf('cloverfield') !== -1 && keywords.indexOf('scaffold') !== -1
);


const modulesReady = (resolve, reject) => (error, tree) => {
Expand All @@ -23,7 +21,7 @@ const modulesReady = (resolve, reject) => (error, tree) => {
};


const loaded = (resolve, reject) => (error) => {
const loaded = npm => (resolve, reject) => (error) => {
if (error) {
return reject(error);
}
Expand All @@ -34,9 +32,12 @@ const loaded = (resolve, reject) => (error) => {


// TODO: add caching
const findScaffolds = () =>
// Configure npm to search for dependencies globally with minimal depth
new Promise((...args) => npm.load({global: true, silent: true, depth: 0}, loaded(...args)));
const findScaffolds = npm => options => () =>
// Configure npm to search for dependencies globally or locally with minimal depth
new Promise((...args) => npm.load({silent: true, depth: 0, ...options}, loaded(npm)(...args)));


export const findLocal = npm => findScaffolds(npm)({global: false});


export default findScaffolds;
export const findGlobal = npm => findScaffolds(npm)({global: true});
86 changes: 52 additions & 34 deletions test/lib/find-scaffolds.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import test from 'blue-tape';
import npm from 'npm';
import {stub, spy} from 'sinon';
import {spy} from 'sinon';


import findScaffolds from '../../lib/find-scaffolds';
import {findLocal, findGlobal} from '../../lib/find-scaffolds';


const dependencies = {
Expand Down Expand Up @@ -36,45 +35,67 @@ const dependencies = {
name: 'incorrectly-tagged',
realPath: 'incorrectly-tagged realpath',
keywords: ['cloverfield', 'something else']
},
packageWithoutName: {
// should skip this because it does not have a name
realPath: 'package-without-name realpath',
keywords: ['cloverfield', 'scaffold']
}
};


const before = () => {
// Stubs
const load = spy();

stub(npm, 'load', load);
npm.commands = {
ls: spy()
const mockNpm = () => {
const npm = {
load: spy(),
commands: {
ls: spy()
}
};

return {load};
return {npm};
};


const after = () => {
npm.load.restore();
};
test('Find Scaffolds API', assert => {
const {npm} = mockNpm();

assert.ok(findGlobal(npm) instanceof Function, 'should be function');
assert.ok(findGlobal(npm)() instanceof Promise, 'should return Promise');

assert.end();
});


test('Find Scaffolds success', assert => {
test('Search for global Scaffolds', assert => {
const {npm} = mockNpm();

const {load} = before();
findGlobal(npm)();
assert.equal(npm.load.getCall(0).args[0].global, true, 'should call npm.init with global flag');

assert.ok(findScaffolds instanceof Function, 'should be function');
assert.end();
});


const promise = findScaffolds();
test('Search for local Scaffolds', assert => {
const {npm} = mockNpm();

assert.ok(promise instanceof Promise, 'should return Promise');
findLocal(npm)();
assert.equal(npm.load.getCall(0).args[0].global,
false,
'should call npm.init without global flag');

assert.end();
});


assert.ok(load.calledOnce, 'npm.init should be called');
test('Finding Scaffolds', assert => {
const {npm} = mockNpm();
const promise = findGlobal(npm)();

assert.ok(npm.load.calledOnce, 'npm.init should be called');

// Emulate successfull load response
const loadCallback = load.getCall(0).args[1];
// Emulate successful load response
const loadCallback = npm.load.getCall(0).args[1];

loadCallback(null);

Expand All @@ -90,15 +111,14 @@ test('Find Scaffolds success', assert => {
assert.ok(scaffolds, 'find-scaffold should resolve with found scaffolds');
assert.deepEqual(Object.keys(scaffolds), ['test', 'tagged1', 'tagged2'],
'should return correctly matched scaffolds');
})
.then(after);
});
});


test('Find Scaffolds fail on npm.init', assert => {
const {load} = before();
const promise = findScaffolds();
const loadCallback = load.getCall(0).args[1];
const {npm} = mockNpm();
const promise = findGlobal(npm)();
const loadCallback = npm.load.getCall(0).args[1];


loadCallback(new Error('Oops'));
Expand All @@ -108,15 +128,14 @@ test('Find Scaffolds fail on npm.init', assert => {
.catch(error => {
assert.ok(error instanceof Error, 'should reject with Error');
assert.equal(error.message, 'Oops', 'should pass-through error message');
})
.then(after);
});
});


test('Find Scaffolds fail on npm.commands.ls', assert => {
const {load} = before();
const promise = findScaffolds();
const loadCallback = load.getCall(0).args[1];
const {npm} = mockNpm();
const promise = findGlobal(npm)();
const loadCallback = npm.load.getCall(0).args[1];

loadCallback(null);

Expand All @@ -129,6 +148,5 @@ test('Find Scaffolds fail on npm.commands.ls', assert => {
.catch(error => {
assert.ok(error instanceof Error, 'should reject with Error');
assert.equal(error.message, 'Oops', 'should pass-through error message');
})
.then(after);
});
});

0 comments on commit df7e3d8

Please sign in to comment.