Skip to content

Commit

Permalink
refactor(): analyse and update dependency objects
Browse files Browse the repository at this point in the history
  • Loading branch information
JamieMason committed Aug 3, 2016
1 parent 042c1c1 commit eb59448
Show file tree
Hide file tree
Showing 51 changed files with 719 additions and 799 deletions.
30 changes: 0 additions & 30 deletions .gitignore
@@ -1,33 +1,3 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules

# Users Environment Variables
.lock-wscript

npm-debug.log

# Testing artifacts
test/sinopia/storage
54 changes: 4 additions & 50 deletions index.js
@@ -1,55 +1,9 @@
var task = {
init: require('./src/init'),
resolveTarball: require('./src/resolveTarball'),
addToCache: require('./src/addToCache'),
addToBundle: require('./src/addToBundle'),
rewriteGraph: require('./src/rewriteGraph'),
removeFromBundle: require('./src/removeFromBundle')
};
// modules
var analyse = require('./src/analyse');
var update = require('./src/update');

// public
module.exports = {
analyse: analyse,
update: update
};

function analyse (directory) {
return Promise.resolve(task.init(directory));
}

function update (config) {
return resolveTarball()
.then(addToCache, onFail)
.then(addToBundle, onFail)
.then(removeFromBundle, onFail)
.then(rewriteGraph, onFail)
.then(onSuccess, onFail)
.catch(onFail);

function resolveTarball () {
return task.resolveTarball(config.deps.missingAndUnresolved);
}

function addToCache () {
return task.addToCache(config.deps.missingFromCache);
}

function addToBundle () {
return task.addToBundle(config.deps.missingFromBundle);
}

function rewriteGraph () {
return task.rewriteGraph(config.path.graph, config.deps.all, config.graph);
}

function removeFromBundle () {
return task.removeFromBundle(config.deps.removeFromBundle);
}

function onSuccess () {
return config;
}

function onFail (err) {
return Promise.reject(err);
}
}
27 changes: 0 additions & 27 deletions src/addToBundle.js

This file was deleted.

22 changes: 0 additions & 22 deletions src/addToCache.js

This file was deleted.

@@ -1,20 +1,19 @@
// 3rd party modules
var fs = require('graceful-fs');
var whenNode = require('when/node');
// modules
var fs = require('../lib/fs');

// public
module.exports = createBundleDirectory;

// implementation
function createBundleDirectory (location) {
return whenNode.call(fs.mkdir, location)
function createBundleDirectory(location) {
return fs.mkdir(location)
.then(onSuccess, onError);

function onSuccess () {
function onSuccess() {
return location;
}

function onError (err) {
function onError(err) {
if (err.code !== 'EEXIST') {
throw new Error('! failed to create node_shrinkwrap directory');
}
Expand Down
19 changes: 19 additions & 0 deletions src/analyse/dependency/bundle.js
@@ -0,0 +1,19 @@
// modules
var copyFile = require('../../lib/copy-file');

// public
module.exports = bundle;

// implementation
function bundle(dependency) {
return copyFile(dependency.getPathToNpmCache(), dependency.getPathToBundle())
.then(onSuccess, onError);

function onSuccess() {
return dependency;
}

function onError() {
throw new Error('! failed to shrinkpack ' + dependency.getId());
}
}
19 changes: 19 additions & 0 deletions src/analyse/dependency/cache.js
@@ -0,0 +1,19 @@
// modules
var childProcess = require('../../lib/child-process');

// public
module.exports = cache;

// implementation
function cache(dependency) {
return childProcess.exec('npm cache --scope=' + dependency.getScope() + ' add ' + dependency.graph.resolved, {encoding: 'utf8'})
.then(onSuccess, onError);

function onSuccess() {
return dependency;
}

function onError() {
throw new Error('! failed to download ' + dependency.getId());
}
}
98 changes: 98 additions & 0 deletions src/analyse/dependency/index.js
@@ -0,0 +1,98 @@
// node modules
var path = require('path');

// 3rd party modules
var chalk = require('chalk');
var when = require('when');

// modules
var bundle = require('./bundle');
var cache = require('./cache');
var resolve = require('./resolve');

// public
module.exports = Dependency;

// implementation
function Dependency(name, graph) {
this.graph = graph;
this.name = name;
}

// statics
Dependency.setConfig = function (config) {
Dependency.prototype.config = config;
};

// shared
Dependency.prototype = {
bundle: function () {
if (!this.isBundled()) {
return bundle(this).then(function (dependency) {
console.info(chalk.green('+ %s'), dependency.getId());
return dependency;
});
}
return when(this);
},
cache: function () {
if (!this.isCached() && !this.isBundled()) {
return cache(this).then(function (dependency) {
console.info(chalk.yellow('↓ %s from %s'), dependency.getId(), dependency.graph.resolved);
return dependency;
});
}
return when(this);
},
config: null,
getId: function () {
return this.name + '@' + this.graph.version;
},
getPathToBundle: function () {
var directory = this.config.path.shrinkpack;
var name = this.name.replace(/\//g, '-');
var version = this.graph.version;
return path.join(directory, name + '-' + version + '.tgz');
},
getPathToNpmCache: function () {
return path.join(this.config.path.npmCache, this.name, this.graph.version, 'package.tgz');
},
getScope: function () {
var scope = this.name.substring(0, this.name.indexOf('/'));
return scope === this.name ? '' : scope;
},
isBundled: function () {
return this.getPathToBundle() in this.config.bundle;
},
isCached: function () {
return this.getPathToNpmCache() in this.config.npmCache;
},
isResolved: function () {
return Boolean(this.graph.resolved);
},
resolve: function () {
if (!this.isResolved()) {
return resolve(this).then(function (dependency) {
console.info(chalk.green('✓ set missing "resolved" property for %s to %s'), dependency.getId(), dependency.graph.resolved);
return dependency;
});
}
return when(this);
},
rewriteGraph: function () {
var relative = path.relative(this.config.path.project, this.getPathToBundle());
this.graph.resolved = './' + relative.split('\\').join('/');
return when(this);
},
synchronise: function () {
return when(this)
.then(this.resolve.bind(this))
.then(this.cache.bind(this))
.then(this.bundle.bind(this))
.then(this.rewriteGraph.bind(this))
.catch(function (err) {
console.error(chalk.red('! failed to resolve tarball for %s'), this.getId());
console.error(err);
}.bind(this));
}
};
24 changes: 24 additions & 0 deletions src/analyse/dependency/resolve.js
@@ -0,0 +1,24 @@
// modules
var childProcess = require('../../lib/child-process');

// public
module.exports = resolve;

// implementation
function resolve(dependency) {
return childProcess.exec('npm view ' + dependency.getId() + ' --json', {encoding: 'utf8'})
.then(onSuccess, onError);

function onSuccess(res) {
var json = JSON.parse(res.join(''));
if (json && json.dist && json.dist.tarball) {
dependency.graph.resolved = json.dist.tarball;
return dependency;
}
throw new Error('! ' + dependency.getId() + ' has no "dist.tarball" in `npm view ' + dependency.getId() + ' --json`');
}

function onError() {
throw new Error('! failed to call `npm view ' + dependency.getId() + ' --json`');
}
}
19 changes: 19 additions & 0 deletions src/analyse/get-dependencies.js
@@ -0,0 +1,19 @@
// 3rd party modules
var when = require('when');

// modules
var forEachNestedDependency = require('../lib/for-each-nested-dependency');
var Dependency = require('./dependency');

// public
module.exports = getDependencies;

// implementation
function getDependencies(config) {
Dependency.setConfig(config);
var dependencies = [];
forEachNestedDependency(config.graph, function (name, graph) {
dependencies.push(new Dependency(name, graph));
});
return when(dependencies);
}
19 changes: 19 additions & 0 deletions src/analyse/get-graph.js
@@ -0,0 +1,19 @@
// modules
var fs = require('../lib/fs');

// public
module.exports = getGraph;

// implementation
function getGraph(location) {
return fs.readFile(location, {encoding: 'utf8'})
.then(onSuccess, onError);

function onSuccess(graph) {
return JSON.parse(graph);
}

function onError() {
throw new Error('! npm-shrinkwrap.json is missing, create it using `npm shrinkwrap --dev` then try again');
}
}
19 changes: 19 additions & 0 deletions src/analyse/get-npm-version.js
@@ -0,0 +1,19 @@
// modules
var childProcess = require('../lib/child-process');

// public
module.exports = getNpmVersion;

// implementation
function getNpmVersion() {
return childProcess.exec('npm --version', {encoding: 'utf8'})
.then(onSuccess, onError);

function onSuccess(npmVersion) {
return npmVersion.join('').trim();
}

function onError() {
throw new Error('! failed to determine version of npm');
}
}

0 comments on commit eb59448

Please sign in to comment.