Automatically clear bower cache when git commands fail with code 128, fixes #216.

This commit is contained in:
André Cruz
2013-02-17 14:23:59 +00:00
parent b7cbd36a07
commit d3d39141be
4 changed files with 57 additions and 16 deletions

View File

@@ -28,6 +28,7 @@ var fs = require('fs');
var crypto = require('crypto');
var unzip = require('unzip');
var tar = require('tar');
var _ = require('lodash');
var config = require('./config');
var source = require('./source');
@@ -35,7 +36,7 @@ var template = require('../util/template');
var readJSON = require('../util/read-json');
var fileExists = require('../util/file-exists');
var isRepo = require('../util/is-repo');
var spawn = require('../util/spawn');
var git = require('../util/git-cmd');
var UnitWork = require('./unit_work');
var Package = function (name, endpoint, manager) {
@@ -608,8 +609,9 @@ Package.prototype.cache = function () {
mkdirp(this.path, function (err) {
if (err) return this.emit('error', err);
var cp = spawn('git', ['clone', url, this.path], null, this);
cp.on('close', function () {
var cp = git(['clone', url, this.path], null, this);
cp.on('close', function (code) {
if (code) return;
this.emit('cache');
}.bind(this));
}.bind(this));
@@ -655,9 +657,11 @@ Package.prototype.checkout = function () {
}).on('data', this.emit.bind(this, 'data'));
// Checkout the tag
spawn('git', [ 'checkout', this.tag, '-f'], { cwd: this.path }, this).on('close', function () {
git([ 'checkout', this.tag, '-f'], { cwd: this.path }, this).on('close', function (code) {
if (code) return;
// Ensure that checkout the tag as it is, removing all untracked files
spawn('git', ['clean', '-f', '-d'], { cwd: this.path }, this).on('close', function () {
git(['clean', '-f', '-d'], { cwd: this.path }, this).on('close', function (code) {
if (code) return;
this.emit('checkout');
this.loadJSON();
}.bind(this));
@@ -667,7 +671,7 @@ Package.prototype.checkout = function () {
};
Package.prototype.describeTag = function () {
var cp = spawn('git', ['describe', '--always', '--tag'], { cwd: this.gitPath || this.path, ignoreCodes: [128] }, this);
var cp = git(['describe', '--always', '--tag'], { cwd: this.gitPath || this.path, ignoreCodes: [128] }, this);
var tag = '';
cp.stdout.setEncoding('utf8');
@@ -683,7 +687,7 @@ Package.prototype.describeTag = function () {
Package.prototype.versions = function () {
this.once('fetch', function () {
var cp = spawn('git', ['tag'], { cwd: this.gitPath }, this);
var cp = git(['tag'], { cwd: this.gitPath }, this);
var versions = '';
@@ -692,7 +696,8 @@ Package.prototype.versions = function () {
versions += data;
});
cp.on('close', function () {
cp.on('close', function (code) {
if (code) return;
versions = versions.split('\n');
versions = versions.filter(function (ver) {
return semver.valid(ver);
@@ -706,14 +711,15 @@ Package.prototype.versions = function () {
// If there is no versions tagged in the repo
// then we grab the hash of the last commit
versions = '';
cp = spawn('git', ['log', '-n', 1, '--format=%H'], { cwd: this.gitPath }, this);
cp = git(['log', '-n', 1, '--format=%H'], { cwd: this.gitPath }, this);
cp.stdout.setEncoding('utf8');
cp.stdout.on('data', function (data) {
versions += data;
});
cp.on('close', function () {
versions = versions.split('\n');
cp.on('close', function (code) {
if (code) return;
versions = _.compact(versions.split('\n'));
this.emit('versions', versions);
}.bind(this));
}.bind(this));
@@ -724,10 +730,12 @@ Package.prototype.fetch = function () {
fileExists(this.gitPath, function (exists) {
if (!exists) return this.emit('error', new Error('Unable to fetch package ' + this.name + ' (if the cache was deleted, run install again)'));
var cp = spawn('git', ['fetch', '--prune'], { cwd: this.gitPath }, this);
cp.on('close', function () {
cp = spawn('git', ['reset', '--hard', this.gitUrl ? 'origin/HEAD' : 'HEAD'], { cwd: this.gitPath }, this);
cp.on('close', function () {
var cp = git(['fetch', '--prune'], { cwd: this.gitPath }, this);
cp.on('close', function (code) {
if (code) return;
cp = git(['reset', '--hard', this.gitUrl ? 'origin/HEAD' : 'HEAD'], { cwd: this.gitPath }, this);
cp.on('close', function (code) {
if (code) return;
this.emit('fetch');
}.bind(this));
}.bind(this));

View File

@@ -103,8 +103,13 @@ exports.info = function (name, callback) {
var Package = require('./package');
var pkg = new Package(name, url);
pkg.once('error', function (err) {
pkg.removeAllListeners();
callback(err);
});
pkg.once('resolve', function () {
pkg.once('versions', function (versions) {
pkg.removeAllListeners();
callback(null, { pkg: pkg, versions: versions });
}).versions();
}).resolve();

28
lib/util/git-cmd.js Normal file
View File

@@ -0,0 +1,28 @@
// ==========================================
// BOWER: git-cmd
// ==========================================
// Copyright 2012 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
// Extension of the spawn command, that only executes git commands
// If a git command fails with code 128 in the cache, that directory
// will be deleted to prevent more issues
var path = require('path');
var spawn = require('./spawn');
var rimraf = require('rimraf');
var config = require('../core/config');
module.exports = function (args, options, emitter) {
var cp = spawn('git', args, options, emitter);
var cwd = options ? options.cwd || process.cwd() : process.cwd();
var isTmp = path.normalize(cwd).indexOf(config.cache) === 0;
cp.on('exit', function (code) {
if (code === 128 && isTmp) rimraf.sync(cwd);
});
return cp;
};

View File

@@ -9,7 +9,7 @@
var spawn = require('child_process').spawn;
// This module is similar to child-process spawn
// but automatically handling errors
// but automatically handles errors
// When an error occurs, it emits the error event containing the details of the error
// It also removes all the listeners of the command