Skip to content

Commit

Permalink
Merge 3a061ef into d5cb825
Browse files Browse the repository at this point in the history
  • Loading branch information
yoitsro committed Dec 16, 2018
2 parents d5cb825 + 3a061ef commit c3657bd
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 28 deletions.
5 changes: 3 additions & 2 deletions bin/pckr.js
Expand Up @@ -13,8 +13,9 @@ program

program
.command('pack')
.action(function () {
const pckr = new Pckr(process.cwd());
.option('-p, --production', 'Only install production dependencies')
.action(function (cmd) {
const pckr = new Pckr(process.cwd(), cmd.production);
pckr.pack();
});

Expand Down
26 changes: 22 additions & 4 deletions src/Module/Dependencies/index.js
Expand Up @@ -10,6 +10,12 @@ const isSymlink = path =>
const isDirectory = src =>
fs.statSync(src).isDirectory();

const getPackageName = modulePath => {
const package = fs.readFileSync(path.resolve(modulePath, 'package.json'));
const packageJson = JSON.parse(package);
return packageJson.name;
};

const getSubDirsOfFolder = folder =>
fs.readdirSync(folder)
.map(subdir => path.resolve(folder, subdir))
Expand Down Expand Up @@ -44,10 +50,22 @@ class Dependencies {
return [];
}

getSymlinked() {
return this.get()
.filter(path => isSymlink(path));
getSymlinked(packageJson) {
let productionDependencies;
if (packageJson) {
productionDependencies = Object.keys(packageJson.getDependencies() || {});
}

const symlinked = this.get().filter(path => isSymlink(path));

if (productionDependencies) {
return symlinked.filter(path =>
productionDependencies.includes(getPackageName(path))
);
}

return symlinked;
}
};
}

module.exports = Dependencies;
4 changes: 4 additions & 0 deletions src/Module/PackageJson/index.js
Expand Up @@ -20,6 +20,10 @@ class PackageJson {
return this._packageJson.version;
}

getDependencies() {
return this._packageJson.dependencies;
}

updateScripts(scripts) {
this._packageJson.scripts = Object.keys(scripts)
.reduce((existingScripts, key) => {
Expand Down
7 changes: 4 additions & 3 deletions src/Module/index.js
Expand Up @@ -10,8 +10,8 @@ const pckrPckr = require('../pckrPckr');
const buildModuleDependenciesTree = (m, level = 1) => ({
module: m,
level: level,
deps: m.dependencies.getSymlinked()
.map(location => new Module(location))
deps: m.dependencies.getSymlinked(m.prodOnly ? m.packageJson : false)
.map(location => new Module(location, false, m.prodOnly))
.map(m => buildModuleDependenciesTree(m, level + 1))
});

Expand Down Expand Up @@ -43,9 +43,10 @@ const sortByLevelInFileNameAscending = (a, b) => {
};

class Module {
constructor(location, root = false) {
constructor(location, root = false, prodOnly = false) {
this.location = location;
this.root = root;
this.prodOnly = prodOnly;
this.packageJson = new PackageJson(location);
this.dependencies = new Dependencies(location);
this.symlinkDirectory = new SymlinkDirectory(location);
Expand Down
4 changes: 2 additions & 2 deletions src/Pckr.js
Expand Up @@ -2,8 +2,8 @@ const pckrPckr = require('./pckrPckr');
const Module = require('./Module');

class Pckr {
constructor(location) {
this.module = new Module(location, true);
constructor(location, prodOnly = false) {
this.module = new Module(location, true, prodOnly);
}

pack() {
Expand Down
20 changes: 20 additions & 0 deletions test/integration/Dependencies.spec.js
Expand Up @@ -14,6 +14,26 @@ test('Dependencies - getSymlinked - retrieves symlinked modules - II', t => {
const twoModulePath = path.resolve(__dirname, 'test-project', 'packages', 'two');
const d = new Dependencies(twoModulePath);
t.deepEqual(d.getSymlinked().sort(), [
path.resolve(twoModulePath, 'node_modules', '@nsp', 'four-x-x'),
path.resolve(twoModulePath, 'node_modules', 'five-x-x'),
path.resolve(twoModulePath, 'node_modules', 'six-x-x'),
path.resolve(twoModulePath, 'node_modules', 'three-x-x')
]);
});

test('Dependencies - getSymlinked - retrieves symlinked production modules', t => {
const twoModulePath = path.resolve(__dirname, 'test-project', 'packages', 'two');
const d = new Dependencies(twoModulePath);
const p = {
getDependencies: () => ({
"@nsp/four-x-x": "*",
"left-pad": "^1.2.0",
"three-x-x": "*",
"five-x-x": "*"
})
};

t.deepEqual(d.getSymlinked(p).sort(), [
path.resolve(twoModulePath, 'node_modules', '@nsp', 'four-x-x'),
path.resolve(twoModulePath, 'node_modules', 'five-x-x'),
path.resolve(twoModulePath, 'node_modules', 'three-x-x')
Expand Down
11 changes: 11 additions & 0 deletions test/integration/Pckr.pack.spec.js
Expand Up @@ -51,6 +51,17 @@ test('Pckr - pack - includes all symlinked dependencies in correct order', async
const packedPath = await p.pack(TO_LOCATION);
const extracted = untar(packedPath);
t.truthy(hasPackagedSubModule(extracted, '0\.five-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '1\.six-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '2\.three-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '3\.nsp-four-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '4\.two-x-x-1\.0\.0\.tgz'));
});

test('Pckr - pack - includes all production symlinked dependencies in correct order', async t => {
const p = new Pckr(MODULE_TO_PACK, true);
const packedPath = await p.pack(TO_LOCATION);
const extracted = untar(packedPath);
t.truthy(hasPackagedSubModule(extracted, '0\.five-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '1\.three-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '2\.nsp-four-x-x-1\.0\.0\.tgz'));
t.truthy(hasPackagedSubModule(extracted, '3\.two-x-x-1\.0\.0\.tgz'));
Expand Down
1 change: 1 addition & 0 deletions test/integration/test-project/packages/six/index.js
@@ -0,0 +1 @@
module.exports = () => ['six'];
11 changes: 11 additions & 0 deletions test/integration/test-project/packages/six/package.json
@@ -0,0 +1,11 @@
{
"name": "six-x-x",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
3 changes: 3 additions & 0 deletions test/integration/test-project/packages/two/package.json
Expand Up @@ -12,6 +12,9 @@
"three-x-x": "*",
"five-x-x": "*"
},
"devDependencies": {
"six-x-x": "*"
},
"author": "",
"license": "ISC"
}
9 changes: 9 additions & 0 deletions test/unit/Module/PackageJson/index.spec.js
Expand Up @@ -198,3 +198,12 @@ test('PackageJson - getVersion - returns version from modules package.json', t =
const pj = new PackageJson(c.location);
t.is(pj.getVersion(), '2.2.2');
});

test('PackageJson - getVersion - returns name from modules package.json', t => {
const packageJson = {
dependencies: { lotsof: 'deps' }
};
const { stubs, PackageJson, c } = setupStubs(t.context, packageJson);
const pj = new PackageJson(c.location);
t.deepEqual(pj.getDependencies(), { lotsof: 'deps' });
});
22 changes: 22 additions & 0 deletions test/unit/Module/index.spec.js
Expand Up @@ -161,6 +161,17 @@ test('Module - constructor - non-root', t => {
t.is(p.packageJson, c.tree.data.stubs.packageJson);
});

test('Module - constructor - root production only', t => {
const { Module, stubs, c } = t.context;
const p = new Module(c.tree.data.name, true, true);
t.is(p.location, c.tree.data.name);
t.is(p.root, true);
t.is(p.prodOnly, true);
t.is(p.dependencies, c.tree.data.stubs.dependencies);
t.is(p.symlinkDirectory, c.tree.data.stubs.symlinkDirectory);
t.is(p.packageJson, c.tree.data.stubs.packageJson);
});

test('Module - pack - root - creates symlink directory', async t => {
t.plan(0);
const { Module, stubs, c } = t.context;
Expand Down Expand Up @@ -200,6 +211,17 @@ test('Module - pack - root - adds downstream symlink dependencies, excluding dup
td.verify(p.symlinkDirectory.addFile('a/d/d-0.0.0.tgz', '2.d-0.0.0.tgz'));
td.verify(p.symlinkDirectory.addFile(td.matchers.isA(String), td.matchers.isA(String)), { times: 3 });
});

test('Module - pack - root - adds downstream symlink dependencies, excluding duplicates, with correct ordered names to symlink directory - production only', async t => {
t.plan(0);
const { Module, stubs, c } = t.context;
const p = new Module(c.tree.data.name, true, true);
await p.pack();
td.verify(p.symlinkDirectory.addFile('a/b/c/c-0.0.0.tgz', '0.c-0.0.0.tgz'));
td.verify(p.symlinkDirectory.addFile('a/b/b-0.0.0.tgz', '1.b-0.0.0.tgz'));
td.verify(p.symlinkDirectory.addFile('a/d/d-0.0.0.tgz', '2.d-0.0.0.tgz'));
td.verify(p.symlinkDirectory.addFile(td.matchers.isA(String), td.matchers.isA(String)), { times: 3 });
});
//
test('Module - pack - root - remove each symlinked dependency from package json', async t => {
t.plan(0);
Expand Down
42 changes: 25 additions & 17 deletions test/unit/Pckr.spec.js
@@ -1,19 +1,19 @@
const test = require('ava');
const td = require('testdouble');
const test = require("ava");
const td = require("testdouble");

const setup = () => {
td.config({
ignoreWarnings: true
});

const stubs = {
pckrPckr: td.replace('../../src/pckrPckr'),
Module: td.replace('../../src/Module')
pckrPckr: td.replace("../../src/pckrPckr"),
Module: td.replace("../../src/Module")
};

td.when(stubs.pckrPckr.pack()).thenReturn();

const Pckr = require('../../src/Pckr');
const Pckr = require("../../src/Pckr");

return { stubs, Pckr };
};
Expand All @@ -22,7 +22,7 @@ const teardown = () => {
td.config({
ignoreWarnings: false
});
td.reset()
td.reset();
};

test.beforeEach(t => {
Expand All @@ -31,45 +31,53 @@ test.beforeEach(t => {

test.afterEach.always(teardown);

test('Pckr - constructor', t => {
test("Pckr - constructor", t => {
const { Pckr, stubs } = t.context;
const location = 'a/a/f';
const location = "a/a/f";
const p = new Pckr(location);
td.verify(new stubs.Module(location, true))
td.verify(new stubs.Module(location, true, false));
t.truthy(p.module instanceof stubs.Module);
});

test('Pckr - pack - packs pckr', async t => {
test("Pckr - constructor with production only", t => {
const { Pckr, stubs } = t.context;
const location = "a/a/f";
const p = new Pckr(location, true);
td.verify(new stubs.Module(location, true, true));
t.truthy(p.module instanceof stubs.Module);
});

test("Pckr - pack - packs pckr", async t => {
t.plan(0);
const { Pckr, stubs } = t.context;
const location = 'a/a/f';
const location = "a/a/f";
const p = new Pckr(location);
await p.pack();
td.verify(stubs.pckrPckr.pack());
});

test('Pckr - pack - packs module', async t => {
test("Pckr - pack - packs module", async t => {
t.plan(0);
const { Pckr, stubs } = t.context;
const location = 'a/a/f';
const location = "a/a/f";
const p = new Pckr(location);
await p.pack();
td.verify(stubs.Module.prototype.pack());
});

test('Pckr - pack - remove pckr', async t => {
test("Pckr - pack - remove pckr", async t => {
t.plan(0);
const { Pckr, stubs } = t.context;
const location = 'a/a/f';
const location = "a/a/f";
const p = new Pckr(location);
await p.pack();
td.verify(stubs.pckrPckr.remove());
});

test('Pckr - pack - installs module', t => {
test("Pckr - pack - installs module", t => {
t.plan(0);
const { Pckr, stubs } = t.context;
const location = 'a/a/f';
const location = "a/a/f";
const p = new Pckr(location);
p.install();
td.verify(stubs.Module.prototype.install());
Expand Down

0 comments on commit c3657bd

Please sign in to comment.