function clean() { rimraf.sync(getCacheDir()); }
n/a
git = function (args, cwd) { return spawn(git, args, cwd); }
n/a
function publish(basePath, config, callback) { if (typeof config === 'function') { callback = config; config = {}; } var defaults = { add: false, git: 'git', clone: getCacheDir(), dotfiles: false, branch: 'gh-pages', remote: 'origin', src: '**/*', only: '.', push: true, message: 'Updates', silent: false, logger: function() {} }; // override defaults with any task options // TODO: Require Node >= 4 and use Object.assign var options = {}; for (var d in defaults) { options[d] = defaults[d]; } for (var c in config) { options[c] = config[c]; } function log(message) { if (!options.silent) { options.logger(message); } } if (!callback) { callback = function(err) { if (err) { log(err.message); } }; } function done(err) { try { callback(err); } catch (err2) { log('Publish callback threw: ', err2.message); } } try { if (!fs.statSync(basePath).isDirectory()) { done(new Error('The "base" option must be an existing directory')); return; } } catch (err) { done(err); return; } var files = globby.sync(options.src, { cwd: basePath, dot: options.dotfiles }).filter(function(file) { return !fs.statSync(path.join(basePath, file)).isDirectory(); }); if (!Array.isArray(files) || files.length === 0) { done(new Error('Files must be provided in the "src" property.')); return; } var only = globby.sync(options.only, {cwd: basePath}); git.exe(options.git); var repoUrl; getRepo(options) .then(function(repo) { repoUrl = repo; log('Cloning ' + repo + ' into ' + options.clone); return git.clone(repo, options.clone, options.branch, options); }) .then(function() { return getRemoteUrl(options.clone, options.remote) .then(function(url) { if (url !== repoUrl) { var message = 'Remote url mismatch. Got "' + url + '" ' + 'but expected "' + repoUrl + '" in ' + options.clone + '. If you have changed your "repo" option, try ' + 'running the "clean" task first.'; return Q.reject(new Error(message)); } else { return Q.resolve(); } }); }) .then(function() { // only required if someone mucks with the checkout between builds log('Cleaning'); return git.clean(options.clone); }) .then(function() { log('Fetching ' + options.remote); return git.fetch(options.remote, options.clone); }) .then(function() { log('Checking out ' + options.remote + '/' + options.branch); return git.checkout(options.remote, options.branch, options.clone); }) .then(function() { if (!options.add) { log('Removing files'); return git.rm(only.join(' '), options.clone); } else { return Q.resolve(); } }) .then(function() { log('Copying files'); return copy(files, basePath, options.clone); }) .then(function() { log('Adding all'); return git.add('.', options.clone); }) .then(function() { if (options.user) { return git(['config', 'user.email', options.user.email], options.clone) .then(function() { return git(['config', 'user.name', options.user.name], options.clone); }); } else { return Q.resolve(); } }) .then(function() { log('Committing'); return git.commit(options.message, options.clone); }) .then(function() { if (options.tag) { log('Tagging'); var deferred = Q.defer(); git.tag(options.tag, options.clone) .then(function() { return deferred.resolve(); }) ...
...
## Basic Usage
```js
var ghpages = require('gh-pages');
var path = require('path');
ghpages.publish(path.join(__dirname, 'dist'), function(err) { ... });
```
## `publish`
```js
ghpages.publish(basePath, callback);
...
git = function (args, cwd) { return spawn(git, args, cwd); }
n/a
function add(files, cwd) { return spawn(git, ['add', files], cwd); }
n/a
function checkout(remote, branch, cwd) { var treeish = remote + '/' + branch; return spawn(git, ['ls-remote', '--exit-code', '.', treeish], cwd) .then(function() { // branch exists on remote, hard reset return spawn(git, ['checkout', branch], cwd) .then(function() { return clean(cwd); }) .then(function() { return reset(remote, branch, cwd); }); }, function(error) { if (error instanceof ProcessError && error.code === 2) { // branch doesn't exist, create an orphan return spawn(git, ['checkout', '--orphan', branch], cwd); } else { // unhandled error return Q.reject(error); } }); }
n/a
function clean(cwd) { return spawn(git, ['clean', '-f', '-d'], cwd); }
n/a
function clone(repo, dir, branch, options) { return fs.exists(dir).then(function(exists) { if (exists) { return Q.resolve(); } else { return fs.makeTree(path.dirname(path.resolve(dir))).then(function() { var args = ['clone', repo, dir, '--branch', branch, '--single-branch', '--origin', options.remote]; if (options.depth) { args.push('--depth', options.depth); } return spawn(git, args).fail(function(err) { // try again without banch options return spawn(git, ['clone', repo, dir, '--origin', options.remote]); }); }); } }); }
n/a
function commit(message, cwd) { return spawn(git, ['diff-index', '--quiet', 'HEAD', '.'], cwd) .then(function() { // nothing to commit return Q.resolve(); }) .fail(function() { return spawn(git, ['commit', '-m', message], cwd); }); }
n/a
exe = function (exe) { git = exe; }
n/a
function fetch(remote, cwd) { return spawn(git, ['fetch', remote], cwd); }
n/a
function init(cwd) { return spawn(git, ['init'], cwd); }
n/a
function push(remote, branch, cwd) { return spawn(git, ['push', '--tags', remote, branch], cwd); }
...
* @return {Promise} A promise.
*/
function spawn(exe, args, cwd) {
var deferred = Q.defer();
var child = cp.spawn(exe, args, {cwd: cwd || process.cwd()});
var buffer = [];
child.stderr.on('data', function(chunk) {
buffer.push(chunk.toString());
});
child.stdout.on('data', function(chunk) {
deferred.notify(chunk);
});
child.on('close', function(code) {
if (code) {
var msg = buffer.join('') || 'Process failed: ' + code;
...
function reset(remote, branch, cwd) { return spawn(git, ['reset', '--hard', remote + '/' + branch], cwd); }
n/a
function rm(files, cwd) { return spawn(git, ['rm', '--ignore-unmatch', '-r', '-f', files], cwd); }
n/a
function tag(name, cwd) { return spawn(git, ['tag', name], cwd); }
n/a
byShortPath = function (a, b) { var aParts = a.split(path.sep); var bParts = b.split(path.sep); var aLength = aParts.length; var bLength = bParts.length; var cmp = 0; if (aLength < bLength) { cmp = -1; } else if (aLength > bLength) { cmp = 1; } else { var aPart, bPart; for (var i = 0; i < aLength; ++i) { aPart = aParts[i]; bPart = bParts[i]; if (aPart < bPart) { cmp = -1; break; } else if (aPart > bPart) { cmp = 1; break; } } } return cmp; }
n/a
copy = function (files, base, dest) { var deferred = Q.defer(); var pairs = []; var destFiles = []; files.forEach(function(file) { var src = path.resolve(base, file); var relative = path.relative(base, src); var target = path.join(dest, relative); pairs.push({ src: src, dest: target }); destFiles.push(target); }); async.eachSeries(dirsToCreate(destFiles), makeDir, function(err) { if (err) { return deferred.reject(err); } async.each(pairs, copyFile, function(err) { if (err) { return deferred.reject(err); } else { return deferred.resolve(); } }); }); return deferred.promise; }
n/a
copyFile = function (obj, callback) { var called = false; function done(err) { if (!called) { called = true; callback(err); } } var read = fs.createReadStream(obj.src); read.on('error', function(err) { done(err); }); var write = fs.createWriteStream(obj.dest); write.on('error', function(err) { done(err); }); write.on('close', function(ex) { done(); }); read.pipe(write); }
n/a
dirsToCreate = function (files) { return uniqueDirs(files).sort(byShortPath); }
n/a
uniqueDirs = function (files) { var dirs = {}; files.forEach(function(filepath) { var parts = path.dirname(filepath).split(path.sep); var partial = parts[0]; dirs[partial] = true; for (var i = 1, ii = parts.length; i < ii; ++i) { partial = path.join(partial, parts[i]); dirs[partial] = true; } }); return Object.keys(dirs); }
n/a