mirror of
https://github.com/bower/bower.git
synced 2026-01-13 16:28:05 -05:00
336 lines
8.2 KiB
JavaScript
336 lines
8.2 KiB
JavaScript
require('chalk').enabled = false;
|
|
|
|
var Q = require('q');
|
|
var path = require('path');
|
|
var mkdirp = require('mkdirp');
|
|
var rimraf = require('../lib/util/rimraf');
|
|
var uuid = require('node-uuid');
|
|
var object = require('mout/object');
|
|
var fs = require('../lib/util/fs');
|
|
var glob = require('glob');
|
|
var os = require('os');
|
|
var which = require('which');
|
|
var proxyquire = require('proxyquire')
|
|
.noCallThru()
|
|
.noPreserveCache();
|
|
var spawnSync = require('spawn-sync');
|
|
var config = require('../lib/config');
|
|
var nock = require('./util/nock');
|
|
var semver = require('semver');
|
|
|
|
// For better promise errors
|
|
Q.longStackSupport = true;
|
|
|
|
// Those are needed for testing or not configured git environment
|
|
var env = {
|
|
GIT_AUTHOR_DATE: 'Sun Apr 7 22:13:13 2013 +0000',
|
|
GIT_AUTHOR_NAME: 'André Cruz',
|
|
GIT_AUTHOR_EMAIL: 'amdfcruz@gmail.com',
|
|
GIT_COMMITTER_DATE: 'Sun Apr 7 22:13:13 2013 +0000',
|
|
GIT_COMMITTER_NAME: 'André Cruz',
|
|
GIT_COMMITTER_EMAIL: 'amdfcruz@gmail.com',
|
|
NODE_ENV: 'test'
|
|
};
|
|
|
|
object.mixIn(process.env, env);
|
|
|
|
var tmpLocation = path.join(
|
|
os.tmpdir ? os.tmpdir() : os.tmpDir(),
|
|
'bower-tests',
|
|
uuid.v4().slice(0, 8)
|
|
);
|
|
|
|
exports.require = function(name, stubs) {
|
|
if (stubs) {
|
|
return proxyquire(path.join(__dirname, '../', name), stubs);
|
|
} else {
|
|
return require(path.join(__dirname, '../', name));
|
|
}
|
|
};
|
|
|
|
// We need to reset cache because tests are reusing temp directories
|
|
beforeEach(function() {
|
|
config.reset();
|
|
});
|
|
|
|
after(function() {
|
|
rimraf.sync(tmpLocation);
|
|
});
|
|
|
|
exports.TempDir = (function() {
|
|
function TempDir(defaults) {
|
|
this.path = path.join(tmpLocation, uuid.v4());
|
|
this.defaults = defaults;
|
|
}
|
|
|
|
TempDir.prototype.create = function(files, defaults) {
|
|
var that = this;
|
|
|
|
defaults = defaults || this.defaults || {};
|
|
files = object.merge(files || {}, defaults);
|
|
|
|
this.meta = function(tag) {
|
|
if (tag) {
|
|
return files[tag]['bower.json'];
|
|
} else {
|
|
return files['bower.json'];
|
|
}
|
|
};
|
|
|
|
if (files) {
|
|
object.forOwn(files, function(contents, filepath) {
|
|
if (typeof contents === 'object') {
|
|
contents = JSON.stringify(contents, null, ' ') + '\n';
|
|
}
|
|
|
|
var fullPath = path.join(that.path, filepath);
|
|
mkdirp.sync(path.dirname(fullPath));
|
|
fs.writeFileSync(fullPath, contents);
|
|
});
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
TempDir.prototype.prepare = function(files) {
|
|
rimraf.sync(this.path);
|
|
mkdirp.sync(this.path);
|
|
this.create(files);
|
|
|
|
return this;
|
|
};
|
|
|
|
// TODO: Rewrite to synchronous form
|
|
TempDir.prototype.prepareGit = function(revisions) {
|
|
var that = this;
|
|
|
|
revisions = object.merge(revisions || {}, this.defaults);
|
|
|
|
rimraf.sync(that.path);
|
|
|
|
mkdirp.sync(that.path);
|
|
|
|
this.git('init');
|
|
|
|
this.glob('./!(.git)').map(function(removePath) {
|
|
var fullPath = path.join(that.path, removePath);
|
|
|
|
rimraf.sync(fullPath);
|
|
});
|
|
|
|
object.forOwn(
|
|
revisions,
|
|
function(files, tag) {
|
|
this.create(files, {});
|
|
this.git('add', '-A');
|
|
this.git('commit', '-m"commit"');
|
|
this.git('tag', tag);
|
|
}.bind(this)
|
|
);
|
|
|
|
return this;
|
|
};
|
|
|
|
TempDir.prototype.glob = function(pattern) {
|
|
return glob.sync(pattern, {
|
|
cwd: this.path,
|
|
dot: true
|
|
});
|
|
};
|
|
|
|
TempDir.prototype.getPath = function(name) {
|
|
return path.join(this.path, name);
|
|
};
|
|
|
|
TempDir.prototype.read = function(name) {
|
|
return fs.readFileSync(this.getPath(name), 'utf8');
|
|
};
|
|
|
|
TempDir.prototype.readJson = function(name) {
|
|
return JSON.parse(this.read(name));
|
|
};
|
|
|
|
TempDir.prototype.git = function() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
var result = spawnSync('git', args, { cwd: this.path });
|
|
|
|
if (result.status !== 0) {
|
|
throw new Error(result.stderr);
|
|
} else {
|
|
return result.stdout.toString();
|
|
}
|
|
};
|
|
|
|
TempDir.prototype.latestGitTag = function() {
|
|
var versions = this.git('tag')
|
|
.split(/\r?\n/)
|
|
.map(function(t) {
|
|
return t[0] == 'v' ? t.slice(1) : t;
|
|
})
|
|
.filter(semver.valid)
|
|
.sort(semver.compare);
|
|
|
|
if (versions.length >= 1) {
|
|
return versions[versions.length - 1];
|
|
} else {
|
|
throw new Error('No valid git version tags found.');
|
|
}
|
|
};
|
|
|
|
TempDir.prototype.exists = function(name) {
|
|
return fs.existsSync(path.join(this.path, name));
|
|
};
|
|
|
|
return TempDir;
|
|
})();
|
|
|
|
exports.expectEvent = function expectEvent(emitter, eventName) {
|
|
var deferred = Q.defer();
|
|
|
|
emitter.once(eventName, function() {
|
|
deferred.resolve(arguments);
|
|
});
|
|
|
|
emitter.once('error', function(reason) {
|
|
deferred.reject(reason);
|
|
});
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
exports.command = function(command, stubs) {
|
|
var rawCommand;
|
|
var commandStubs = {};
|
|
|
|
stubs = stubs || {};
|
|
var cwd = stubs.cwd;
|
|
delete stubs.cwd;
|
|
|
|
rawCommand = exports.require('lib/commands/' + command, stubs);
|
|
|
|
commandStubs['./' + command] = function() {
|
|
var args = [].slice.call(arguments);
|
|
args[rawCommand.length - 1] = object.merge(
|
|
{ cwd: cwd },
|
|
args[rawCommand.length - 1] || {}
|
|
);
|
|
return rawCommand.apply(null, args);
|
|
};
|
|
|
|
var instance = exports.require('lib/commands/index', commandStubs);
|
|
|
|
var commandParts = command.split('/');
|
|
|
|
while (commandParts.length > 0) {
|
|
instance = instance[commandParts.shift()];
|
|
}
|
|
|
|
if (!instance) {
|
|
throw new Error('Unknown command: ' + command);
|
|
}
|
|
|
|
// TODO: refactor tests, so they can use readOptions directly
|
|
instance.readOptions = function(argv) {
|
|
argv = ['node', 'bower'].concat(argv);
|
|
argv = command.split('/').concat(argv);
|
|
|
|
return rawCommand.readOptions(argv);
|
|
};
|
|
|
|
return instance;
|
|
};
|
|
|
|
exports.run = function(command, args) {
|
|
var logger = command.apply(null, args || []);
|
|
|
|
// Hack so we can intercept prompring for data
|
|
logger.prompt = function(data) {
|
|
logger.emit('confirm', data);
|
|
};
|
|
|
|
var promise = exports.expectEvent(logger, 'end');
|
|
|
|
promise.logger = logger;
|
|
|
|
return promise;
|
|
};
|
|
|
|
// Captures all stdout and stderr
|
|
exports.capture = function(callback) {
|
|
var oldStdout = process.stdout.write;
|
|
var oldStderr = process.stderr.write;
|
|
|
|
var stdout = '';
|
|
var stderr = '';
|
|
|
|
process.stdout.write = function(text) {
|
|
stdout += text;
|
|
};
|
|
|
|
process.stderr.write = function(text) {
|
|
stderr += text;
|
|
};
|
|
|
|
return Q.fcall(callback)
|
|
.then(function() {
|
|
process.stdout.write = oldStdout;
|
|
process.stderr.write = oldStderr;
|
|
|
|
return [stdout, stderr];
|
|
})
|
|
.fail(function(e) {
|
|
process.stdout.write = oldStdout;
|
|
process.stderr.write = oldStderr;
|
|
|
|
throw e;
|
|
});
|
|
};
|
|
|
|
exports.hasSvn = function() {
|
|
try {
|
|
which.sync('svn');
|
|
return true;
|
|
} catch (ex) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
exports.isWin = function() {
|
|
return process.platform === 'win32';
|
|
};
|
|
|
|
exports.localSource = function(localPath) {
|
|
localPath = path.normalize(localPath);
|
|
|
|
if (!exports.isWin()) {
|
|
localPath = 'file://' + localPath;
|
|
}
|
|
|
|
return localPath;
|
|
};
|
|
|
|
// Used for example by "svn checkout" and "svn export"
|
|
exports.localUrl = function(localPath) {
|
|
localPath = path.normalize(localPath);
|
|
|
|
if (!exports.isWin()) {
|
|
localPath = 'file://' + localPath;
|
|
} else {
|
|
localPath = 'file:///' + localPath;
|
|
}
|
|
|
|
return localPath;
|
|
};
|
|
|
|
// Returns the result of executing the bower binary + args
|
|
// example: runBin('install') --> $ bower install
|
|
exports.runBin = function(args) {
|
|
args = args || [];
|
|
args.unshift(path.resolve(__dirname, '../bin/bower'));
|
|
return spawnSync('node', args);
|
|
};
|
|
|
|
afterEach(function() {
|
|
nock.cleanAll();
|
|
});
|