Skip to content

Instantly share code, notes, and snippets.

@duncanbeevers
Created July 10, 2014 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duncanbeevers/c8c8ba125a730693861e to your computer and use it in GitHub Desktop.
Save duncanbeevers/c8c8ba125a730693861e to your computer and use it in GitHub Desktop.
<!DOCTYPE html><html class=""><head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>chriso/cli · GitHub</title><link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"><link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"><link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-114.png"><link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114.png"><link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-144.png"><link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144.png"><meta property="fb:app_id" content="1401488693436528"><meta content="@github" name="twitter:site"><meta
content="summary" name="twitter:card"><meta content="chriso/cli" name="twitter:title"><meta content="cli - Rapidly build command line apps with node" name="twitter:description"><meta content="https://avatars2.githubusercontent.com/u/364903?s=400" name="twitter:image:src"><meta content="GitHub" property="og:site_name"><meta content="object" property="og:type"><meta content="https://avatars2.githubusercontent.com/u/364903?s=400" property="og:image"><meta content="chriso/cli" property="og:title"><meta content="https://github.com/chriso/cli" property="og:url"><meta content="cli - Rapidly build command line apps with node" property="og:description"><link rel="assets" href="https://assets-cdn.github.com/"><link rel="conduit-xhr" href="https://ghconduit.com:25035"><meta name="msapplication-TileImage" content="/windows-tile.png"><meta name="msapplication-TileColor" content="#ffffff"><meta
name="selected-link" value="repo_source" data-pjax-transient><meta name="google-analytics" content="UA-3769691-2"><meta content="collector.githubapp.com" name="octolytics-host"><meta content="collector-cdn.github.com" name="octolytics-script-host"><meta content="github" name="octolytics-app-id"><meta content="BDF36887:1161:2258897:53BDE737" name="octolytics-dimension-request_id"><link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico"><meta content="authenticity_token" name="csrf-param"><meta content="T1/CUHPgiEP8/U2Sc8xxGYuLm8BSNZOG3GwWuxA6Yzgf7iqgL7wejcC5PcT8y6lMqGMYLU/ZHsYnHYj1xLjLvQ==" name="csrf-token"><link href="https://assets-cdn.github.com/assets/github-2821c1ad898ad75485178fc4b9beac83d34a8130.css" media="all" rel="stylesheet" type="text/css"><link href="https://assets-cdn.github.com/assets/github2-0152c570f8653ad45619957f2eee5eb4bca8a6c7.css"
media="all" rel="stylesheet" type="text/css"><meta http-equiv="x-pjax-version" content="a0abe7418133630c82f6eb767eb96352"><meta name="description" content="cli - Rapidly build command line apps with node"><meta content="364903" name="octolytics-dimension-user_id"><meta content="chriso" name="octolytics-dimension-user_login"><meta content="1212062" name="octolytics-dimension-repository_id"><meta content="chriso/cli" name="octolytics-dimension-repository_nwo"><meta content="true" name="octolytics-dimension-repository_public"><meta content="false" name="octolytics-dimension-repository_is_fork"><meta content="1212062" name="octolytics-dimension-repository_network_root_id"><meta content="chriso/cli" name="octolytics-dimension-repository_network_root_nwo"><link href="https://github.com/chriso/cli/commits/master.atom" rel="alternate" title="Recent Commits to cli:master"
type="application/atom+xml"></head><body class="logged_out env-production vis-public"><a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a><div class="wrapper"><div class="header header-logged-out"><div class="container clearfix"><a class="header-logo-wordmark" href="https://github.com/"><span class="mega-octicon octicon-logo-github"></span></a><div class="header-actions"><a class="button primary" href="/join">Sign up</a> <a class="button signin" href="/login?return_to=%2Fchriso%2Fcli">Sign in</a></div><div class="command-bar js-command-bar in-repository"><ul class="top-nav"><li class="explore"><a href="/explore">Explore</a></li><li class="features"><a href="/features">Features</a></li><li class="enterprise"><a href="https://enterprise.github.com/">Enterprise</a></li><li class="blog"><a href="/blog">Blog</a></li></ul><form
accept-charset="UTF-8" action="/search" class="command-bar-form" id="top_search_form" method="get"><div class="commandbar"><span class="message"></span> <input type="text" data-hotkey="s, /" name="q" id="js-command-bar-field" placeholder="Search or type a command" tabindex="1" autocapitalize="off" data-repo="chriso/cli"><div class="display hidden"></div></div><input type="hidden" name="nwo" value="chriso/cli"><div class="select-menu js-menu-container js-select-menu search-context-select-menu"><span class="minibutton select-menu-button js-menu-target" role="button" aria-haspopup="true"><span class="js-select-button">This repository</span></span><div class="select-menu-modal-holder js-menu-content js-navigation-container" aria-hidden="true"><div class="select-menu-modal"><div class="select-menu-item js-navigation-item js-this-repository-navigation-item selected"><span
class="select-menu-item-icon octicon octicon-check"></span> <input type="radio" class="js-search-this-repository" name="search_target" value="repository" checked="checked"><div class="select-menu-item-text js-select-button-text">This repository</div></div><!-- /.select-menu-item --><div class="select-menu-item js-navigation-item js-all-repositories-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <input type="radio" name="search_target" value="global"><div class="select-menu-item-text js-select-button-text">All repositories</div></div><!-- /.select-menu-item --></div></div></div><span class="help tooltipped tooltipped-s" aria-label="Show command bar help"><span class="octicon octicon-question"></span></span> <input type="hidden" name="ref" value="cmdform"></form></div></div></div><div id="start-of-content" class="accessibility-aid"></div><div
class="site" itemscope itemtype="http://schema.org/WebPage"><div id="js-flash-container"></div><div class="pagehead repohead instapaper_ignore readability-menu"><div class="container"><ul class="pagehead-actions"><li><a href="/login?return_to=%2Fchriso%2Fcli" class="minibutton with-count star-button tooltipped tooltipped-n" aria-label="You must be signed in to star a repository" rel="nofollow"><span class="octicon octicon-star"></span> Star</a> <a class="social-count js-social-count" href="/chriso/cli/stargazers">281</a></li><li><a href="/login?return_to=%2Fchriso%2Fcli" class="minibutton with-count js-toggler-target fork-button tooltipped tooltipped-n" aria-label="You must be signed in to fork a repository" rel="nofollow"><span class="octicon octicon-repo-forked"></span> Fork</a> <a href="/chriso/cli/network" class="social-count">24</a></li></ul><h1 itemscope
itemtype="http://data-vocabulary.org/Breadcrumb" class="entry-title public"><span class="repo-label"><span>public</span></span> <span class="mega-octicon octicon-repo"></span> <span class="author"><a href="/chriso" class="url fn" itemprop="url" rel="author"><span itemprop="title">chriso</span></a></span><!--
--><span class="path-divider">/</span><!--
--><strong><a href="/chriso/cli" class="js-current-repository js-repo-home-link">cli</a></strong> <span class="page-context-loader"><img alt="" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></span></h1></div><!-- /.container --></div><!-- /.repohead --><div class="container"><div class="repository-with-sidebar repo-container new-discussion-timeline js-new-discussion-timeline with-full-navigation"><div class="repository-sidebar clearfix"><div
class="sunken-menu vertical-right repo-nav js-repo-nav js-repository-container-pjax js-octicon-loaders"><div class="sunken-menu-contents"><ul class="sunken-menu-group"><li class="tooltipped tooltipped-w" aria-label="Code"><a href="/chriso/cli" aria-label="Code" class="selected js-selected-navigation-item sunken-menu-item" data-hotkey="g c" data-pjax="true" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /chriso/cli"><span class="octicon octicon-code"></span> <span class="full-word">Code</span> <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></a></li><li class="tooltipped tooltipped-w" aria-label="Issues"><a href="/chriso/cli/issues" aria-label="Issues" class="js-selected-navigation-item sunken-menu-item js-disable-pjax" data-hotkey="g i"
data-selected-links="repo_issues /chriso/cli/issues"><span class="octicon octicon-issue-opened"></span> <span class="full-word">Issues</span> <span class="counter">0</span> <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></a></li><li class="tooltipped tooltipped-w" aria-label="Pull Requests"><a href="/chriso/cli/pulls" aria-label="Pull Requests" class="js-selected-navigation-item sunken-menu-item js-disable-pjax" data-hotkey="g p" data-selected-links="repo_pulls /chriso/cli/pulls"><span class="octicon octicon-git-pull-request"></span> <span class="full-word">Pull Requests</span> <span class="counter">0</span> <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></a></li></ul><div class="sunken-menu-separator"></div><ul
class="sunken-menu-group"><li class="tooltipped tooltipped-w" aria-label="Pulse"><a href="/chriso/cli/pulse" aria-label="Pulse" class="js-selected-navigation-item sunken-menu-item" data-pjax="true" data-selected-links="pulse /chriso/cli/pulse"><span class="octicon octicon-pulse"></span> <span class="full-word">Pulse</span> <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></a></li><li class="tooltipped tooltipped-w" aria-label="Graphs"><a href="/chriso/cli/graphs" aria-label="Graphs" class="js-selected-navigation-item sunken-menu-item" data-pjax="true" data-selected-links="repo_graphs repo_contributors /chriso/cli/graphs"><span class="octicon octicon-graph"></span> <span class="full-word">Graphs</span> <img alt="" class="mini-loader" height="16"
src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></a></li><li class="tooltipped tooltipped-w" aria-label="Network"><a href="/chriso/cli/network" aria-label="Network" class="js-selected-navigation-item sunken-menu-item js-disable-pjax" data-selected-links="repo_network /chriso/cli/network"><span class="octicon octicon-repo-forked"></span> <span class="full-word">Network</span> <img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></a></li></ul></div></div><div class="only-with-full-nav"><div class="clone-url open" data-protocol-type="http" data-url="/users/set_protocol?protocol_selector=http&amp;protocol_type=clone"><h3><strong>HTTPS</strong> clone URL</h3><div class="clone-url-box"><input type="text" class="clone js-url-field" value="https://github.com/chriso/cli.git"
readonly="readonly"> <span class="url-box-clippy"><button aria-label="Copy to clipboard" class="js-zeroclipboard minibutton zeroclipboard-button" data-clipboard-text="https://github.com/chriso/cli.git" data-copied-hint="Copied!" type="button"><span class="octicon octicon-clippy"></span></button></span></div></div><div class="clone-url" data-protocol-type="subversion" data-url="/users/set_protocol?protocol_selector=subversion&amp;protocol_type=clone"><h3><strong>Subversion</strong> checkout URL</h3><div class="clone-url-box"><input type="text" class="clone js-url-field" value="https://github.com/chriso/cli" readonly="readonly"> <span class="url-box-clippy"><button aria-label="Copy to clipboard" class="js-zeroclipboard minibutton zeroclipboard-button" data-clipboard-text="https://github.com/chriso/cli" data-copied-hint="Copied!" type="button"><span class="octicon octicon-clippy"></span>
</button></span></div></div><p class="clone-options">You can clone with <a href="#" class="js-clone-selector" data-protocol="http">HTTPS</a> or <a href="#" class="js-clone-selector" data-protocol="subversion">Subversion</a>. <a href="https://help.github.com/articles/which-remote-url-should-i-use" class="help tooltipped tooltipped-n" aria-label="Get help on which URL is right for you."><span class="octicon octicon-question"></span></a></p><a href="/chriso/cli/archive/master.zip" class="minibutton sidebar-button" aria-label="Download chriso/cli as a zip file" title="Download chriso/cli as a zip file" rel="nofollow"><span class="octicon octicon-cloud-download"></span> Download ZIP</a></div></div><!-- /.repository-sidebar --><div id="js-repo-pjax-container" class="repository-content context-loader-container" data-pjax-container><span id="js-show-full-navigation"></span><div
class="repository-meta js-details-container"><div class="repository-description js-details-show"><p>Rapidly build command line apps with node</p></div></div><div class="capped-box overall-summary"><div class="stats-switcher-viewport js-stats-switcher-viewport"><div class="stats-switcher-wrapper"><ul class="numbers-summary"><li class="commits"><a data-pjax href="/chriso/cli/commits/master"><span class="num"><span class="octicon octicon-history"></span> 123</span> commits</a></li><li><a data-pjax href="/chriso/cli/branches"><span class="num"><span class="octicon octicon-git-branch"></span> 1</span> branch</a></li><li><a data-pjax href="/chriso/cli/releases"><span class="num"><span class="octicon octicon-tag"></span> 6</span> releases</a></li><li><a href="/chriso/cli/graphs/contributors"><span class="num"><span class="octicon octicon-organization"></span> 13</span> contributors</a></li>
</ul><div class="repository-lang-stats"><ol class="repository-lang-stats-numbers"><li><a href="/chriso/cli/search?l=javascript"><span class="color-block language-color" style="background-color:#f1e05a"></span> <span class="lang">JavaScript</span> <span class="percent">98.4%</span></a></li><li><a href="/chriso/cli/search?l=coffeescript"><span class="color-block language-color" style="background-color:#244776"></span> <span class="lang">CoffeeScript</span> <span class="percent">1.6%</span></a></li></ol></div></div></div></div><div class="tooltipped tooltipped-s" aria-label="Show language statistics"><a href="#" class="repository-lang-stats-graph js-toggle-lang-stats" style="background-color:#244776"><span class="language-color" style="width:98.4%; background-color:#f1e05a" itemprop="keywords">JavaScript</span><span class="language-color" style="width:1.6%; background-color:#244776"
itemprop="keywords">CoffeeScript</span></a></div><div class="file-navigation in-mid-page"><a href="/chriso/cli/find/master" class="js-show-file-finder minibutton empty-icon tooltipped tooltipped-s right" data-pjax data-hotkey="t" aria-label="Quickly jump between files"><span class="octicon octicon-list-unordered"></span></a> <a href="/chriso/cli/compare" aria-label="Compare, review, create a pull request" class="minibutton compact primary tooltipped tooltipped-s" aria-label="Compare &amp; review" data-pjax><span class="octicon octicon-git-compare"></span></a><div class="select-menu js-menu-container js-select-menu"><span class="minibutton select-menu-button js-menu-target css-truncate" data-hotkey="w" data-master-branch="master" data-ref="master" title="master" role="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true"><span class="octicon octicon-git-branch">
</span> <i>branch:</i> <span class="js-select-button css-truncate-target">master</span></span><div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true"><div class="select-menu-modal"><div class="select-menu-header"><span class="select-menu-title">Switch branches/tags</span> <span class="octicon octicon-x js-menu-close"></span></div><!-- /.select-menu-header --><div class="select-menu-filters"><div class="select-menu-text-filter"><input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="js-filterable-field js-navigation-enable" placeholder="Filter branches/tags"></div><div class="select-menu-tabs"><ul><li class="select-menu-tab"><a href="#" data-tab-filter="branches" class="js-select-menu-tab">Branches</a></li><li class="select-menu-tab"><a href="#" data-tab-filter="tags" class="js-select-menu-tab">
Tags</a></li></ul></div><!-- /.select-menu-tabs --></div><!-- /.select-menu-filters --><div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches"><div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring"><div class="select-menu-item js-navigation-item selected"><span class="select-menu-item-icon octicon octicon-check"></span> <a href="/chriso/cli/tree/master" data-name="master" data-skip-pjax="true" rel="nofollow" class="js-navigation-open select-menu-item-text css-truncate-target" title="master">master</a></div><!-- /.select-menu-item --></div><div class="select-menu-no-results">Nothing to show</div></div><!-- /.select-menu-list --><div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags"><div data-filterable-for="context-commitish-filter-field"
data-filterable-type="substring"><div class="select-menu-item js-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <a href="/chriso/cli/tree/0.6.3" data-name="0.6.3" data-skip-pjax="true" rel="nofollow" class="js-navigation-open select-menu-item-text css-truncate-target" title="0.6.3">0.6.3</a></div><!-- /.select-menu-item --><div class="select-menu-item js-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <a href="/chriso/cli/tree/0.6.2" data-name="0.6.2" data-skip-pjax="true" rel="nofollow" class="js-navigation-open select-menu-item-text css-truncate-target" title="0.6.2">0.6.2</a></div><!-- /.select-menu-item --><div class="select-menu-item js-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <a href="/chriso/cli/tree/0.6.1" data-name="0.6.1" data-skip-pjax="true" rel="nofollow"
class="js-navigation-open select-menu-item-text css-truncate-target" title="0.6.1">0.6.1</a></div><!-- /.select-menu-item --><div class="select-menu-item js-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <a href="/chriso/cli/tree/0.6.0" data-name="0.6.0" data-skip-pjax="true" rel="nofollow" class="js-navigation-open select-menu-item-text css-truncate-target" title="0.6.0">0.6.0</a></div><!-- /.select-menu-item --><div class="select-menu-item js-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <a href="/chriso/cli/tree/0.5.0" data-name="0.5.0" data-skip-pjax="true" rel="nofollow" class="js-navigation-open select-menu-item-text css-truncate-target" title="0.5.0">0.5.0</a></div><!-- /.select-menu-item --><div class="select-menu-item js-navigation-item"><span class="select-menu-item-icon octicon octicon-check"></span> <a
href="/chriso/cli/tree/0.4.5" data-name="0.4.5" data-skip-pjax="true" rel="nofollow" class="js-navigation-open select-menu-item-text css-truncate-target" title="0.4.5">0.4.5</a></div><!-- /.select-menu-item --></div><div class="select-menu-no-results">Nothing to show</div></div><!-- /.select-menu-list --></div><!-- /.select-menu-modal --></div><!-- /.select-menu-modal-holder --></div><!-- /.select-menu --><div class="breadcrumb"><span class="repo-root js-repo-root"><span itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/chriso/cli" data-branch="master" data-direction="back" data-pjax="true" itemscope="url"><span itemprop="title">cli</span></a></span></span><span class="separator">/</span><form action="/login?return_to=%2Fchriso%2Fcli" aria-label="Sign in to make or propose changes" class="js-new-blob-form tooltipped tooltipped-e new-file-link" method="post"><span
aria-label="Sign in to make or propose changes" class="js-new-blob-submit octicon octicon-plus" data-test-id="create-new-git-file" role="button"></span></form></div></div><div class="commit commit-tease js-details-container"><p class="commit-title"><a href="/chriso/cli/commit/19ae97aef733362601ff2e3ae9e44ea452228125" class="message" data-pjax="true" title="0.6.3">0.6.3</a></p><div class="commit-meta"><button aria-label="Copy SHA" class="js-zeroclipboard zeroclipboard-link" data-clipboard-text="19ae97aef733362601ff2e3ae9e44ea452228125" data-copied-hint="copied!" type="button"><span class="octicon octicon-clippy"></span></button> <a href="/chriso/cli/commit/19ae97aef733362601ff2e3ae9e44ea452228125" class="sha-block" data-pjax>latest commit <span class="sha">19ae97aef7</span></a><div class="authorship"><img alt="Chris O&#39;Hara" class="gravatar js-avatar" data-user="364903" height="20"
src="https://avatars1.githubusercontent.com/u/364903?s=140" width="20"> <span class="author-name"><a href="/chriso" rel="author">chriso</a></span> authored <time class="updated" datetime="2014-06-03T09:00:04+07:00" is="relative-time">June 03, 2014</time></div></div></div><div class="file-wrap"><table class="files" data-pjax><tbody class="" data-url="/chriso/cli/file-list/master" data-deferred-content-error="Failed to load latest commit information."><tr><td class="icon"><span class="octicon octicon-file-directory"></span> <img alt="" class="spinner" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></td><td class="content"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/tree/master/examples" class="js-directory-link" id="bfebe34154a0dfd9fc7b447fc9ed74e9-523911cb59f7b6a7ef013d87aa258979e2c6417b" title="examples">
examples</a></span></td><td class="message"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/commit/92b687f827e979392fa530a0eabcad994c83f0d0" class="message" data-pjax="true" title="Adjust option/command def width in --help">Adjust option/command def width in --help</a></span></td><td class="age"><span class="css-truncate css-truncate-target"><time datetime="2011-05-24T09:51:56Z" is="time-ago">May 24, 2011</time></span></td></tr><tr><td class="icon"><span class="octicon octicon-file-text"></span> <img alt="" class="spinner" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></td><td class="content"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/blob/master/README.md" class="js-directory-link" id="04c6e90faac2675aa89e2176d2eec7d8-6dd8dd5e6a49be0accac0c0142a8870a0df2689c" title="README.md">README.md</a>
</span></td><td class="message"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/commit/2c96ee2e99ed417a300d5cbd9c77d2d30bbcce2f" class="message" data-pjax="true" title="Fix README link, closes #43">Fix README link, closes</a> <a href="https://github.com/chriso/cli/issues/43" class="issue-link" title="cli-min: 404">#43</a></span></td><td class="age"><span class="css-truncate css-truncate-target"><time datetime="2014-04-24T04:53:43Z" is="time-ago">April 24, 2014</time></span></td></tr><tr><td class="icon"><span class="octicon octicon-file-text"></span> <img alt="" class="spinner" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></td><td class="content"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/blob/master/cli.js" class="js-directory-link"
id="2cce40143051e25f811b56c79d619bf5-43bf2adb3a2a5578a11d1644591d0bc9783a5b57" title="cli.js">cli.js</a></span></td><td class="message"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/commit/3f01f502974fd74290e01a4ae4816ae18bc107f1" class="message" data-pjax="true" title="Modified fix for stderr not draining on Windows">Modified fix for stderr not draining on Windows</a></span></td><td class="age"><span class="css-truncate css-truncate-target"><time datetime="2014-05-04T23:47:39Z" is="time-ago">May 04, 2014</time></span></td></tr><tr><td class="icon"><span class="octicon octicon-file-text"></span> <img alt="" class="spinner" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></td><td class="content"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/blob/master/index.js" class="js-directory-link"
id="168726dbe96b3ce427e7fedce31bb0bc-3966bd737bdb10d7b121d72611ca1fd4b97b0d16" title="index.js">index.js</a></span></td><td class="message"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/commit/1b7bf9a4895daa4d116463ad9a06bda0fd80f9d8" class="message" data-pjax="true" title="Fixed handling of large log files">Fixed handling of large log files</a></span></td><td class="age"><span class="css-truncate css-truncate-target"><time datetime="2011-05-02T09:05:36Z" is="time-ago">May 02, 2011</time></span></td></tr><tr><td class="icon"><span class="octicon octicon-file-text"></span> <img alt="" class="spinner" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16"></td><td class="content"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/blob/master/package.json" class="js-directory-link"
id="b9cfc7f2cdf78a7f4b91a753d10865a2-648db77491d75b73a23a4e3e9096bbc23218020e" title="package.json">package.json</a></span></td><td class="message"><span class="css-truncate css-truncate-target"><a href="/chriso/cli/commit/19ae97aef733362601ff2e3ae9e44ea452228125" class="message" data-pjax="true" title="0.6.3">0.6.3</a></span></td><td class="age"><span class="css-truncate css-truncate-target"><time datetime="2014-06-03T02:00:04Z" is="time-ago">June 03, 2014</time></span></td></tr></tbody></table></div><div id="readme" class="clearfix announce instapaper_body md"><span class="name"><span class="octicon octicon-book"></span> README.md</span><article class="markdown-body entry-content" itemprop="mainContentOfPage"><p><strong>cli is a toolkit for rapidly building command line apps - it includes:</strong></p><ul class="task-list"><li>Full featured opts/args parser</li><li>
Plugin support for adding common options and switches</li><li>Helper methods for working with input/output and spawning child processes</li><li>Output colored/styled messages, <a href="https://github.com/chriso/cli/blob/master/examples/progress.js">progress bars</a> or <a href="https://github.com/chriso/cli/blob/master/examples/spinner.js">spinners</a></li><li>Command <a href="https://github.com/chriso/cli/blob/master/examples/command.js">auto-completion</a> and <a href="https://github.com/chriso/cli/blob/master/examples/glob.js">glob support</a></li></ul><p>Install using <code>npm install cli</code> or just bundle <a href="https://github.com/chriso/cli/raw/master/cli.js">cli.js</a> with your app.</p><h2><a name="user-content-example-apps" class="anchor" href="#example-apps" aria-hidden="true"><span class="octicon octicon-link"></span></a>Example apps</h2><h3><a
name="user-content-sortjs" class="anchor" href="#sortjs" aria-hidden="true"><span class="octicon octicon-link"></span></a>sort.js</h3><div class="highlight highlight-javascript"><pre><span class="err">#</span><span class="o">!</span><span class="err">/usr/bin/env node</span>
<span class="nx">require</span><span class="p">(</span><span class="s1">'cli'</span><span class="p">).</span><span class="nx">withStdinLines</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">lines</span><span class="p">,</span> <span class="nx">newline</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">output</span><span class="p">(</span><span class="nx">lines</span><span class="p">.</span><span class="nx">sort</span><span class="p">().</span><span class="nx">join</span><span class="p">
(</span><span class="nx">newline</span><span class="p">));</span>
<span class="p">});</span>
</pre></div><p>Try it out</p><div class="highlight highlight-bash"><pre><span class="nv">$ </span>./sort.js &lt; input.txt
</pre></div><p>Let's add support for an <code>-n</code> switch to use a numeric sort, and a <code>-r</code> switch to reverse output - only 5 extra lines of code (!)</p><div class="highlight highlight-javascript"><pre><span class="kd">var</span> <span class="nx">cli</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'cli'</span><span class="p">),</span> <span class="nx">options</span> <span class="o">=</span> <span class="nx">cli</span><span class="p">.</span><span class="nx">parse</span><span class="p">();</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">withStdinLines</span><span class="p">(
</span><span class="kd">function</span><span class="p">(</span><span class="nx">lines</span><span class="p">,</span> <span class="nx">newline</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">lines</span><span class="p">.</span><span class="nx">sort</span><span class="p">(</span><span class="o">!</span><span class="nx">options</span><span class="p">.</span><span class="nx">n</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">a</span><span class="p">)</span> <span class="o">&gt;</span> <span class="nb">parseInt</span><span class="p">(
</span><span class="nx">b</span><span class="p">);</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">r</span><span class="p">)</span> <span class="nx">lines</span><span class="p">.</span><span class="nx">reverse</span><span class="p">();</span>
<span class="k">this</span><span class="p">.</span><span class="nx">output</span><span class="p">(</span><span class="nx">lines</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">newline</span><span class="p">));</span>
<span class="p">});</span>
</pre></div><h3><a name="user-content-staticjs" class="anchor" href="#staticjs" aria-hidden="true"><span class="octicon octicon-link"></span></a>static.js</h3><p>
Let's create a static file server with daemon support to see the opts parser + plugins in use - note: this requires <code>npm install creationix daemon</code></p><div class="highlight highlight-javascript"><pre><span class="kd">var</span> <span class="nx">cli</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'cli'</span><span class="p">).</span><span class="nx">enable</span><span class="p">(</span><span class="s1">'daemon'</span><span class="p">,</span> <span class="s1">'status'</span><span class="p">);</span> <span class="c1">//Enable 2 plugins</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">parse</span><span class="p">({</span>
<span class="nx">log</span><span class="o">:</span> <span class="p">[</span><span class="s1">'l'</span><span class="p">,</span> <span class="s1">'Enable logging'</span><span
class="p">],</span>
<span class="nx">port</span><span class="o">:</span> <span class="p">[</span><span class="s1">'p'</span><span class="p">,</span> <span class="s1">'Listen on this port'</span><span class="p">,</span> <span class="s1">'number'</span><span class="p">,</span> <span class="mi">8080</span><span class="p">],</span>
<span class="nx">serve</span><span class="o">:</span> <span class="p">[</span><span class="kc">false</span><span class="p">,</span> <span class="s1">'Serve static files from PATH'</span><span class="p">,</span> <span class="s1">'path'</span><span class="p">,</span> <span class="s1">'./public'</span><span class="p">]</span>
<span class="p">});</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">main</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">,
</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">server</span><span class="p">,</span> <span class="nx">middleware</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">log</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">debug</span><span class="p">(</span><span class="s1">'Enabling logging'</span><span class="p">);</span>
<span class="nx">middleware</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">require</span><span class="p">(</span><span class="s1">'creationix/log'</span><span class="p">)());</span>
<span class="p">}
</span>
<span class="k">this</span><span class="p">.</span><span class="nx">debug</span><span class="p">(</span><span class="s1">'Serving files from '</span> <span class="o">+</span> <span class="nx">options</span><span class="p">.</span><span class="nx">serve</span><span class="p">);</span>
<span class="nx">middleware</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">require</span><span class="p">(</span><span class="s1">'creationix/static'</span><span class="p">)(</span><span class="s1">'/'</span><span class="p">,</span> <span class="nx">options</span><span class="p">.</span><span class="nx">serve</span><span class="p">,</span> <span class="s1">'index.html'</span><span class="p">));</span>
<span class="nx">server</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">
createServer</span><span class="p">(</span><span class="nx">middleware</span><span class="p">).</span><span class="nx">listen</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">port</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="s1">'Listening on port '</span> <span class="o">+</span> <span class="nx">options</span><span class="p">.</span><span class="nx">port</span><span class="p">);</span>
<span class="p">});</span>
</pre></div><p>To output usage information</p><div class="highlight highlight-bash"><pre><span class="nv">$ </span>./static.js --help
</pre></div><p>To create a daemon that serves files from <em>/tmp</em>, run</p><div class="highlight highlight-bash"><pre><span class="nv">$ </span>./static.js -ld --serve<span class="o">=
</span>/tmp
</pre></div><p>For more examples, see <a href="https://github.com/chriso/cli/tree/master/examples">./examples</a></p><h2><a name="user-content-helper-methods" class="anchor" href="#helper-methods" aria-hidden="true"><span class="octicon octicon-link"></span></a>Helper methods</h2><p>cli has methods that collect stdin (newline is autodetected as \n or \r\n)</p><div class="highlight highlight-javascript"><pre><span class="nx">cli</span><span class="p">.</span><span class="nx">withStdin</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span> <span class="c1">//callback receives stdin as a string</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">withStdinLines</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span> <span class="c1">
//callback receives stdin split into an array of lines (lines, newline)</span>
</pre></div><p>cli also has a lower level method for working with input line by line (see <a href="https://github.com/chriso/cli/blob/master/examples/cat.js">./examples/cat.js</a> for an example).</p><div class="highlight highlight-javascript"><pre><span class="nx">cli</span><span class="p">.</span><span class="nx">withInput</span><span class="p">(</span><span class="nx">file</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">line</span><span class="p">,</span> <span class="nx">newline</span><span class="p">,</span> <span class="nx">eof</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">eof</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">output</span><span class="p">(</span><span class="nx">line</span> <span class="o">+</span> <span class="nx">newline</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre></div><p><em>Note: <code>file</code> can be omitted if you want to work with stdin</em></p><p>To output a progress bar, call</p><div class="highlight highlight-javascript"><pre><span class="nx">cli</span><span class="p">.</span><span class="nx">progress</span><span class="p">(</span><span class="nx">progress</span><span class="p">);</span> <span class="c1">//Where 0 &lt;= progress &lt;= 1</span>
</pre></div><p>To spawn a child process, use</p><div class="highlight highlight-javascript"><pre><span class="nx">cli</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">cmd
</span><span class="p">,</span> <span class="nx">callback</span><span class="p">);</span> <span class="c1">//callback receives the output of the process (split into lines)</span>
</pre></div><p>cli also comes bundled with kof's <a href="https://github.com/kof/node-natives">node-natives</a> (access with cli.native) and creationix' <a href="https://github.com/creationix/stack">stack</a> (access with cli.createServer)</p><h2><a name="user-content-plugins" class="anchor" href="#plugins" aria-hidden="true"><span class="octicon octicon-link"></span></a>Plugins</h2><p>Plugins are a way of adding common opts and can be enabled using</p><div class="highlight highlight-javascript"><pre><span class="nx">cli</span><span class="p">.</span><span class="nx">enable</span><span class="p">(</span><span class="nx">plugin1</span><span class="p">,</span> <span class="p">[</span><span class="nx">plugin2
</span><span class="p">,</span> <span class="p">...]);</span> <span class="c1">//To disable, use the equivalent disable() method</span>
</pre></div><p><strong>help</strong> - <em>enabled by default</em></p><p>Adds <code>-h,--help</code> to output auto-generated usage information</p><p><strong>version</strong></p><p>Adds <code>-v,--version</code> to output version information for the app. cli will attempt to locate and parse a nearby <em>package.json</em></p><p>To set your own app name and version, use <code>cli.setApp(app_name, version)</code></p><p><strong>status</strong></p><p>Adds options to show/hide the stylized status messages that are output to the console when using one of these methods</p><div class="highlight highlight-javascript"><pre><span class="nx">cli</span><span class="p">.</span><span class="nx">debug</span><span class="p">(</span><span class="nx">msg</span><span
class="p">);</span> <span class="c1">//Only shown when using --debug</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">fatal</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span> <span class="c1">//Exits the process after outputting msg</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span>
<span class="nx">cli</span><span class="p">.</span><span class="nx">ok</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span>
</pre></div><p><code>-k,--no-color</code> will omit ANSI color escapes from the output</p><p><strong>glob</strong> - <em>requires
</em> <code>npm install glob</code></p><p>Enables glob matching of arguments</p><p><strong>daemon</strong> - <em>requires</em> <code>npm install daemon</code></p><p>Adds <code>-d,--daemon ARG</code> for daemonizing the process and controlling the resulting daemon</p><p><code>ARG</code> can be either start (default), stop, restart, pid (outputs the daemon's pid if it's running), or log (output the daemon's stdout+stderr)</p><p><strong>timeout</strong></p><p>Adds <code>-t,--timeout N</code> to exit the process after N seconds with an error</p><p><strong>catchall</strong></p><p>Adds <code>-c,--catch</code> to catch and output uncaughtExceptions and resume execution</p><p><em>Note: Plugins are automatically disabled if an option or switch of the same name is already defined</em></p><h2><a name="user-content-license" class="anchor" href="#license" aria-hidden="true"><span
class="octicon octicon-link"></span></a>LICENSE</h2><p>(MIT license)</p><p>Copyright (c) 2010 Chris O'Hara <a href="mailto:cohara87@gmail.com">cohara87@gmail.com</a></p><p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p><p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p><p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p></article></div></div></div><!-- /.repo-container --><div class="modal-backdrop"></div></div><!-- /.container --></div><!-- /.site --></div><!-- /.wrapper --><div class="container"><div class="site-footer"><ul class="site-footer-links right"><li><a href="https://status.github.com/">Status</a></li><li><a href="http://developer.github.com">API</a></li><li><a href="http://training.github.com">Training</a></li><li><a
href="http://shop.github.com">Shop</a></li><li><a href="/blog">Blog</a></li><li><a href="/about">About</a></li></ul><a href="/"><span class="mega-octicon octicon-mark-github" title="GitHub"></span></a><ul class="site-footer-links"><li>&copy; 2014 <span title="0.07717s from github-fe117-cp1-prd.iad.github.net">GitHub</span>, Inc.</li><li><a href="/site/terms">Terms</a></li><li><a href="/site/privacy">Privacy</a></li><li><a href="/security">Security</a></li><li><a href="/contact">Contact</a></li></ul></div><!-- /.site-footer --></div><!-- /.container --><div class="fullscreen-overlay js-fullscreen-overlay" id="fullscreen_overlay"><div class="fullscreen-container js-fullscreen-container"><div class="textarea-wrap"><textarea name="fullscreen-contents" id="fullscreen-contents" class="fullscreen-contents js-fullscreen-contents" placeholder="" data-suggester="fullscreen_suggester"></textarea>
</div></div><div class="fullscreen-sidebar"><a href="#" class="exit-fullscreen js-exit-fullscreen tooltipped tooltipped-w" aria-label="Exit Zen Mode"><span class="mega-octicon octicon-screen-normal"></span></a> <a href="#" class="theme-switcher js-theme-switcher tooltipped tooltipped-w" aria-label="Switch themes"><span class="octicon octicon-color-mode"></span></a></div></div><div id="ajax-error-message" class="flash flash-error"><span class="octicon octicon-alert"></span> <a href="#" class="octicon octicon-x close js-ajax-error-dismiss" aria-label="Dismiss error"></a> Something went wrong with that request. Please try again.</div><script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-df9e4beac80276ed3dfa56be0d97b536d0f5ee12.js" type="text/javascript"></script><script async="async" crossorigin="anonymous"
src="https://assets-cdn.github.com/assets/github-6c36c982823a9c1da510bdce51ffed16220c48ed.js" type="text/javascript"></script><script async src="https://www.google-analytics.com/analytics.js"></script></body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment