class: middle, dark # .big-one[.yellow[Building Interactive npm Command Line Applications]] --- class: middle, light, center # .big-one[,   .brown[NodeFest]] --- class: middle, light, center # .big-one[ I am .brown[[@_lrlna](https://twitter.com/_lrlna)]] --- class: middle, light, center # .big-one[.brown[80%] ] --- class: middle, center, dark #      .yellow-font[-->]     --- class: middle, dark, light # .big-one[.brown[Building Interactive npm Command Line Applications]] --- class: center, middle, light # .align-centre[.brown[I <3] ] --- class: center, middle, light # .align-centre[.brown[4G of Ram]  ] --- class: center, middle, light # .align-centre[.brown[I <3 CLIs]] --- class: middle, light # .brown-font[.javascript[yourCoolCli -rgb global-status --latest -m]] --- class: middle, light # .brown-font[.javascript[tar -xfv /path/to/file]] #### where x === --get --- class: middle, light # .brown-font[.javascript[yourCoolCli -rgb global-status --latest -m]] -- # .yellow[lol wut?] --- class: middle, dark # .yellow[Monday] # .yellow-font[.javascript[yourCoolCli -rgb global-status --latest -m]] --- class: middle, dark # .yellow[Tuesday] # .yellow-font[.javascript[yourCoolCli -rgb global-status --latest -m]] --- class: middle, dark # .yellow[Wednesday] # .yellow-font[.javascript[yourCoolCli -rgb global-status --latest -m]] --- class: middle, dark # .yellow[Thursday] # .yellow-font[.javascript[yourCoolCli -rgb global-status --latest -m]] --- class: center, middle, light    --- class: middle, light # .brown[Friday] # .brown-font[.javascript[yourCoolCli -rgb global-status --latest -m]] --- class: middle, dark # .yellow-font[.javascript[yourCoolCli -rgb global-status --latest -m]] ## .yellow[lol wut?] --- class: middle, light # ,  # .brown[so what's a command line application ?] --- class: middle, light # .brown[git] # .brown-font[.javascript[git rebase i veryCoolSHA]] --- class: middle, light # .brown[npm] # .brown-font[.javascript[npm i coolModule@latest --save]] --- class: middle, light # .brown[vagrant] # .brown-font[.javascript[vagrant halt processID]] --- class: middle, light background-image: url(./src/images/ls.gif) background-size: cover # .yellow[ls] # .yellow-font[.javascript[ls -al]] --- class: middle background-image: url(./src/images/cowsay.gif) background-size: cover # .yellow[cow-say] # .yellow-font[.javascript[cowsay hello nodefest]] .citation[https://www.npmjs.com/package/cowsay] --- class: middle, dark # .yellow[wombat] # .yellow-font[.javascript[wombat hello nodefest]] .citation[https://www.npmjs.com/package/wombatjs] --- class: middle background-image: url(./src/images/wombatjs.gif) background-size: cover .citation[https://www.npmjs.com/package/wombatjs] --- class: middle, dark # ,  # .yellow[so what's a command line application ?] --- class: middle > Command Line Interface is a means of interacting with a computer program where the user *issues commands to the program* in the form of successive lines of text. .blockquote-footer[[the internet](https://en.wikipedia.org/wiki/Command-line_interface)] --- class: middle, light # .brown-font[issues commands to the program] --- class: middle, light # .brown-font[~~issues commands to~~ interacts with the program] --- class: middle, dark # .yellow-font[.javascript[yourCoolCli -rgb global-status --latest -m]] # .yellow[lol wut?] --- class: bottom, center background-image: url(./src/images/excited-baby.gif) background-size: cover --- class: middle, light # .brown[Irina's guide to interactivity™] ### .brown-font[aka level up your CLI skillz] --- class: middle, dark #  .yellow-font[,]  #.yellow[so you want to write a command line module?] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/_lrlna/status/763135592154660864](https://twitter.com/_lrlna/status/763135592154660864)] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/trott/status/763145652368879616](https://twitter.com/trott/status/763145652368879616)] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/ceejbot/status/763140341620801537](https://twitter.com/ceejbot/status/763140341620801537)] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/rickycodes/status/763243646854565888](https://twitter.com/rickycodes/status/763243646854565888)] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/othiym23/status/763144318911512576](https://twitter.com/othiym23/status/763144318911512576)] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/evilchili/status/763172629477859329](https://twitter.com/evilchili/status/763172629477859329)] --- class: middle, dark .twitter-img[] .citation[[https://twitter.com/brianloveswords/status/763245592726401024](https://twitter.com/brianloveswords/status/763245592726401024)] --- class: dark --- class: center, middle, dark # .align-center[ .yellow-font[-------> bash?]] --- class: center, middle, dark # .align-center[ .yellow-font[-------> ruby?]] --- class: center, middle, dark # .align-center[ .yellow-font[-------> perl?]] --- class: center, middle, light # .align-center[ .brown-font[-------> node]] --- class: center, middle # .align-centre[ argument parsing] --- class: middle, dark # .yellow[.javascript[process.argv.slice(2)]] --- class: center, middle background-image: url(./src/images/parser.gif) background-size: cover background-position: left --- class: center, middle, light # .align-center[ .brown-font[------->node]] --- class: middle, light # .brown[Irina's guide to interactivity™] ### .brown-font[aka level up your CLI skillz] --- class: middle, dark # .yellow[Level 1] #  .yellow-font[argument parsing]]]] --- class: bottom background-image: url(./src/images/yargs.png) background-size: cover background-position: left .citation[yargs.js.org] --- background-image: url(./src/images/parser.gif) background-size: cover background-position: left --- class: bottom background-image: url(./src/images/yargs.png) background-size: cover background-position: left .citation[yargs.js.org] --- class: middle, light # .brown[Irina's guide to interactivity™] ### .brown-font[aka level up your CLI skillz] --- class: middle, light # We use .brown[options] on daily basis -- ```shell npm install -g yargs@latest ``` --- class: middle, dark # .yellow[Level 2] # .yellow-font[Give your options] .yellow[aliases] --- class: middle ```javascript var argv = require('yargs') .usage('Usage: $0 -n [string] -f [string]') .option('n', { alias: 'name', describe: 'Twitter name of your choosing', type: 'string', demand: true }) ``` .citation[https://www.npmjs.com/package/twitter-node-name] --- class: middle, dark ```shell twitter-node-name --name ira<2728> ``` # .yellow[or] ```shell twitter-node-name -n ira<2728> ``` .citation[https://www.npmjs.com/package/twitter-node-name] --- class: middle, dark background-image: url(./src/images/twitter-node-name.gif) background-size: cover background-position: left .citation[https://www.npmjs.com/package/twitter-node-name] --- class: middle, dark # .yellow[Level 3] # .yellow-font[Set up] .yellow[default] .yellow-font[values] --- class: middle ```javascript .option("yellow", { alias: "y", describe: "yellow wombat", type: "boolean", default: true }) ``` .citation[https://www.npmjs.com/package/wombatjs] --- class: middle, dark # .yellow[Level 4] # .yellow-font[Provide a] .yellow[help] .yellow-font[menu]  --- class: middle ```javascript var argv = require('yargs') // all your options .help() .argv ``` --- class: middle, dark background-image: url(./src/images/twitter-node-help.gif) background-size: cover background-position: left .citation[[https://www.npmjs.com/package/twitter-node-name](https://www.npmjs.com/package/twitter-node-name)] --- class: middle, light # .brown[
] -- # .brown[--option] -- # .brown[command] -- # .brown[[optional param]] .citation[[http://docopt.org/](http://docopt.org/)] --- class: middle, dark # .yellow[Level 5] # .yellow-font[Get] .yellow[input] .yellow-font[from your users] --- class: middle, light ```javascript prompt.start() var property = { name: "yesno", message: message, validator: /y[es]*|n[o]?/, warning: "Please respond with yer or no", default: "yes" } prompt.get(property, function(err, result) { if (err) console.log(err) done(result) }) ``` --- class: middle, light ```bash prompt: Are you sure you want to overwrite: (yes) ``` --- class: middle, light # .align-center[.brown[wow p cool]  .brown[prompt] ] .citation[https://www.npmjs.com/package/prompt] --- class: middle, light ```javascript // where setuprc is your questions file promzard(setuprc, function(err, data) { // do <2728> magic <2728> with data } // setuprc module.exports = { "displayName": prompt("Hey stranger, what shall you be called?", function(displayName) { return displayName; }) } ``` --- class: middle, light ```bash Hey stranger, what shall you be called?: irina ``` --- class: middle, light # .align-center[.brown[wow p cool]  .brown[prompt] ] .citation[https://www.npmjs.com/package/prompt] --- class: middle, dark # .yellow[Level 6] # .yellow-font[Why not use] .yellow[commands] .yellow-font[?]  --- class: middle, light # .brown-font[We can make options] .brown[descriptive] --- class: middle, light #.brown-font[but they are not] .brown[*interactive*] --- class: middle, light # user issues commands to the program --- class: middle, light # user ~~issues commands to~~ .brown[interact] with the program --- class: middle, light # .align-center[.brown[wow p cool]  .brown[commands] ] .citation[https://www.npmjs.com/package/prompt] --- class: middle, light # .brown[yargs] .brown-font[lets you build out command modules] --- class: middle, light ```javascript yargs.command(require('text')) .help() .argv ``` --- class: middle, light ```javascript exports.command = 'text
' exports.describe = 'text message your contact' exports.builder = { contact: { default: 'mom' }, message: { default: 'brunch on sunday?' } } exports.handler = function (argv) { // do <2728> magic <2728> } ``` --- class: middle, dark # .yellow[Level 7] # .yellow-font[Just add] .yellow[colour]  --- class: middle, light # .align-center[.brown[wow p cool]  .brown[colour] ] .citation[https://www.npmjs.com/package/cli-color] --- class: middle, light ```javascript clc.yellow(wombat + concatArgvs(argv._)) ``` --- class: middle, light # .align-center[.brown[wow p cool]  .brown[colour] ] .citation[https://www.npmjs.com/package/chalk] --- class: middle, light ```javascript chalk.yellow(wombat + concatArgvs(argv._)) ``` --- class: middle, dark # .yellow[Level 8] # .yellow-font[Can we get the user to] .yellow[interact] .yellow-font[with the program other than prompts?] --- class: middle, light # .align-center[.brown[wow p cool]  .brown[inquirer] ] .citation[https://www.npmjs.com/package/inquirer] --- class: middle, light ```javascript var prompt = inquirer.createPromptModule(); prompt({type: 'list', message: 'yourCoolQuestionPrompt' }) .then(// do <2728> magic <2728>); //{type: 'list'} //{type: 'checkbox'} ``` --- background-image: url(./src/images/magic.gif) background-size: cover class: bottom, center # .brown[alt='magic'] --- class: middle, dark --- class: middle, light # .brown[Get out there, and build command line interfaces] --- class: middle, dark # .big-one[.yellow[Thank you] ] ## .yellow[[@_lrlna](https://twitter.com/_lrlna)] ## .yellow[lrlna.github.io/nodefest-2016]