From 9f9693cb157563c448349e4d8f443b88ccd2ca08 Mon Sep 17 00:00:00 2001 From: Francis Gulotta Date: Sun, 1 May 2016 18:19:54 -0400 Subject: [PATCH] Update cli tools (#776) - Better argument handling - Switch to commander as optimist is deprecated - more output formats for serial port list - give serialportterm a list option --- README.md | 54 +++++++++++++++++- bin/serialport-list.js | 46 +++++++++++---- bin/serialport-terminal.js | 83 +++++++++++++--------------- package.json | 5 +- test/arduinoTest/serialDuplexTest.js | 25 ++++----- 5 files changed, 140 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index b78f2dd11..48341844d 100644 --- a/README.md +++ b/README.md @@ -436,7 +436,57 @@ Callback is called with an error object. If you install `serialport` globally. (eg, `npm install -g serialport`) you'll receive two command line tools. ### Serial Port List -`serialportlist` will list all available serialports +`serialportlist` will list all available serial ports in different formats. + +```bash +$ serialportlist -h + + Usage: serialport-list [options] + + List available serial ports + + Options: + + -h, --help output usage information + -V, --version output the version number + -f, --format Format the output as text, json, or jsonline. default: text + + +$ serialportlist +/dev/cu.Bluetooth-Incoming-Port +/dev/cu.usbmodem1421 Arduino (www.arduino.cc) + +$ serialportlist -f json +[{"comName":"/dev/cu.Bluetooth-Incoming-Port"},{"comName":"/dev/cu.usbmodem1421","manufacturer":"Arduino (www.arduino.cc)","serialNumber":"752303138333518011C1","locationId":"0x14200000","vendorId":"0x2341","productId":"0x0043"}] + +$ serialportlist -f jsonline +{"comName":"/dev/cu.Bluetooth-Incoming-Port"} +{"comName":"/dev/cu.usbmodem1421","manufacturer":"Arduino (www.arduino.cc)","serialNumber":"752303138333518011C1","locationId":"0x14200000","vendorId":"0x2341","productId":"0x0043"} +``` ### Serial Port Terminal -`serialportterm` provides a basic terminal interface for a serialport. `ctrl+c` will exit. +`serialportterm` provides a basic terminal interface for communicating over a serial port. `ctrl+c` will exit. + +```bash +$ serialportterminal -h + + Usage: serialport-terminal -p [options] + + A basic terminal interface for communicating over a serial port. Pressing ctrl+c exits. + + Options: + + -h, --help output usage information + -V, --version output the version number + -l --list List available ports then exit + -p, --port, --portname Path or Name of serial port + -b, --baud Baud rate default: 9600 + --databits Data bits default: 8 + --parity Parity default: none + --stopbits Stop bits default: 1 + --echo --localecho Print characters as you type them. + +$ serialportterminal -l +/dev/cu.Bluetooth-Incoming-Port +/dev/cu.usbmodem1421 Arduino (www.arduino.cc) +``` diff --git a/bin/serialport-list.js b/bin/serialport-list.js index 1fbf60eee..070f68ad4 100755 --- a/bin/serialport-list.js +++ b/bin/serialport-list.js @@ -1,17 +1,43 @@ #!/usr/bin/env node - 'use strict'; var serialport = require('../'); -var sf = require('sf'); +var version = require('../package.json').version; +var args = require('commander'); -serialport.list(function (err, results) { - if (err) { - throw err; - } +args + .version(version) + .description('List available serial ports') + .option('-f, --format ', 'Format the output as text, json, or jsonline. default: text', /^(text|json|jsonline)$/i, 'text') + .parse(process.argv); - for (var i = 0; i < results.length; i++) { - var item = results[i]; - console.log(sf('{comName,-15} {pnpId,-20} {manufacturer}', item)); +var formatters = { + text: function(err, ports) { + if (err) { + console.error(err); + process.exit(1); + } + ports.forEach(function(port) { + console.log(port.comName + '\t' + (port.pnpId || '') + '\t' + (port.manufacturer || '')); + }); + }, + json: function(err, ports) { + if (err) { + console.error(JSON.stringify(err)); + process.exit(1); + } + console.log(JSON.stringify(ports)); + }, + jsonline: function(err, ports) { + if (err) { + console.error(JSON.stringify(err)); + process.exit(1); + } + ports.forEach(function(port) { + console.log(JSON.stringify(port)); + }); } -}); +}; + +serialport.list(formatters[args.format]); + diff --git a/bin/serialport-terminal.js b/bin/serialport-terminal.js index 2fd51fb74..900603138 100755 --- a/bin/serialport-terminal.js +++ b/bin/serialport-terminal.js @@ -1,47 +1,45 @@ #!/usr/bin/env node - 'use strict'; -var SerialPort = require('../').SerialPort; -var optimist = require('optimist'); +var serialport = require('../'); +var version = require('../package.json').version; +var args = require('commander'); + +args + .version(version) + .usage('-p [options]') + .description('A basic terminal interface for communicating over a serial port. Pressing ctrl+c exits.') + .option('-l --list', 'List available ports then exit') + // TODO make the port not a flag as it's always required + .option('-p, --port, --portname ', 'Path or Name of serial port') + .option('-b, --baud ', 'Baud rate default: 9600', parseInt, 9600) + .option('--databits ', 'Data bits default: 8', parseInt, 8) + .option('--parity ', 'Parity default: none', 'none') + .option('--stopbits ', 'Stop bits default: 1', parseInt, 1) + // TODO make this on by default + .option('--echo --localecho', 'Print characters as you type them.') + .parse(process.argv); -var args = optimist - .alias('h', 'help') - .alias('h', '?') - .options('portname', { - alias: 'p', - describe: 'Name of serial port. See serialPortList.js for open serial ports.' - }) - .options('baud', { - describe: 'Baud rate.', - default: 9600 - }) - .options('databits', { - describe: 'Data bits.', - default: 8 - }) - .options('parity', { - describe: 'Parity.', - default: 'none' - }) - .options('stopbits', { - describe: 'Stop bits.', - default: 1 - }) - .options('localecho', { - describe: 'Enable local echo.', - boolean: true - }) - .argv; +function listPorts() { + serialport.list(function(err, ports) { + if (err) { + console.error('Error listing ports', err); + } else { + ports.forEach(function(port) { + console.log(port.comName + '\t' + (port.pnpId || '') + '\t' + (port.manufacturer || '')); + }); + } + }); +}; -if (args.help) { - optimist.showHelp(); - return process.exit(-1); +if (args.list) { + return listPorts(); } -if (!args.portname) { - console.error('Serial port name is required.'); - return process.exit(-1); +if (!args.port) { + args.outputHelp(); + args.missingArgument('port'); + process.exit(-1); } var openOptions = { @@ -51,7 +49,7 @@ var openOptions = { stopBits: args.stopbits }; -var port = new SerialPort(args.portname, openOptions); +var port = new serialport.SerialPort(args.port, openOptions); process.stdin.resume(); process.stdin.setRawMode(true); @@ -67,11 +65,7 @@ process.stdin.on('data', function (s) { process.stdout.write(s); } } - port.write(s, function (err) { - if (err) { - console.log(err); - } - }); + port.write(s); }); port.on('data', function (data) { @@ -79,5 +73,6 @@ port.on('data', function (data) { }); port.on('error', function (err) { - console.log(err); + console.log('Error', err); + process.exit(1); }); diff --git a/package.json b/package.json index 72e34b987..e890a6bb5 100644 --- a/package.json +++ b/package.json @@ -50,13 +50,12 @@ ], "dependencies": { "bindings": "1.2.1", + "commander": "^2.9.0", "debug": "^2.1.1", "es6-promise": "^3.1.2", "nan": "~2.2.1", "node-pre-gyp": "^0.6.26", - "object.assign": "^4.0.3", - "optimist": "~0.6.1", - "sf": "0.1.7" + "object.assign": "^4.0.3" }, "devDependencies": { "chai": "^3.5.0", diff --git a/test/arduinoTest/serialDuplexTest.js b/test/arduinoTest/serialDuplexTest.js index 2dea68901..d27419b88 100755 --- a/test/arduinoTest/serialDuplexTest.js +++ b/test/arduinoTest/serialDuplexTest.js @@ -8,24 +8,21 @@ To be used in conjunction with the Arduino sketch ArduinoEcho.ino */ 'use strict'; var SerialPort = require('../../').SerialPort; -var optimist = require('optimist'); +var args = require('commander'); -var args = optimist - .alias('h', 'help') - .alias('h', '?') - .usage('Run printable characters through the serial port\n Usage: $0') - .options('p', { - describe: 'Name of serial port. See serialportlist for available serial ports.' - }) - .demand(['p']) - .argv; +args + .usage('-p ') + .description('Run printable characters through the serial port') + .option('-p, --port ', 'Path or Name of serial port. See serialportlist for available serial ports.') + .parse(process.argv); -if (args.help) { - optimist.showHelp(); - return process.exit(0); +if (!args.port) { + args.outputHelp(); + args.missingArgument('port'); + process.exit(-1); } -var port = new SerialPort(args.p); // open the serial port: +var port = new SerialPort(args.port); // open the serial port: var output = 32; // ASCII space; lowest printable character var byteCount = 0; // number of bytes read