Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 2e695809d3ff61af6e7acd9e476da8d755841bf3 0 parents
@abi authored
56 .gitignore
@@ -0,0 +1,56 @@
+# Assembled from https://github.com/github/gitignore
+
+#Linux
+
+.* # LOOK HERE (BE VERY CAREFUL ABOUT THIS. IT IGNORES ALL DOTFILES OTHER THAN .gitignore and .npmignore)
+!.gitignore
+!.npmignore
+*~
+
+# KDE
+.directory
+
+#OS X
+
+.DS_Store
+Icon?
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+#Textmate
+
+*.tmproj
+*.tmproject
+tmtags
+
+#Vim
+
+.*.sw[a-z]
+*.un~
+Session.vim
+
+#Emacs
+
+*~
+#*#
+/.emacs.desktop
+/.emacs.desktop.lock
+.elc
+auto-save-list
+tramp
+
+# Remnants when using npm
+npm-debug.log
+
+# Remnants when using `npm link` while using this module
+node_modules
+
+# Module-specific
+
+# example.coffee might leave this file in the root dir if it errors out in the middle
+TEST
0  .npmignore
No changes.
24 Cakefile
@@ -0,0 +1,24 @@
+{spawn} = require 'child_process'
+
+log = console.log
+
+run = (cmd) ->
+ log "#{cmd}"
+ [cmd, args...] = cmd.split ' '
+ proc = spawn cmd, args
+ proc.stdin.end()
+ proc.stdout.on 'data', (data) -> log data.toString()
+ proc.stderr.on 'data', (data) -> log data.toString()
+
+task 'build', ->
+ run 'coffee -o lib -c src/node_util.coffee'
+
+task 'test', ->
+ run 'npm test'
+
+task 'bt', ->
+ run 'coffee -o lib -c src/node_util.coffee'
+ run 'npm test'
+
+task 'docs', ->
+ run 'docco src/node_util.coffee'
15 LICENSE
@@ -0,0 +1,15 @@
+Copyright (c) 2011 Abi <abii@stanford.edu>
+
+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:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+the Software.
+
+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.
33 README.md
@@ -0,0 +1,33 @@
+node_util
+======
+
+Utilities that help you write Node programs and in particular, CLI scripts easily.
+
+Goals
+=====
+
+Usage
+=====
+
+In JS,
+
+```javascript
+node_util = require('node_util').sync()
+read = node_util.read
+mv = node_util.mv
+```
+
+In Coffee, destructuring makes usage even more pleasant
+```coffee
+{mv, read, rm_r, get} = require('node_util').sync()
+```
+
+See [[examples/example.coffee]] for more.
+
+TODO
+====
+
+* Add async() that returns the async version of everything
+* Helper for mkdir -p
+* Helper for running something in the current TTY
+* Interactive examples?
186 docs/docco.css
@@ -0,0 +1,186 @@
+/*--------------------- Layout and Typography ----------------------------*/
+body {
+ font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+ font-size: 15px;
+ line-height: 22px;
+ color: #252519;
+ margin: 0; padding: 0;
+}
+a {
+ color: #261a3b;
+}
+ a:visited {
+ color: #261a3b;
+ }
+p {
+ margin: 0 0 15px 0;
+}
+h1, h2, h3, h4, h5, h6 {
+ margin: 0px 0 15px 0;
+}
+ h1 {
+ margin-top: 40px;
+ }
+#container {
+ position: relative;
+}
+#background {
+ position: fixed;
+ top: 0; left: 525px; right: 0; bottom: 0;
+ background: #f5f5ff;
+ border-left: 1px solid #e5e5ee;
+ z-index: -1;
+}
+#jump_to, #jump_page {
+ background: white;
+ -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
+ -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
+ font: 10px Arial;
+ text-transform: uppercase;
+ cursor: pointer;
+ text-align: right;
+}
+#jump_to, #jump_wrapper {
+ position: fixed;
+ right: 0; top: 0;
+ padding: 5px 10px;
+}
+ #jump_wrapper {
+ padding: 0;
+ display: none;
+ }
+ #jump_to:hover #jump_wrapper {
+ display: block;
+ }
+ #jump_page {
+ padding: 5px 0 3px;
+ margin: 0 0 25px 25px;
+ }
+ #jump_page .source {
+ display: block;
+ padding: 5px 10px;
+ text-decoration: none;
+ border-top: 1px solid #eee;
+ }
+ #jump_page .source:hover {
+ background: #f5f5ff;
+ }
+ #jump_page .source:first-child {
+ }
+table td {
+ border: 0;
+ outline: 0;
+}
+ td.docs, th.docs {
+ max-width: 450px;
+ min-width: 450px;
+ min-height: 5px;
+ padding: 10px 25px 1px 50px;
+ overflow-x: hidden;
+ vertical-align: top;
+ text-align: left;
+ }
+ .docs pre {
+ margin: 15px 0 15px;
+ padding-left: 15px;
+ }
+ .docs p tt, .docs p code {
+ background: #f8f8ff;
+ border: 1px solid #dedede;
+ font-size: 12px;
+ padding: 0 0.2em;
+ }
+ .pilwrap {
+ position: relative;
+ }
+ .pilcrow {
+ font: 12px Arial;
+ text-decoration: none;
+ color: #454545;
+ position: absolute;
+ top: 3px; left: -20px;
+ padding: 1px 2px;
+ opacity: 0;
+ -webkit-transition: opacity 0.2s linear;
+ }
+ td.docs:hover .pilcrow {
+ opacity: 1;
+ }
+ td.code, th.code {
+ padding: 14px 15px 16px 25px;
+ width: 100%;
+ vertical-align: top;
+ background: #f5f5ff;
+ border-left: 1px solid #e5e5ee;
+ }
+ pre, tt, code {
+ font-size: 12px; line-height: 18px;
+ font-family: Monaco, Consolas, "Lucida Console", monospace;
+ margin: 0; padding: 0;
+ }
+
+
+/*---------------------- Syntax Highlighting -----------------------------*/
+td.linenos { background-color: #f0f0f0; padding-right: 10px; }
+span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
+body .hll { background-color: #ffffcc }
+body .c { color: #408080; font-style: italic } /* Comment */
+body .err { border: 1px solid #FF0000 } /* Error */
+body .k { color: #954121 } /* Keyword */
+body .o { color: #666666 } /* Operator */
+body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+body .cp { color: #BC7A00 } /* Comment.Preproc */
+body .c1 { color: #408080; font-style: italic } /* Comment.Single */
+body .cs { color: #408080; font-style: italic } /* Comment.Special */
+body .gd { color: #A00000 } /* Generic.Deleted */
+body .ge { font-style: italic } /* Generic.Emph */
+body .gr { color: #FF0000 } /* Generic.Error */
+body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+body .gi { color: #00A000 } /* Generic.Inserted */
+body .go { color: #808080 } /* Generic.Output */
+body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+body .gs { font-weight: bold } /* Generic.Strong */
+body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+body .gt { color: #0040D0 } /* Generic.Traceback */
+body .kc { color: #954121 } /* Keyword.Constant */
+body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
+body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
+body .kp { color: #954121 } /* Keyword.Pseudo */
+body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
+body .kt { color: #B00040 } /* Keyword.Type */
+body .m { color: #666666 } /* Literal.Number */
+body .s { color: #219161 } /* Literal.String */
+body .na { color: #7D9029 } /* Name.Attribute */
+body .nb { color: #954121 } /* Name.Builtin */
+body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+body .no { color: #880000 } /* Name.Constant */
+body .nd { color: #AA22FF } /* Name.Decorator */
+body .ni { color: #999999; font-weight: bold } /* Name.Entity */
+body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+body .nf { color: #0000FF } /* Name.Function */
+body .nl { color: #A0A000 } /* Name.Label */
+body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+body .nt { color: #954121; font-weight: bold } /* Name.Tag */
+body .nv { color: #19469D } /* Name.Variable */
+body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+body .w { color: #bbbbbb } /* Text.Whitespace */
+body .mf { color: #666666 } /* Literal.Number.Float */
+body .mh { color: #666666 } /* Literal.Number.Hex */
+body .mi { color: #666666 } /* Literal.Number.Integer */
+body .mo { color: #666666 } /* Literal.Number.Oct */
+body .sb { color: #219161 } /* Literal.String.Backtick */
+body .sc { color: #219161 } /* Literal.String.Char */
+body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
+body .s2 { color: #219161 } /* Literal.String.Double */
+body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+body .sh { color: #219161 } /* Literal.String.Heredoc */
+body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+body .sx { color: #954121 } /* Literal.String.Other */
+body .sr { color: #BB6688 } /* Literal.String.Regex */
+body .s1 { color: #219161 } /* Literal.String.Single */
+body .ss { color: #19469D } /* Literal.String.Symbol */
+body .bp { color: #954121 } /* Name.Builtin.Pseudo */
+body .vc { color: #19469D } /* Name.Variable.Class */
+body .vg { color: #19469D } /* Name.Variable.Global */
+body .vi { color: #19469D } /* Name.Variable.Instance */
+body .il { color: #666666 } /* Literal.Number.Integer.Long */
4 docs/node_util.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html> <html> <head> <title>node_util.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> node_util.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">&#182;</a> </div> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">&#182;</a> </div> <h2>Aliases</h2> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">&#182;</a> </div> <h2>Child process utilities</h2> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">&#182;</a> </div> <p>Runs as a sub-process (important to note that it does not run this in a shell)</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">&#182;</a> </div> <h2>HTTP utilities</h2> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">&#182;</a> </div> <p>NOTE: This seems redundant
+The only place where this might be meaningful is when
+TODO: Import all the other methods from request too</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">&#182;</a> </div> <h2>File system utilities</h2> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">&#182;</a> </div> <p>Removes the dir located at <code>path</code> and all it's sub-dirs. If the path does not exist, then this does not do anything
+and returns successfully. Based off [[ryanmcgrath/wrench-js]]</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">&#182;</a> </div> <p>If the directory doesn't exist, then return success</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">&#182;</a> </div> <p>Empty this directory </p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">&#182;</a> </div> <p>Remove the directory and return the return value of that system call</p> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">&#182;</a> </div> <h2>Exports</h2> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">&#182;</a> </div> <h1>#</h1> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">&#182;</a> </div> <h1>#</h1> </td> <td class="code"> <div class="highlight"><pre>undefined</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>
18 examples/example.coffee
@@ -0,0 +1,18 @@
+{read, rm, write, exists, ls, get} = require('../lib/node_util').sync()
+{equal, ok} = require 'assert'
+
+eq = equal
+
+write 'TEST', 'Hola world!'
+eq read('TEST'), 'Hola world!'
+eq ('TEST' in ls('.')), true
+rm 'TEST'
+eq ('TEST' in ls('.')), false
+eq exists('TESTS'), false
+
+get 'http://google.com', (err, res, body) ->
+ ok body.substr('google') isnt -1
+
+# post url, {json : },
+
+
76 lib/node_util.js
@@ -0,0 +1,76 @@
+(function() {
+ var fs, get, log, path, post, put, request, rmdirRecursiveSync, run, spawn;
+ var __slice = Array.prototype.slice;
+ spawn = require('child_process').spawn;
+ fs = require('fs');
+ path = require('path');
+ request = require('request');
+ log = console.log;
+ run = function(cmd) {
+ var args, proc, _ref;
+ log("" + cmd);
+ _ref = cmd.split(' '), cmd = _ref[0], args = 2 <= _ref.length ? __slice.call(_ref, 1) : [];
+ proc = spawn(cmd, args);
+ proc.stdin.end();
+ proc.stdout.on('data', function(data) {
+ return log(data.toString());
+ });
+ return proc.stderr.on('data', function(data) {
+ return log(data.toString());
+ });
+ };
+ post = request.post;
+ get = request.get;
+ put = request.put;
+ rmdirRecursiveSync = function(dirPath) {
+ var currFile, currFilePath, file, _i, _len, _ref;
+ if (!path.existsSync(dirPath)) {
+ return true;
+ }
+ _ref = fs.readdirSync(dirPath);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ file = _ref[_i];
+ currFilePath = dirPath + "/" + file;
+ currFile = fs.statSync(currFilePath);
+ if (currFile.isDirectory()) {
+ rmdirRecursiveSync(currFilePath);
+ } else if (currFile.isSymbolicLink()) {
+ fs.unlinkSync(currFilePath);
+ } else {
+ fs.unlinkSync(currFilePath);
+ }
+ }
+ return fs.rmdirSync(dirPath);
+ };
+ /*
+ The way you would use this module is as follows:
+
+ In JS,
+ node_util = require('node_util').sync()
+ read = node_util.read
+ mv = node_util.mv
+
+ In Coffee, destructuring makes usage even more pleasant
+ {mv, read, rm_r} = require('node_util').sync()
+
+ */
+ exports.sync = function() {
+ return {
+ mv: fs.renameSync,
+ read: fs.readFileSync,
+ cat: fs.readFileSync,
+ write: fs.writeFileSync,
+ mkdir: fs.mkdirSync,
+ rm: fs.unlinkSync,
+ remove: fs.unlinkSync,
+ rm_r: rmdirRecursiveSync,
+ rmdirRecursiveSync: rmdirRecursiveSync,
+ join: path.join,
+ exec: run,
+ ls: fs.readdirSync,
+ exists: path.existsSync,
+ post: post,
+ get: get
+ };
+ };
+}).call(this);
39 package.json
@@ -0,0 +1,39 @@
+{
+ "name": "node_util",
+ "version": "0.0.1",
+ "description": "Utilities that help you write Node programs and in particular, CLI scripts easily.",
+ "keywords": [
+ "file system",
+ "fs",
+ "utilities",
+ "cli"
+ ],
+ "author": "Abi <abii@stanford.edu> (http://abi.sh)",
+ "licenses": [
+ {
+ "type": "MIT"
+ }
+ ],
+ "scripts": {
+ "prepublish": "coffee -o lib/ -c ./src/node_util.coffee",
+ "test": "coffee examples/example.coffee"
+ },
+ "dependencies": {
+ "request": "2.x"
+ },
+ "main": "./lib/node_util.js",
+ "engines": {
+ "node": ">=0.4.x"
+ },
+ "directories": {
+ "example": "./examples",
+ "lib": "./src"
+ },
+ "devDependencies": {
+ "coffee-script": ""
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/abi/ostutil.git"
+ }
+}
1  src/.gitignore
@@ -0,0 +1 @@
+.js
90 src/node_util.coffee
@@ -0,0 +1,90 @@
+{spawn} = require 'child_process'
+fs = require 'fs'
+path = require 'path'
+request = require 'request'
+
+# Aliases
+# -------
+
+log = console.log
+
+# Child process utilities
+# -----------------------
+
+# Runs as a sub-process (important to note that it does not run this in a shell)
+run = (cmd) ->
+ log "#{cmd}"
+ [cmd, args...] = cmd.split ' '
+ proc = spawn cmd, args
+ proc.stdin.end()
+ proc.stdout.on 'data', (data) -> log data.toString()
+ proc.stderr.on 'data', (data) -> log data.toString()
+
+
+# HTTP utilities
+# --------------
+
+# NOTE: This seems redundant
+# The only place where this might be meaningful is when
+# TODO: Import all the other methods from request too
+post = request.post
+get = request.get
+put = request.put
+
+# File system utilities
+# ---------------------
+
+# Removes the dir located at `path` and all it's sub-dirs. If the path does not exist, then this does not do anything
+# and returns successfully. Based off [[ryanmcgrath/wrench-js]]
+rmdirRecursiveSync = (dirPath) ->
+ # If the directory doesn't exist, then return success
+ if not path.existsSync dirPath
+ return true
+
+ # Empty this directory
+ for file in fs.readdirSync(dirPath)
+ currFilePath = dirPath + "/" + file
+ currFile = fs.statSync currFilePath
+
+ if currFile.isDirectory()
+ rmdirRecursiveSync currFilePath
+ else if currFile.isSymbolicLink()
+ fs.unlinkSync currFilePath
+ else
+ fs.unlinkSync currFilePath
+
+ # Remove the directory and return the return value of that system call
+ return fs.rmdirSync dirPath
+
+# Exports
+# -------
+
+###
+The way you would use this module is as follows:
+
+In JS,
+node_util = require('node_util').sync()
+read = node_util.read
+mv = node_util.mv
+
+In Coffee, destructuring makes usage even more pleasant
+{mv, read, rm_r} = require('node_util').sync()
+
+###
+
+exports.sync = () ->
+ mv : fs.renameSync
+ read : fs.readFileSync
+ cat : fs.readFileSync
+ write : fs.writeFileSync
+ mkdir : fs.mkdirSync
+ rm : fs.unlinkSync # Will fail if the directory is not empty
+ remove : fs.unlinkSync
+ rm_r : rmdirRecursiveSync
+ rmdirRecursiveSync : rmdirRecursiveSync
+ join : path.join
+ exec : run
+ ls : fs.readdirSync
+ exists : path.existsSync
+ post : post
+ get : get
Please sign in to comment.
Something went wrong with that request. Please try again.