Files
bower/lib/commands/cache-clean.js

162 lines
4.3 KiB
JavaScript

// ==========================================
// BOWER: CacheClean API
// ==========================================
// Copyright 2012 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
var Emitter = require('events').EventEmitter;
var async = require('async');
var nopt = require('nopt');
var rimraf = require('rimraf');
var path = require('path');
var glob = require('glob');
var fs = require('fs');
var _ = require('lodash');
var help = require('./help');
var config = require('../core/config');
var template = require('../util/template');
var fileExists = require('../util/file-exists');
var optionTypes = { help: Boolean };
var shorthand = { 'h': ['--help'] };
var processCachedPackage = function (emitter, pkg, next) {
removeCachedPackage(pkg, function (err, exists) {
if (err) {
emitter.emit('error', err);
return next();
}
if (exists) {
template('action', { name: 'cache cleared', shizzle: pkg })
.on('data', emitter.emit.bind(emitter, 'data'));
}
next();
});
};
var removeCachedPackage = function (pkg, next) {
var folder = path.join(config.cache, pkg);
fileExists(folder, function (exists) {
if (!exists) return next(null, false);
rimraf(folder, function (err) {
if (err) return next(err);
next(null, true);
});
});
};
var processLinkedPackage = function (emitter, pkg, next) {
checkAndRemoveLinkToPackage(pkg, function (err, removed) {
if (err) {
emitter.emit('error', err);
return next();
}
if (removed) {
template('action', { name: 'link cleared', shizzle: pkg })
.on('data', emitter.emit.bind(emitter, 'data'));
}
next();
});
};
var checkAndRemoveLinkToPackage = function (pkg, next) {
var folder = path.join(config.links, pkg);
fs.readlink(folder, function (err, linkString) {
if (err && err.code === 'ENOENT') return next();
fileExists(linkString, function (exists) {
if (!exists) {
return rimraf(folder, function (err) {
if (err) return next(err);
next(null, true);
});
}
next(null, false);
});
});
};
module.exports = function (pkgs) {
var emitter = new Emitter;
async.parallel({
cache: function (next) {
if (!pkgs || !pkgs.length) {
glob('./*', { cwd: config.cache }, function (err, dirs) {
if (err) {
emitter.emit('error', err);
return next();
}
var pkgs = dirs.map(function (dir) { return dir.replace(/^\.\//, ''); });
async.forEach(pkgs, processCachedPackage.bind(this, emitter), next);
});
} else {
pkgs = _.uniq(pkgs);
async.forEach(pkgs, processCachedPackage.bind(this, emitter), next);
}
},
links: function (next) {
if (!pkgs || !pkgs.length) {
glob('./*', { cwd: config.links }, function (err, dirs) {
if (err) {
emitter.emit('error', err);
return next();
}
var pkgs = dirs.map(function (dir) { return dir.replace(/^\.\//, ''); });
async.forEach(pkgs, processLinkedPackage.bind(this, emitter), next);
});
} else {
pkgs = _.uniq(pkgs);
async.forEach(pkgs, processLinkedPackage.bind(this, emitter), next);
}
},
completion: function (next) {
rimraf(config.completion, function (err) {
if (err) {
emitter.emit('error', err);
return next();
}
template('action', { name: 'completion cleared', shizzle: 'completion cache' })
.on('data', emitter.emit.bind(emitter, 'data'));
next();
});
}
}, emitter.emit.bind(emitter, 'end'));
return emitter;
};
module.exports.line = function (argv) {
var options = nopt(optionTypes, shorthand, argv);
var pkgs = options.argv.remain.slice(1);
if (options.help) return help('cache-clean');
return module.exports(pkgs);
};
module.exports.completion = function (opts, cb) {
glob('./*', { cwd: config.cache }, function (err, dirs) {
if (err) return cb(err);
dirs = dirs.map(function (dir) {
return dir.replace(/^\.\//, '');
});
cb(null, dirs);
});
};
module.exports.completion.options = shorthand;