Skip to content

Commit

Permalink
Major updates and bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
rex committed Jun 23, 2013
1 parent eb55f93 commit 40e437e
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 74 deletions.
160 changes: 90 additions & 70 deletions lib/rex-git.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,79 +37,50 @@
var fs = require('fs')
, path = require('path')
, os = require('os')
, _ = require('underscore')._
, async = require('async')
, cli = require('rex-shell')
, exec = require('rex-exec')
, package = require('../package.json')
, config = require('../package.json').config
, optimist = require('optimist')
.usage("Perform simple operations on local Git repos. \n $0 [option] [path]")
.alias('l','list')
.describe('l','List all the git repos in the current directory')
.alias('s','status')
.describe('s','Get the status of all the git repos in the current directory')
.alias('p','pull')
.describe('p','Pull all repos down from their remote counterparts.')
.alias('v','version')
.describe('v','Display current rex-git version.')
, argv = optimist.argv
, git_commands = {
branch : 'git rev-parse --abbrev-ref HEAD',
status_quiet : 'git fetch && git status -sb',
status_long : 'git fetch && git status',
peek : '',
prePull : 'if [ -n "$(git status --porcelain)" ]; then \n\
echo >&2 "ERROR: Working tree dirty, aborting pull."; \n\
exit 1; \n\
else \n\
echo "Working tree clean, pulling"; \n\
git pull \n\
fi'
}
, utils = require('rex-utils')
, _ = require('rex-utils')._
, package = require('../package')
, config = require('../package').config
, git_commands = _.rex_commands().git

var tree = function(dir, maxDepth) {
var repos = []
var files = fs.readdirSync(path.resolve(dir))
_.each(files, function(file) {
// @todo: Bring in osPath() function in mixins from rex-utils
var filePath = path.resolve(dir + path.sep + file)
if(_.contains(['.DS_Store'], file))
return false
// cli("Processing file: "+ filePath +" ("+ typeof file +")")

var stat = fs.statSync( filePath )
if(stat.isDirectory()) {
if( fs.existsSync( path.resolve(filePath+"/.git") ) )
repos.push( filePath )
}
if( file == ".git" ) {
repos.push( dir )
}
})

return repos
}
exports.version = package.version
exports.package = package

exports.init = function() {
if(argv.version)
version()
else if(argv.list)
list(argv.list)
else if(argv.status)
status(argv.status)
else if(argv.pull)
pull(argv.pull)
else
optimist.showHelp()
}
var operation = process.argv[2] || 'help'
var dir = process.argv[3] || null

exports.version = version = function() {
cli.$.blue( "Current rex-git version: \n "+ cli.$$.g( package.version ) )
switch(operation) {
case 'list':
list(dir)
break;
case 'status':
status(dir)
break;
case 'pull':
pull(dir)
break;
case 'dirty':
dirty(dir)
break;
case 'version':
_.displayVersion(package, {
"rex-exec" : exec.version,
"rex-utils" : utils.version,
"rex-shell" : cli.version
})
break;
case 'help':
default:
_.showHelp(package)
}
}

exports.branch = branch = function(dir) {
exec(path.resolve(dir), git_commands.branch, function(err, currentBranch) {
exec(_.osPath(dir), git_commands.branch, function(err, currentBranch) {
cli.$.blue( path.basename(dir) +" is on branch "+ currentBranch)
})
}
Expand All @@ -118,9 +89,9 @@ exports.list = list = function(dir) {
if(typeof dir !== 'string')
dir = process.cwd()
else
dir = path.resolve(dir)
dir = _.osPath(dir)
cli("Finding all git repos in: "+ dir)
var repos = tree(dir)
var repos = _.gitTree(dir)
if(repos.length == 0) {
cli.error("There are no git repos in the specified path.")
} else {
Expand All @@ -144,9 +115,9 @@ exports.status = status = function(dir) {
if(typeof dir !== 'string')
dir = process.cwd()
else
dir = path.resolve(dir)
dir = _.osPath(dir)
cli("Displaying status of all git repos in: "+ dir)
var repos = tree(dir)
var repos = _.gitTree(dir)
if(repos.length == 0) {
cli.error("There are no git repos in the specified path.")
} else {
Expand All @@ -170,13 +141,13 @@ exports.status = status = function(dir) {
}
}

exports.pull = pull = function(dir) {
exports.pull = pull = function(dir, callback) {
if(typeof dir !== 'string')
dir = process.cwd()
else
dir = path.resolve(dir)
dir = _.osPath(dir)
cli("Pulling all git repos in: "+ dir)
var repos = tree(dir)
var repos = _.gitTree(dir)
if(repos.length == 0) {
cli.error("There are no git repos in the specified path.")
} else {
Expand All @@ -189,6 +160,11 @@ exports.pull = pull = function(dir) {
var cmd = git_commands.prePull
}

var after = _.after(repos.length, function() {
if(_.isFunction(callback))
callback(null, repos.length +' repositories updated.')
})

_.each(repos, function(repoPath) {

exec(repoPath,cmd, function(stderr, stdout) {
Expand All @@ -204,7 +180,51 @@ exports.pull = pull = function(dir) {
} else {
console.log( cli.$$.g(" > ")+ cli.$$.R( path.basename(repoPath) +" (ERROR) - Unable to Retrieve Status"), stderr, stdout )
}

after()
})
})
}
}

/**
* Lists only the git repos found in the path provided that are in a dirty state.
*/
exports.dirty = dirty = function(dir) {
// Sorry, Windows guys.
_.killWindows()

if(typeof dir !== 'string')
dir = process.cwd()
else
dir = _.osPath(dir)
cli("Finding dirty git repos in: "+ dir)
var repos = _.gitTree(dir)
if(repos.length == 0) {
cli.error("There are no git repos in the specified path.")
} else {
var totalDirty = 0
var after = _.after(repos.length, function() {
if(totalDirty == 0) {
cli.success("All repos in '"+ dir +"' are in a clean, working state!")
} else {
cli.error( totalDirty +" dirty git repos were found in '"+ dir +"'.")
}
})

_.each(repos, function(repoPath) {
exec(repoPath, git_commands.porcelain, function(stderr, stdout) {
if( stderr ) {
console.log( cli.$$.g(" > ")+ cli.$$.R( path.basename(repoPath) +" (DIRTY)\n"), stderr )
totalDirty++
} else if( stdout ) {
// Intentionally ignore successful, clean output
} else {
console.log( cli.$$.g(" > ")+ cli.$$.R( path.basename(repoPath) +" (ERROR) - Unable to Retrieve Status"), stderr, stdout )
totalDirty++
}
after()
})
})
}
}
17 changes: 13 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,26 @@
"test": "./test"
},
"dependencies": {
"optimist": "*",
"underscore": "*",
"async": "*",
"rex-shell": "*",
"rex-exec": "*"
"rex-exec": "*",
"rex-utils": "*"
},
"devDependencies": {},
"engines": {
"node": ">=0.10.x"
},
"config": {},
"config": {
"cli" : {
"usage" : "rex-git [list|status|pull]",
"args" : {
"list" : "Find and display all git repos in the current directory or a path, if specified.",
"status" : "Display the status of all the git repos in the current directory or a path, if specified.",
"pull" : "Fetch the latest changes for all git repos in the current directory or a path, if specified.",
"dirty" : "Display all the git repos in the provided directory that are in an unclean state. (No Windows Support yet, sorry!)"
}
}
},
"bugs": {
"url": "https://github.com/rex/rex-git/issues"
},
Expand Down

0 comments on commit 40e437e

Please sign in to comment.