diff --git a/README.md b/README.md index c8762a3..91988c2 100644 --- a/README.md +++ b/README.md @@ -150,9 +150,11 @@ All commands run synchronously, unless otherwise stated. ### cd('dir') Changes to directory `dir` for the duration of the script + ### pwd() Returns the current directory. + ### ls([options ,] path [,path ...]) ### ls([options ,] path_array) Available options: @@ -170,6 +172,7 @@ ls('-R', ['/users/me', '/tmp']); // same as above Returns array of files in the given path, or in current directory if no path provided. + ### find(path [,path ...]) ### find(path_array) Examples: @@ -185,6 +188,7 @@ Returns array of all files (however deep) in the given paths. The main difference from `ls('-R', path)` is that the resulting file names include the base directories, e.g. `lib/resources/file1` instead of just `file1`. + ### cp([options ,] source [,source ...], dest) ### cp([options ,] source_array, dest) Available options: @@ -202,6 +206,7 @@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above Copies files. The wildcard `*` is accepted. + ### rm([options ,] file [, file ...]) ### rm([options ,] file_array) Available options: @@ -219,6 +224,7 @@ rm(['some_file.txt', 'another_file.txt']); // same as above Removes files. The wildcard `*` is accepted. + ### mv(source [, source ...], dest') ### mv(source_array, dest') Available options: @@ -235,6 +241,7 @@ mv(['file1', 'file2'], 'dir/'); // same as above Moves files. The wildcard `*` is accepted. + ### mkdir([options ,] dir [, dir ...]) ### mkdir([options ,] dir_array) Available options: @@ -250,6 +257,7 @@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above Creates directories. + ### test(expression) Available expression primaries: @@ -266,11 +274,12 @@ Examples: ```javascript if (test('-d', path)) { /* do something with dir */ }; -if (!test('-f', path)) continue; // skip if it's not a regular file +if (!test('-f', path)) continue; // skip if it's a regular file ``` Evaluates expression using the available primaries and returns corresponding value. + ### cat(file [, file ...]) ### cat(file_array) @@ -286,6 +295,7 @@ Returns a string containing the given file, or a concatenated string containing the files if more than one file is given (a new line character is introduced between each file). Wildcard `*` accepted. + ### 'string'.to(file) Examples: @@ -297,6 +307,7 @@ cat('input.txt').to('output.txt'); Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ + ### sed([options ,] search_regex, replace_str, file) Available options: @@ -312,6 +323,7 @@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); Reads an input string from `file` and performs a JavaScript `replace()` on the input using the given search regex and replacement string. Returns the new string after replacement. + ### grep([options ,] regex_filter, file [, file ...]) ### grep([options ,] regex_filter, file_array) Available options: @@ -328,6 +340,7 @@ grep('GLOBAL_VARIABLE', '*.js'); Reads input string from given files and returns a string containing all lines of the file that match the given `regex_filter`. Wildcard `*` accepted. + ### which(command) Examples: @@ -339,6 +352,7 @@ var nodeExec = which('node'); Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions. Returns string containing the absolute path to the command. + ### echo(string [,string ...]) Examples: @@ -351,20 +365,6 @@ var str = echo('hello world'); Prints string to stdout, and returns string with additional utility methods like `.to()`. -### dirs([options | '+N' | '-N']) - -Available options: - -+ `-c`: Clears the directory stack by deleting all of the elements. - -Arguments: - -+ `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero. -+ `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. - -Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified. - -See also: pushd, popd ### pushd([options,] [dir | '-N' | '+N']) @@ -411,6 +411,22 @@ echo(process.cwd()); // '/usr' When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack. +### dirs([options | '+N' | '-N']) + +Available options: + ++ `-c`: Clears the directory stack by deleting all of the elements. + +Arguments: + ++ `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero. ++ `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. + +Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified. + +See also: pushd, popd + + ### exit(code) Exits the current process with the given exit code. @@ -448,6 +464,7 @@ the `callback` gets the arguments `(code, output)`. the current synchronous implementation uses a lot of CPU. This should be getting fixed soon. + ### chmod(octal_mode || octal_string, file) ### chmod(symbolic_mode, file) @@ -461,7 +478,7 @@ Examples: ```javascript chmod(755, '/Users/brandon'); -chmod('755', '/Users/brandon'); // same as above +chmod('755', '/Users/brandon'); // same as above chmod('u+x', '/Users/brandon'); ``` @@ -474,6 +491,20 @@ Notable exceptions: given to the umask. + There is no "quiet" option since default behavior is to run silent. + +## Non-Unix commands + + +### tempdir() +Searches and returns string containing a writeable, platform-dependent temporary directory. +Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). + + +### error() +Tests if error occurred in the last command. Returns `null` if no error occurred, +otherwise returns string explaining the error + + ## Configuration @@ -500,14 +531,3 @@ cp('this_file_does_not_exist', '/dev/null'); // dies here ``` If `true` the script will die on errors. Default is `false`. - -## Non-Unix commands - - -### tempdir() -Searches and returns string containing a writeable, platform-dependent temporary directory. -Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). - -### error() -Tests if error occurred in the last command. Returns `null` if no error occurred, -otherwise returns string explaining the error diff --git a/scripts/docs.js b/scripts/generate-docs.js similarity index 70% rename from scripts/docs.js rename to scripts/generate-docs.js index 68a2138..532fed9 100755 --- a/scripts/docs.js +++ b/scripts/generate-docs.js @@ -7,6 +7,12 @@ cd(__dirname + '/..'); // Extract docs from shell.js var docs = grep('//@', 'shell.js'); + +docs = docs.replace(/\/\/\@include (.+)/g, function(match, path) { + var file = path.match('.js$') ? path : path+'.js'; + return grep('//@', file); +}); + // Remove '//@' docs = docs.replace(/\/\/\@ ?/g, ''); // Append docs to README diff --git a/shell.js b/shell.js index ffd468f..830221a 100644 --- a/shell.js +++ b/shell.js @@ -17,327 +17,71 @@ var common = require('./src/common'); //@ All commands run synchronously, unless otherwise stated. //@ - -//@ -//@ ### cd('dir') -//@ Changes to directory `dir` for the duration of the script +//@include ./src/cd var _cd = require('./src/cd'); exports.cd = common.wrap('cd', _cd); -//@ -//@ ### pwd() -//@ Returns the current directory. +//@include ./src/pwd var _pwd = require('./src/pwd'); exports.pwd = common.wrap('pwd', _pwd); - -//@ -//@ ### ls([options ,] path [,path ...]) -//@ ### ls([options ,] path_array) -//@ Available options: -//@ -//@ + `-R`: recursive -//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`) -//@ -//@ Examples: -//@ -//@ ```javascript -//@ ls('projs/*.js'); -//@ ls('-R', '/users/me', '/tmp'); -//@ ls('-R', ['/users/me', '/tmp']); // same as above -//@ ``` -//@ -//@ Returns array of files in the given path, or in current directory if no path provided. +//@include ./src/ls var _ls = require('./src/ls'); exports.ls = common.wrap('ls', _ls); - -//@ -//@ ### find(path [,path ...]) -//@ ### find(path_array) -//@ Examples: -//@ -//@ ```javascript -//@ find('src', 'lib'); -//@ find(['src', 'lib']); // same as above -//@ find('.').filter(function(file) { return file.match(/\.js$/); }); -//@ ``` -//@ -//@ Returns array of all files (however deep) in the given paths. -//@ -//@ The main difference from `ls('-R', path)` is that the resulting file names -//@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`. +//@include ./src/find var _find = require('./src/find'); exports.find = common.wrap('find', _find); - -//@ -//@ ### cp([options ,] source [,source ...], dest) -//@ ### cp([options ,] source_array, dest) -//@ Available options: -//@ -//@ + `-f`: force -//@ + `-r, -R`: recursive -//@ -//@ Examples: -//@ -//@ ```javascript -//@ cp('file1', 'dir1'); -//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp'); -//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above -//@ ``` -//@ -//@ Copies files. The wildcard `*` is accepted. +//@include ./src/cp var _cp = require('./src/cp'); exports.cp = common.wrap('cp', _cp); -//@ -//@ ### rm([options ,] file [, file ...]) -//@ ### rm([options ,] file_array) -//@ Available options: -//@ -//@ + `-f`: force -//@ + `-r, -R`: recursive -//@ -//@ Examples: -//@ -//@ ```javascript -//@ rm('-rf', '/tmp/*'); -//@ rm('some_file.txt', 'another_file.txt'); -//@ rm(['some_file.txt', 'another_file.txt']); // same as above -//@ ``` -//@ -//@ Removes files. The wildcard `*` is accepted. +//@include ./src/rm var _rm = require('./src/rm'); exports.rm = common.wrap('rm', _rm); -//@ -//@ ### mv(source [, source ...], dest') -//@ ### mv(source_array, dest') -//@ Available options: -//@ -//@ + `f`: force -//@ -//@ Examples: -//@ -//@ ```javascript -//@ mv('-f', 'file', 'dir/'); -//@ mv('file1', 'file2', 'dir/'); -//@ mv(['file1', 'file2'], 'dir/'); // same as above -//@ ``` -//@ -//@ Moves files. The wildcard `*` is accepted. +//@include ./src/mv var _mv = require('./src/mv'); exports.mv = common.wrap('mv', _mv); -//@ -//@ ### mkdir([options ,] dir [, dir ...]) -//@ ### mkdir([options ,] dir_array) -//@ Available options: -//@ -//@ + `p`: full path (will create intermediate dirs if necessary) -//@ -//@ Examples: -//@ -//@ ```javascript -//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g'); -//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above -//@ ``` -//@ -//@ Creates directories. +//@include ./src/mkdir var _mkdir = require('./src/mkdir'); exports.mkdir = common.wrap('mkdir', _mkdir); -//@ -//@ ### test(expression) -//@ Available expression primaries: -//@ -//@ + `'-b', 'path'`: true if path is a block device -//@ + `'-c', 'path'`: true if path is a character device -//@ + `'-d', 'path'`: true if path is a directory -//@ + `'-e', 'path'`: true if path exists -//@ + `'-f', 'path'`: true if path is a regular file -//@ + `'-L', 'path'`: true if path is a symboilc link -//@ + `'-p', 'path'`: true if path is a pipe (FIFO) -//@ + `'-S', 'path'`: true if path is a socket -//@ -//@ Examples: -//@ -//@ ```javascript -//@ if (test('-d', path)) { /* do something with dir */ }; -//@ if (!test('-f', path)) continue; // skip if it's a regular file -//@ ``` -//@ -//@ Evaluates expression using the available primaries and returns corresponding value. +//@include ./src/test var _test = require('./src/test'); exports.test = common.wrap('test', _test); - -//@ -//@ ### cat(file [, file ...]) -//@ ### cat(file_array) -//@ -//@ Examples: -//@ -//@ ```javascript -//@ var str = cat('file*.txt'); -//@ var str = cat('file1', 'file2'); -//@ var str = cat(['file1', 'file2']); // same as above -//@ ``` -//@ -//@ Returns a string containing the given file, or a concatenated string -//@ containing the files if more than one file is given (a new line character is -//@ introduced between each file). Wildcard `*` accepted. +//@include ./src/cat var _cat = require('./src/cat'); exports.cat = common.wrap('cat', _cat); -//@ -//@ ### 'string'.to(file) -//@ -//@ Examples: -//@ -//@ ```javascript -//@ cat('input.txt').to('output.txt'); -//@ ``` -//@ -//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as -//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ +//@include ./src/to var _to = require('./src/to'); String.prototype.to = common.wrap('to', _to); -//@ -//@ ### sed([options ,] search_regex, replace_str, file) -//@ Available options: -//@ -//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ -//@ -//@ Examples: -//@ -//@ ```javascript -//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js'); -//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); -//@ ``` -//@ -//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input -//@ using the given search regex and replacement string. Returns the new string after replacement. +//@include ./src/sed var _sed = require('./src/sed'); exports.sed = common.wrap('sed', _sed); -//@ -//@ ### grep([options ,] regex_filter, file [, file ...]) -//@ ### grep([options ,] regex_filter, file_array) -//@ Available options: -//@ -//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria. -//@ -//@ Examples: -//@ -//@ ```javascript -//@ grep('-v', 'GLOBAL_VARIABLE', '*.js'); -//@ grep('GLOBAL_VARIABLE', '*.js'); -//@ ``` -//@ -//@ Reads input string from given files and returns a string containing all lines of the -//@ file that match the given `regex_filter`. Wildcard `*` accepted. +//@include ./src/grep var _grep = require('./src/grep'); exports.grep = common.wrap('grep', _grep); - -//@ -//@ ### which(command) -//@ -//@ Examples: -//@ -//@ ```javascript -//@ var nodeExec = which('node'); -//@ ``` -//@ -//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions. -//@ Returns string containing the absolute path to the command. +//@include ./src/which var _which = require('./src/which'); exports.which = common.wrap('which', _which); -//@ -//@ ### echo(string [,string ...]) -//@ -//@ Examples: -//@ -//@ ```javascript -//@ echo('hello world'); -//@ var str = echo('hello world'); -//@ ``` -//@ -//@ Prints string to stdout, and returns string with additional utility methods -//@ like `.to()`. +//@include ./src/echo var _echo = require('./src/echo'); exports.echo = _echo; // don't common.wrap() as it could parse '-options' -//@ -//@ ### dirs([options | '+N' | '-N']) -//@ -//@ Available options: -//@ -//@ + `-c`: Clears the directory stack by deleting all of the elements. -//@ -//@ Arguments: -//@ -//@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero. -//@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. -//@ -//@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified. -//@ -//@ See also: pushd, popd +//@include ./src/dirs var _dirs = require('./src/dirs').dirs; exports.dirs = common.wrap("dirs", _dirs); - -//@ -//@ ### pushd([options,] [dir | '-N' | '+N']) -//@ -//@ Available options: -//@ -//@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. -//@ -//@ Arguments: -//@ -//@ + `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`. -//@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. -//@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. -//@ -//@ Examples: -//@ -//@ ```javascript -//@ // process.cwd() === '/usr' -//@ pushd('/etc'); // Returns /etc /usr -//@ pushd('+1'); // Returns /usr /etc -//@ ``` -//@ -//@ Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack. var _pushd = require('./src/dirs').pushd; exports.pushd = common.wrap('pushd', _pushd); - -//@ -//@ ### popd([options,] ['-N' | '+N']) -//@ -//@ Available options: -//@ -//@ + `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. -//@ -//@ Arguments: -//@ -//@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero. -//@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero. -//@ -//@ Examples: -//@ -//@ ```javascript -//@ echo(process.cwd()); // '/usr' -//@ pushd('/etc'); // '/etc /usr' -//@ echo(process.cwd()); // '/etc' -//@ popd(); // '/usr' -//@ echo(process.cwd()); // '/usr' -//@ ``` -//@ -//@ When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack. var _popd = require('./src/dirs').popd; exports.popd = common.wrap("popd", _popd); @@ -351,72 +95,28 @@ exports.exit = process.exit; //@ Object containing environment variables (both getter and setter). Shortcut to process.env. exports.env = process.env; -//@ -//@ ### exec(command [, options] [, callback]) -//@ Available options (all `false` by default): -//@ -//@ + `async`: Asynchronous execution. Defaults to true if a callback is provided. -//@ + `silent`: Do not echo program output to console. -//@ -//@ Examples: -//@ -//@ ```javascript -//@ var version = exec('node --version', {silent:true}).output; -//@ -//@ var child = exec('some_long_running_process', {async:true}); -//@ child.stdout.on('data', function(data) { -//@ /* ... do something with data ... */ -//@ }); -//@ -//@ exec('some_long_running_process', function(code, output) { -//@ console.log('Exit code:', code); -//@ console.log('Program output:', output); -//@ }); -//@ ``` -//@ -//@ Executes the given `command` _synchronously_, unless otherwise specified. -//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's -//@ `output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and -//@ the `callback` gets the arguments `(code, output)`. -//@ -//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as -//@ the current synchronous implementation uses a lot of CPU. This should be getting -//@ fixed soon. +//@include ./src/exec var _exec = require('./src/exec'); exports.exec = common.wrap('exec', _exec, {notUnix:true}); - -//@ -//@ ### chmod(octal_mode || octal_string, file) -//@ ### chmod(symbolic_mode, file) -//@ -//@ Available options: -//@ -//@ + `-v`: output a diagnostic for every file processed//@ -//@ + `-c`: like verbose but report only when a change is made//@ -//@ + `-R`: change files and directories recursively//@ -//@ -//@ Examples: -//@ -//@ ```javascript -//@ chmod(755, '/Users/brandon'); -//@ chmod('755', '/Users/brandon'); // same as above -//@ chmod('u+x', '/Users/brandon'); -//@ ``` -//@ -//@ Alters the permissions of a file or directory by either specifying the -//@ absolute permissions in octal form or expressing the changes in symbols. -//@ This command tries to mimic the POSIX behavior as much as possible. -//@ Notable exceptions: -//@ -//@ + In symbolic modes, 'a-r' and '-r' are identical. No consideration is -//@ given to the umask. -//@ + There is no "quiet" option since default behavior is to run silent. +//@include ./src/chmod var _chmod = require('./src/chmod'); exports.chmod = common.wrap('chmod', _chmod); +//@ +//@ ## Non-Unix commands +//@ + +//@include ./src/tempdir +var _tempDir = require('./src/tempdir'); +exports.tempdir = common.wrap('tempdir', _tempDir); + + +//@include ./src/error +var _error = require('./src/error'); +exports.error = _error; @@ -451,26 +151,3 @@ exports.config = common.config; //@ ``` //@ //@ If `true` the script will die on errors. Default is `false`. - - - - -//@ -//@ ## Non-Unix commands -//@ - - -//@ -//@ ### tempdir() -//@ Searches and returns string containing a writeable, platform-dependent temporary directory. -//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). -var _tempDir = require('./src/tempdir'); -exports.tempdir = common.wrap('tempdir', _tempDir); - - -//@ -//@ ### error() -//@ Tests if error occurred in the last command. Returns `null` if no error occurred, -//@ otherwise returns string explaining the error -var _error = require('./src/error'); -exports.error = _error; diff --git a/src/cat.js b/src/cat.js index 428062b..f6f4d25 100644 --- a/src/cat.js +++ b/src/cat.js @@ -1,6 +1,21 @@ var common = require('./common'); var fs = require('fs'); +//@ +//@ ### cat(file [, file ...]) +//@ ### cat(file_array) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var str = cat('file*.txt'); +//@ var str = cat('file1', 'file2'); +//@ var str = cat(['file1', 'file2']); // same as above +//@ ``` +//@ +//@ Returns a string containing the given file, or a concatenated string +//@ containing the files if more than one file is given (a new line character is +//@ introduced between each file). Wildcard `*` accepted. function _cat(options, files) { var cat = ''; diff --git a/src/cd.js b/src/cd.js index 40ef241..230f432 100644 --- a/src/cd.js +++ b/src/cd.js @@ -1,6 +1,9 @@ var fs = require('fs'); var common = require('./common'); +//@ +//@ ### cd('dir') +//@ Changes to directory `dir` for the duration of the script function _cd(options, dir) { if (!dir) common.error('directory not specified'); diff --git a/src/chmod.js b/src/chmod.js index fed0526..f288893 100644 --- a/src/chmod.js +++ b/src/chmod.js @@ -30,6 +30,32 @@ var PERMS = (function (base) { READ : 4 }); +//@ +//@ ### chmod(octal_mode || octal_string, file) +//@ ### chmod(symbolic_mode, file) +//@ +//@ Available options: +//@ +//@ + `-v`: output a diagnostic for every file processed//@ +//@ + `-c`: like verbose but report only when a change is made//@ +//@ + `-R`: change files and directories recursively//@ +//@ +//@ Examples: +//@ +//@ ```javascript +//@ chmod(755, '/Users/brandon'); +//@ chmod('755', '/Users/brandon'); // same as above +//@ chmod('u+x', '/Users/brandon'); +//@ ``` +//@ +//@ Alters the permissions of a file or directory by either specifying the +//@ absolute permissions in octal form or expressing the changes in symbols. +//@ This command tries to mimic the POSIX behavior as much as possible. +//@ Notable exceptions: +//@ +//@ + In symbolic modes, 'a-r' and '-r' are identical. No consideration is +//@ given to the umask. +//@ + There is no "quiet" option since default behavior is to run silent. function _chmod(options, mode, filePattern) { if (!filePattern) { if (options.length > 0 && options.charAt(0) === '-') { diff --git a/src/cp.js b/src/cp.js index 1e0b732..7d793f9 100644 --- a/src/cp.js +++ b/src/cp.js @@ -82,6 +82,23 @@ function cpdirSyncRecursive(sourceDir, destDir, opts) { } // cpdirSyncRecursive +//@ +//@ ### cp([options ,] source [,source ...], dest) +//@ ### cp([options ,] source_array, dest) +//@ Available options: +//@ +//@ + `-f`: force +//@ + `-r, -R`: recursive +//@ +//@ Examples: +//@ +//@ ```javascript +//@ cp('file1', 'dir1'); +//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp'); +//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above +//@ ``` +//@ +//@ Copies files. The wildcard `*` is accepted. function _cp(options, sources, dest) { options = common.parseOptions(options, { 'f': 'force', diff --git a/src/dirs.js b/src/dirs.js index 4e27217..58fae8b 100644 --- a/src/dirs.js +++ b/src/dirs.js @@ -25,6 +25,28 @@ function _actualDirStack() { return [process.cwd()].concat(_dirStack); } +//@ +//@ ### pushd([options,] [dir | '-N' | '+N']) +//@ +//@ Available options: +//@ +//@ + `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. +//@ +//@ Arguments: +//@ +//@ + `dir`: Makes the current working directory be the top of the stack, and then executes the equivalent of `cd dir`. +//@ + `+N`: Brings the Nth directory (counting from the left of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. +//@ + `-N`: Brings the Nth directory (counting from the right of the list printed by dirs, starting with zero) to the top of the list by rotating the stack. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ // process.cwd() === '/usr' +//@ pushd('/etc'); // Returns /etc /usr +//@ pushd('+1'); // Returns /usr /etc +//@ ``` +//@ +//@ Save the current directory on the top of the directory stack and then cd to `dir`. With no arguments, pushd exchanges the top two directories. Returns an array of paths in the stack. function _pushd(options, dir) { if (_isStackIndex(options)) { dir = options; @@ -68,6 +90,29 @@ function _pushd(options, dir) { } exports.pushd = _pushd; +//@ +//@ ### popd([options,] ['-N' | '+N']) +//@ +//@ Available options: +//@ +//@ + `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. +//@ +//@ Arguments: +//@ +//@ + `+N`: Removes the Nth directory (counting from the left of the list printed by dirs), starting with zero. +//@ + `-N`: Removes the Nth directory (counting from the right of the list printed by dirs), starting with zero. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ echo(process.cwd()); // '/usr' +//@ pushd('/etc'); // '/etc /usr' +//@ echo(process.cwd()); // '/etc' +//@ popd(); // '/usr' +//@ echo(process.cwd()); // '/usr' +//@ ``` +//@ +//@ When no arguments are given, popd removes the top directory from the stack and performs a cd to the new top directory. The elements are numbered from 0 starting at the first directory listed with dirs; i.e., popd is equivalent to popd +0. Returns an array of paths in the stack. function _popd(options, index) { if (_isStackIndex(options)) { index = options; @@ -96,6 +141,21 @@ function _popd(options, index) { } exports.popd = _popd; +//@ +//@ ### dirs([options | '+N' | '-N']) +//@ +//@ Available options: +//@ +//@ + `-c`: Clears the directory stack by deleting all of the elements. +//@ +//@ Arguments: +//@ +//@ + `+N`: Displays the Nth directory (counting from the left of the list printed by dirs when invoked without options), starting with zero. +//@ + `-N`: Displays the Nth directory (counting from the right of the list printed by dirs when invoked without options), starting with zero. +//@ +//@ Display the list of currently remembered directories. Returns an array of paths in the stack, or a single path if +N or -N was specified. +//@ +//@ See also: pushd, popd function _dirs(options, index) { if (_isStackIndex(options)) { index = options; diff --git a/src/echo.js b/src/echo.js index 9f6af8a..760ea84 100644 --- a/src/echo.js +++ b/src/echo.js @@ -1,5 +1,17 @@ var common = require('./common'); +//@ +//@ ### echo(string [,string ...]) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ echo('hello world'); +//@ var str = echo('hello world'); +//@ ``` +//@ +//@ Prints string to stdout, and returns string with additional utility methods +//@ like `.to()`. function _echo() { var messages = [].slice.call(arguments, 0); console.log.apply(this, messages); diff --git a/src/error.js b/src/error.js index eabf13f..cca3efb 100644 --- a/src/error.js +++ b/src/error.js @@ -1,6 +1,10 @@ var common = require('./common'); +//@ +//@ ### error() +//@ Tests if error occurred in the last command. Returns `null` if no error occurred, +//@ otherwise returns string explaining the error function error() { return common.state.error; }; -module.exports = error; \ No newline at end of file +module.exports = error; diff --git a/src/exec.js b/src/exec.js index 908b916..592b459 100644 --- a/src/exec.js +++ b/src/exec.js @@ -118,6 +118,37 @@ function execAsync(cmd, opts, callback) { return c; } +//@ +//@ ### exec(command [, options] [, callback]) +//@ Available options (all `false` by default): +//@ +//@ + `async`: Asynchronous execution. Defaults to true if a callback is provided. +//@ + `silent`: Do not echo program output to console. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var version = exec('node --version', {silent:true}).output; +//@ +//@ var child = exec('some_long_running_process', {async:true}); +//@ child.stdout.on('data', function(data) { +//@ /* ... do something with data ... */ +//@ }); +//@ +//@ exec('some_long_running_process', function(code, output) { +//@ console.log('Exit code:', code); +//@ console.log('Program output:', output); +//@ }); +//@ ``` +//@ +//@ Executes the given `command` _synchronously_, unless otherwise specified. +//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's +//@ `output` (stdout + stderr) and its exit `code`. Otherwise returns the child process object, and +//@ the `callback` gets the arguments `(code, output)`. +//@ +//@ **Note:** For long-lived processes, it's best to run `exec()` asynchronously as +//@ the current synchronous implementation uses a lot of CPU. This should be getting +//@ fixed soon. function _exec(command, options, callback) { if (!command) common.error('must specify command'); diff --git a/src/find.js b/src/find.js index 97f8d42..d9eeec2 100644 --- a/src/find.js +++ b/src/find.js @@ -2,6 +2,21 @@ var fs = require('fs'); var common = require('./common'); var _ls = require('./ls'); +//@ +//@ ### find(path [,path ...]) +//@ ### find(path_array) +//@ Examples: +//@ +//@ ```javascript +//@ find('src', 'lib'); +//@ find(['src', 'lib']); // same as above +//@ find('.').filter(function(file) { return file.match(/\.js$/); }); +//@ ``` +//@ +//@ Returns array of all files (however deep) in the given paths. +//@ +//@ The main difference from `ls('-R', path)` is that the resulting file names +//@ include the base directories, e.g. `lib/resources/file1` instead of just `file1`. function _find(options, paths) { if (!paths) common.error('no path specified'); diff --git a/src/grep.js b/src/grep.js index ba7120b..00c7d6a 100644 --- a/src/grep.js +++ b/src/grep.js @@ -1,6 +1,22 @@ var common = require('./common'); var fs = require('fs'); +//@ +//@ ### grep([options ,] regex_filter, file [, file ...]) +//@ ### grep([options ,] regex_filter, file_array) +//@ Available options: +//@ +//@ + `-v`: Inverse the sense of the regex and print the lines not matching the criteria. +//@ +//@ Examples: +//@ +//@ ```javascript +//@ grep('-v', 'GLOBAL_VARIABLE', '*.js'); +//@ grep('GLOBAL_VARIABLE', '*.js'); +//@ ``` +//@ +//@ Reads input string from given files and returns a string containing all lines of the +//@ file that match the given `regex_filter`. Wildcard `*` accepted. function _grep(options, regex, files) { options = common.parseOptions(options, { 'v': 'inverse' diff --git a/src/ls.js b/src/ls.js index 651504c..3345db4 100644 --- a/src/ls.js +++ b/src/ls.js @@ -4,6 +4,23 @@ var common = require('./common'); var _cd = require('./cd'); var _pwd = require('./pwd'); +//@ +//@ ### ls([options ,] path [,path ...]) +//@ ### ls([options ,] path_array) +//@ Available options: +//@ +//@ + `-R`: recursive +//@ + `-A`: all files (include files beginning with `.`, except for `.` and `..`) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ ls('projs/*.js'); +//@ ls('-R', '/users/me', '/tmp'); +//@ ls('-R', ['/users/me', '/tmp']); // same as above +//@ ``` +//@ +//@ Returns array of files in the given path, or in current directory if no path provided. function _ls(options, paths) { options = common.parseOptions(options, { 'R': 'recursive', diff --git a/src/mkdir.js b/src/mkdir.js index 927e33e..5a7088f 100644 --- a/src/mkdir.js +++ b/src/mkdir.js @@ -19,6 +19,21 @@ function mkdirSyncRecursive(dir) { fs.mkdirSync(dir, parseInt('0777', 8)); } +//@ +//@ ### mkdir([options ,] dir [, dir ...]) +//@ ### mkdir([options ,] dir_array) +//@ Available options: +//@ +//@ + `p`: full path (will create intermediate dirs if necessary) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g'); +//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above +//@ ``` +//@ +//@ Creates directories. function _mkdir(options, dirs) { options = common.parseOptions(options, { 'p': 'fullpath' diff --git a/src/mv.js b/src/mv.js index 3d7c347..11f9607 100644 --- a/src/mv.js +++ b/src/mv.js @@ -2,6 +2,22 @@ var fs = require('fs'); var path = require('path'); var common = require('./common'); +//@ +//@ ### mv(source [, source ...], dest') +//@ ### mv(source_array, dest') +//@ Available options: +//@ +//@ + `f`: force +//@ +//@ Examples: +//@ +//@ ```javascript +//@ mv('-f', 'file', 'dir/'); +//@ mv('file1', 'file2', 'dir/'); +//@ mv(['file1', 'file2'], 'dir/'); // same as above +//@ ``` +//@ +//@ Moves files. The wildcard `*` is accepted. function _mv(options, sources, dest) { options = common.parseOptions(options, { 'f': 'force' diff --git a/src/pwd.js b/src/pwd.js index 8971c15..41727bb 100644 --- a/src/pwd.js +++ b/src/pwd.js @@ -1,6 +1,9 @@ var path = require('path'); var common = require('./common'); +//@ +//@ ### pwd() +//@ Returns the current directory. function _pwd(options) { var pwd = path.resolve(process.cwd()); return common.ShellString(pwd); diff --git a/src/rm.js b/src/rm.js index a254086..a093723 100644 --- a/src/rm.js +++ b/src/rm.js @@ -70,6 +70,23 @@ function isWriteable(file) { return writePermission; } +//@ +//@ ### rm([options ,] file [, file ...]) +//@ ### rm([options ,] file_array) +//@ Available options: +//@ +//@ + `-f`: force +//@ + `-r, -R`: recursive +//@ +//@ Examples: +//@ +//@ ```javascript +//@ rm('-rf', '/tmp/*'); +//@ rm('some_file.txt', 'another_file.txt'); +//@ rm(['some_file.txt', 'another_file.txt']); // same as above +//@ ``` +//@ +//@ Removes files. The wildcard `*` is accepted. function _rm(options, files) { options = common.parseOptions(options, { 'f': 'force', diff --git a/src/sed b/src/sed.js similarity index 58% rename from src/sed rename to src/sed.js index 91b79ac..9783252 100644 --- a/src/sed +++ b/src/sed.js @@ -1,6 +1,21 @@ var common = require('./common'); var fs = require('fs'); +//@ +//@ ### sed([options ,] search_regex, replace_str, file) +//@ Available options: +//@ +//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ +//@ +//@ Examples: +//@ +//@ ```javascript +//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js'); +//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); +//@ ``` +//@ +//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input +//@ using the given search regex and replacement string. Returns the new string after replacement. function _sed(options, regex, replacement, file) { options = common.parseOptions(options, { 'i': 'inplace' diff --git a/src/tempdir.js b/src/tempdir.js index 433684e..eee4dcd 100644 --- a/src/tempdir.js +++ b/src/tempdir.js @@ -21,9 +21,10 @@ function writeableDir(dir) { } -// Cross-platform method for getting an available temporary directory. -// Follows the algorithm of Python's tempfile.tempdir -// http://docs.python.org/library/tempfile.html#tempfile.tempdir +//@ +//@ ### tempdir() +//@ Searches and returns string containing a writeable, platform-dependent temporary directory. +//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir). function _tempDir() { var state = common.state; if (state.tempDir) diff --git a/src/test.js b/src/test.js index 4d9a28c..8a4ac7d 100644 --- a/src/test.js +++ b/src/test.js @@ -1,6 +1,27 @@ var common = require('./common'); var fs = require('fs'); +//@ +//@ ### test(expression) +//@ Available expression primaries: +//@ +//@ + `'-b', 'path'`: true if path is a block device +//@ + `'-c', 'path'`: true if path is a character device +//@ + `'-d', 'path'`: true if path is a directory +//@ + `'-e', 'path'`: true if path exists +//@ + `'-f', 'path'`: true if path is a regular file +//@ + `'-L', 'path'`: true if path is a symboilc link +//@ + `'-p', 'path'`: true if path is a pipe (FIFO) +//@ + `'-S', 'path'`: true if path is a socket +//@ +//@ Examples: +//@ +//@ ```javascript +//@ if (test('-d', path)) { /* do something with dir */ }; +//@ if (!test('-f', path)) continue; // skip if it's a regular file +//@ ``` +//@ +//@ Evaluates expression using the available primaries and returns corresponding value. function _test(options, path) { if (!path) common.error('no path given'); diff --git a/src/to.js b/src/to.js index e127d20..f029999 100644 --- a/src/to.js +++ b/src/to.js @@ -2,6 +2,17 @@ var common = require('./common'); var fs = require('fs'); var path = require('path'); +//@ +//@ ### 'string'.to(file) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ cat('input.txt').to('output.txt'); +//@ ``` +//@ +//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as +//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_ function _to(options, file) { if (!file) common.error('wrong arguments'); diff --git a/src/which.js b/src/which.js index 61b9f62..eb7faa8 100644 --- a/src/which.js +++ b/src/which.js @@ -13,6 +13,17 @@ function splitPath(p) { return p.split(':'); } +//@ +//@ ### which(command) +//@ +//@ Examples: +//@ +//@ ```javascript +//@ var nodeExec = which('node'); +//@ ``` +//@ +//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions. +//@ Returns string containing the absolute path to the command. function _which(options, cmd) { if (!cmd) common.error('must specify command');