Browse files

Working now

  • Loading branch information...
1 parent 601ba42 commit 75a69b2ff9a15e58a3180dcdef46ca5498d7402c @isaacs isaacs committed Jul 24, 2012
Showing with 56 additions and 30 deletions.
  1. +42 −15 lib/read.js
  2. +14 −15 test/basic.js
View
57 lib/read.js
@@ -15,18 +15,24 @@ function read (opts, cb) {
m.pipe(output)
output = m
var def = opts.default || ''
- var rl = readline.createInterface({ input: input, output: output })
+ var terminal = !!(opts.terminal || output.isTTY)
+ var rlOpts = { input: input, output: output, terminal: terminal }
+ var rl = readline.createInterface(rlOpts)
var prompt = (opts.prompt || '').trim() + ' '
var silent = opts.silent
- var editDef = def && opts.edit
- if (def && !editDef) {
- prompt += '(' + def + ') '
- }
+ var editDef = false
+ var timeout = opts.timeout
- read_(rl, input, output, prompt, def, silent, editDef, cb)
-}
+ if (def) {
+ if (silent) {
+ prompt += '(<default hidden>) '
+ } else if (opts.edit) {
+ editDef = true
+ } else {
+ prompt += '(' + def + ') '
+ }
+ }
-function read_ (rl, input, output, prompt, def, silent, editDef, cb) {
if (silent) {
output.unmute()
rl.setPrompt(prompt)
@@ -43,27 +49,48 @@ function read_ (rl, input, output, prompt, def, silent, editDef, cb) {
}
var called = false
- rl.once('line', onLine)
- rl.once('error', onError)
+ rl.on('line', onLine)
+ rl.on('error', onError)
- function onError (er) {
- if (called) return
+ rl.on('SIGINT', function () {
+ rl.close()
+ onError(new Error('canceled'))
+ })
+
+ var timer
+ if (timeout) {
+ timer = setTimeout(function () {
+ onError(new Error('timed out'))
+ }, timeout)
+ }
+
+ function done () {
called = true
rl.close()
+ clearTimeout(timer)
output.mute()
+ }
+
+ function onError (er) {
+ if (called) return
+ done()
return cb(er)
}
function onLine (line) {
if (called) return
- called = true
- rl.close()
- output.mute()
+ if (silent && terminal) {
+ output.unmute()
+ output.write('\r\n')
+ }
+ done()
var isDefault = !!(editDef && line === def)
if (def && !line) {
isDefault = true
line = def
}
+ // truncate the \n at the end.
+ line = line.replace(/\r?\n$/, '')
cb(null, line, isDefault)
}
}
View
29 test/basic.js
@@ -10,44 +10,43 @@ var spawn = require('child_process').spawn
tap.test('basic', function (t) {
var child = spawn(process.execPath, [__filename, 'child'])
var output = ''
+ var write = child.stdin.write.bind(child.stdin)
child.stdout.on('data', function (c) {
console.error('data %s', c)
output += c
if (output.match(/Username: \(test-user\) $/)) {
- child.stdin.write('a user\n')
+ process.nextTick(write.bind(null, 'a user\n'))
} else if (output.match(/Password: \(<default hidden>\) $/)) {
- child.stdin.write('a password\n')
- } else if (output.match(/characters: $/)) {
- child.stdin.write('asdf\n')
+ process.nextTick(write.bind(null, 'a password\n'))
} else if (output.match(/Password again: \(<default hidden>\) $/)) {
- child.stdin.write('a password\n')
+ process.nextTick(write.bind(null, 'a password\n'))
+ } else {
+ console.error('prompts done, output=%j', output)
}
})
var result = ''
child.stderr.on('data', function (c) {
result += c
+ console.error('result %j', c.toString())
})
child.on('close', function () {
result = JSON.parse(result)
- t.same(result, {"user":"a user","pass":"a password","verify":"a password","four":"asdf","passMatch":true})
- t.equal(output, 'Username: (test-user) Password: (<default hidden>) Enter 4 characters: Password again: (<default hidden>) ')
+ t.same(result, {"user":"a user","pass":"a password","verify":"a password","passMatch":true})
+ t.equal(output, 'Username: (test-user) Password: (<default hidden>) Password again: (<default hidden>) ')
t.end()
})
})
function child () {
read({prompt: "Username: ", default: "test-user" }, function (er, user) {
read({prompt: "Password: ", default: "test-pass", silent: true }, function (er, pass) {
- read({prompt: "Enter 4 characters: ", num: 4 }, function (er, four) {
- read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
- console.error(JSON.stringify({user: user,
- pass: pass,
- verify: pass2,
- four:four,
- passMatch: (pass === pass2)}))
- })
+ read({prompt: "Password again: ", default: "test-pass", silent: true }, function (er, pass2) {
+ console.error(JSON.stringify({user: user,
+ pass: pass,
+ verify: pass2,
+ passMatch: (pass === pass2)}))
})
})
})

0 comments on commit 75a69b2

Please sign in to comment.