Skip to content

Commit

Permalink
add ability to supply an event emitter so you can
Browse files Browse the repository at this point in the history
stream stdout and stderr back
  • Loading branch information
Niall O'Higgins committed Dec 25, 2012
1 parent eb01eb5 commit cebe6b9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 4 deletions.
52 changes: 49 additions & 3 deletions index.js
@@ -1,12 +1,15 @@
var crypto = require('crypto')
var exec = require('child_process').exec
var EventEmitter = require('events').EventEmitter
var fs = require('fs')
var path = require('path')
var os = require('os')
var spawn = require('child_process').spawn
var Step = require('step')

var PATH = process.env.PATH

var emitter//= new EventEmitter()

// Template string for wrapper script.
var GIT_SSH_TEMPLATE = '#!/bin/sh\n' +
'exec ssh -i $key -o StrictHostKeyChecking=no "$@"\n'
Expand Down Expand Up @@ -76,14 +79,31 @@ function writeFiles(privKey, file, keyMode, cb) {
// *baseDir* current working dir from which to execute git
// *privKey* SSH private key to use
// *cmd* command to run
// *keyMode* optional unix file mode of key
// *cb* callback function of signature function(err, stdout, stderr)
//
// or first argument may be an object with params same as above,
// with addition of *emitter* which is an EventEmitter for real-time stdout and stderr events.
function run(baseDir, privKey, cmd, keyMode, cb) {
if (typeof(keyMode) === 'function') {
cb = keyMode
keyMode = 0600
}

if (typeof(baseDir) === 'object') {
var opts = baseDir
cb = privKey
cmd = opts.cmd
privKey = opts.privKey
keyMode = opts.keyMode || 0600
emitter = opts.emitter
baseDir = opts.baseDir
}

var split = cmd.split(/\s+/)
var cmd = split[0]
var args = split.slice(1)

Step(
function() {
writeFiles(privKey, null, keyMode, this)
Expand All @@ -95,7 +115,34 @@ function run(baseDir, privKey, cmd, keyMode, cb) {
}
this.file = file
this.keyfile = keyfile
exec(cmd, {cwd: baseDir, env: {GIT_SSH: file, PATH:PATH}}, this)
var proc = spawn(cmd, args, {cwd: baseDir, env: {GIT_SSH: file, PATH:PATH}})
proc.stdoutBuffer = ""
proc.stderrBuffer = ""
proc.stdout.setEncoding('utf8')
proc.stderr.setEncoding('utf8')

proc.stdout.on('data', function(buf) {
if (typeof(emitter) === 'object') {
emitter.emit('stdout', buf)
}
proc.stdoutBuffer += buf
})

proc.stderr.on('data', function(buf) {
if (typeof(emitter) === 'object') {
emitter.emit('stderr', buf)
}
proc.stderrBuffer += buf
})

var self = this
proc.on('close', function(exitCode) {
var err = null
if (exitCode !== 0) {
err = "process exited with status " + exitCode
}
self(err, proc.stdoutBuffer, proc.stderrBuffer)
})
},
function(err, stdout, stderr) {
// cleanup temp files
Expand All @@ -105,7 +152,6 @@ function run(baseDir, privKey, cmd, keyMode, cb) {
} catch(e) {}

cb(err, stdout, stderr)

}
)
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -2,7 +2,7 @@
"author": "Niall O'Higgins <niallo@beyondfog.com> (http://niallohiggins.com)",
"name": "gitane",
"description": "Easy Node.JS Git wrapper with support for SSH keys",
"version": "0.2.11",
"version": "0.3.0",
"homepage": "https://github.com/niallo/Gitane",
"keywords":["git", "ssh", "strider"],
"repository": {
Expand Down
19 changes: 19 additions & 0 deletions test/test.js
Expand Up @@ -121,6 +121,25 @@ describe('gitane', function() {

})

it('should support event emitter parameter for real-time updates', function(done) {
var testkey = 'testkey'
var gotStdout = false
function mockEmit(ev, data) {
console.log("emitter")
if (ev === 'stdout') {
gotStdout = true
expect(fs.realpathSync(data.trim())).to.eql(fs.realpathSync(os.tmpDir()))
}
}
var opts = {emitter: {emit:mockEmit}, baseDir:os.tmpDir(), privKey: testkey, cmd:'pwd'}
gitane.run(opts, function(err, stdout, stderr) {
expect(err).to.be.null
expect(fs.realpathSync(stdout.trim())).to.eql(fs.realpathSync(os.tmpDir()))
expect(gotStdout).to.be.true
done()
})
})

})

})
Expand Down

0 comments on commit cebe6b9

Please sign in to comment.