Comparing version 0.7.5 to 0.7.6
103
CHANGELOG.md
@@ -5,6 +5,107 @@ # Change Log | ||
[Full Changelog](https://github.com/shelljs/shelljs/compare/v0.7.4...HEAD) | ||
[Full Changelog](https://github.com/shelljs/shelljs/compare/v0.7.5...HEAD) | ||
**Closed issues:** | ||
- QUESTION: Feedback while an operation is running? [\#629](https://github.com/shelljs/shelljs/issues/629) | ||
- Test setup/cleanup is broken [\#621](https://github.com/shelljs/shelljs/issues/621) | ||
- Ignore temp directories when running lint [\#620](https://github.com/shelljs/shelljs/issues/620) | ||
- parseOptions should throw an error if the option string doesn't start with '-' [\#614](https://github.com/shelljs/shelljs/issues/614) | ||
- chore: LGTM.co is gone [\#595](https://github.com/shelljs/shelljs/issues/595) | ||
- refactor: objectAssign should refer to Object.assign if it exists, or the internal polyfill otherwise [\#592](https://github.com/shelljs/shelljs/issues/592) | ||
- parseOptions: allow a way to keep errors silent \(exception only\) [\#591](https://github.com/shelljs/shelljs/issues/591) | ||
- \[Question\] commands with multiple options / arguments? [\#589](https://github.com/shelljs/shelljs/issues/589) | ||
- feature: GNU Parallel [\#585](https://github.com/shelljs/shelljs/issues/585) | ||
- write to file [\#568](https://github.com/shelljs/shelljs/issues/568) | ||
- Cannot figure out how to disable globbing for rm [\#567](https://github.com/shelljs/shelljs/issues/567) | ||
- Switch to the ava test framework [\#560](https://github.com/shelljs/shelljs/issues/560) | ||
- feature: echo -n [\#559](https://github.com/shelljs/shelljs/issues/559) | ||
- Option not recognized [\#556](https://github.com/shelljs/shelljs/issues/556) | ||
- chore: add @freitagbr to LGTM maintainers [\#552](https://github.com/shelljs/shelljs/issues/552) | ||
- chore: set up dev branch [\#548](https://github.com/shelljs/shelljs/issues/548) | ||
- bug: cp\(\) doesn't always copy everything [\#547](https://github.com/shelljs/shelljs/issues/547) | ||
- User-friendly lint command [\#544](https://github.com/shelljs/shelljs/issues/544) | ||
- Lint warning [\#542](https://github.com/shelljs/shelljs/issues/542) | ||
- Possible Regression: cp from 0.6.0 to 0.7.x version [\#538](https://github.com/shelljs/shelljs/issues/538) | ||
- chore: add nodejs v7 to CI [\#537](https://github.com/shelljs/shelljs/issues/537) | ||
- error.code is not always available [\#536](https://github.com/shelljs/shelljs/issues/536) | ||
- Add shx as a dependency for testing [\#525](https://github.com/shelljs/shelljs/issues/525) | ||
- Feature request: allow `common.error\(\)` to optionally not insert a prefix and optionally not print to console [\#523](https://github.com/shelljs/shelljs/issues/523) | ||
- Feature request: Add "shelljs.unlink" [\#519](https://github.com/shelljs/shelljs/issues/519) | ||
- Sed should allow a replacement string to contain `\1` for match groups [\#507](https://github.com/shelljs/shelljs/issues/507) | ||
- Don't kill the node process upon unexpected error [\#483](https://github.com/shelljs/shelljs/issues/483) | ||
- Usage with neodoc [\#445](https://github.com/shelljs/shelljs/issues/445) | ||
- \[ Feature idea \] synchronous sleep command [\#441](https://github.com/shelljs/shelljs/issues/441) | ||
- Add a way to prevent shell-expansion on commands \(this issue is not for exec\) [\#345](https://github.com/shelljs/shelljs/issues/345) | ||
- Chown [\#183](https://github.com/shelljs/shelljs/issues/183) | ||
- spawn EMFILE [\#81](https://github.com/shelljs/shelljs/issues/81) | ||
- Rewrite exec using execsync-ng \(which uses node-ffi\) [\#66](https://github.com/shelljs/shelljs/issues/66) | ||
- `exec` gets stuck on my Debian box [\#51](https://github.com/shelljs/shelljs/issues/51) | ||
- 100% cpu usage when a nodejs script goes side ways executing a command. [\#5](https://github.com/shelljs/shelljs/issues/5) | ||
**Merged pull requests:** | ||
- Finalize moving to ava [\#630](https://github.com/shelljs/shelljs/pull/630) ([freitagbr](https://github.com/freitagbr)) | ||
- test: refactor pushd tests to AVA [\#627](https://github.com/shelljs/shelljs/pull/627) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor popd tests to AVA [\#626](https://github.com/shelljs/shelljs/pull/626) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor shjs tests to AVA [\#625](https://github.com/shelljs/shelljs/pull/625) ([nfischer](https://github.com/nfischer)) | ||
- test: remove tests for make \(deprecated\) [\#624](https://github.com/shelljs/shelljs/pull/624) ([nfischer](https://github.com/nfischer)) | ||
- Ignore test temp directories during linting [\#623](https://github.com/shelljs/shelljs/pull/623) ([freitagbr](https://github.com/freitagbr)) | ||
- refactor: list all commands in commands.json [\#616](https://github.com/shelljs/shelljs/pull/616) ([nfischer](https://github.com/nfischer)) | ||
- Throw an error if the options string does not start with '-' [\#615](https://github.com/shelljs/shelljs/pull/615) ([freitagbr](https://github.com/freitagbr)) | ||
- chore: switch to files attribute from npmignore [\#613](https://github.com/shelljs/shelljs/pull/613) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor 'test' command tests to AVA [\#612](https://github.com/shelljs/shelljs/pull/612) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor find tests to AVA [\#611](https://github.com/shelljs/shelljs/pull/611) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor ln tests to AVA [\#610](https://github.com/shelljs/shelljs/pull/610) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor ls to use AVA [\#609](https://github.com/shelljs/shelljs/pull/609) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor pipe tests to AVA [\#608](https://github.com/shelljs/shelljs/pull/608) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor sed tests to AVA [\#607](https://github.com/shelljs/shelljs/pull/607) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor grep tests to AVA [\#606](https://github.com/shelljs/shelljs/pull/606) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor global tests to AVA [\#605](https://github.com/shelljs/shelljs/pull/605) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor touch tests to AVA [\#604](https://github.com/shelljs/shelljs/pull/604) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor uniq tests to AVA [\#603](https://github.com/shelljs/shelljs/pull/603) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor sort tests to AVA [\#602](https://github.com/shelljs/shelljs/pull/602) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor tail tests to AVA [\#601](https://github.com/shelljs/shelljs/pull/601) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor head tests to AVA [\#600](https://github.com/shelljs/shelljs/pull/600) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor mkdir tests to AVA [\#599](https://github.com/shelljs/shelljs/pull/599) ([nfischer](https://github.com/nfischer)) | ||
- Fix: rm behavior regarding symlinks [\#598](https://github.com/shelljs/shelljs/pull/598) ([freitagbr](https://github.com/freitagbr)) | ||
- test: refactor mv tests to AVA [\#597](https://github.com/shelljs/shelljs/pull/597) ([nfischer](https://github.com/nfischer)) | ||
- Remove files related to lgtm.co [\#596](https://github.com/shelljs/shelljs/pull/596) ([freitagbr](https://github.com/freitagbr)) | ||
- Add ability to configure error from parseOptions [\#594](https://github.com/shelljs/shelljs/pull/594) ([freitagbr](https://github.com/freitagbr)) | ||
- Use Object.assign if possible [\#593](https://github.com/shelljs/shelljs/pull/593) ([freitagbr](https://github.com/freitagbr)) | ||
- Add "-n" option to echo [\#590](https://github.com/shelljs/shelljs/pull/590) ([freitagbr](https://github.com/freitagbr)) | ||
- test: refactor rm tests to AVA [\#586](https://github.com/shelljs/shelljs/pull/586) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor pwd tests to AVA [\#582](https://github.com/shelljs/shelljs/pull/582) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor tempdir tests to AVA [\#581](https://github.com/shelljs/shelljs/pull/581) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor 'which' tests to AVA [\#580](https://github.com/shelljs/shelljs/pull/580) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor plugin tests to AVA [\#579](https://github.com/shelljs/shelljs/pull/579) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor toEnd tests to AVA [\#578](https://github.com/shelljs/shelljs/pull/578) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor to tests to AVA [\#577](https://github.com/shelljs/shelljs/pull/577) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor 'set' tests to AVA [\#576](https://github.com/shelljs/shelljs/pull/576) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor echo tests to AVA [\#575](https://github.com/shelljs/shelljs/pull/575) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor exec tests to AVA [\#574](https://github.com/shelljs/shelljs/pull/574) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor env tests to AVA [\#573](https://github.com/shelljs/shelljs/pull/573) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor dirs tests to AVA [\#572](https://github.com/shelljs/shelljs/pull/572) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor config tests to AVA [\#571](https://github.com/shelljs/shelljs/pull/571) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor common tests to AVA [\#570](https://github.com/shelljs/shelljs/pull/570) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor chmod tests to AVA [\#569](https://github.com/shelljs/shelljs/pull/569) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor cp tests to ava [\#565](https://github.com/shelljs/shelljs/pull/565) ([nfischer](https://github.com/nfischer)) | ||
- test: refactor cat tests to ava [\#564](https://github.com/shelljs/shelljs/pull/564) ([nfischer](https://github.com/nfischer)) | ||
- test: set up ava and move cd.js [\#561](https://github.com/shelljs/shelljs/pull/561) ([nfischer](https://github.com/nfischer)) | ||
- Update sed documentation regarding capture groups [\#558](https://github.com/shelljs/shelljs/pull/558) ([freitagbr](https://github.com/freitagbr)) | ||
- Add newline to output of echo [\#557](https://github.com/shelljs/shelljs/pull/557) ([freitagbr](https://github.com/freitagbr)) | ||
- fix: handle code-less errors more carefully in exec [\#554](https://github.com/shelljs/shelljs/pull/554) ([nfischer](https://github.com/nfischer)) | ||
- Add Brandon Freitag to maintainers/contributors [\#553](https://github.com/shelljs/shelljs/pull/553) ([freitagbr](https://github.com/freitagbr)) | ||
- Get pipe tests running on Windows. [\#550](https://github.com/shelljs/shelljs/pull/550) ([binki](https://github.com/binki)) | ||
- fix: maxdepth doesn't limit total number of copies [\#549](https://github.com/shelljs/shelljs/pull/549) ([nfischer](https://github.com/nfischer)) | ||
- Safely exit by throwing an error [\#546](https://github.com/shelljs/shelljs/pull/546) ([freitagbr](https://github.com/freitagbr)) | ||
- Fix lint warning [\#543](https://github.com/shelljs/shelljs/pull/543) ([freitagbr](https://github.com/freitagbr)) | ||
- chore: remove v0.10 from Travis CI [\#540](https://github.com/shelljs/shelljs/pull/540) ([nfischer](https://github.com/nfischer)) | ||
- chore: add Node v7 for CI [\#539](https://github.com/shelljs/shelljs/pull/539) ([nfischer](https://github.com/nfischer)) | ||
## [v0.7.5](https://github.com/shelljs/shelljs/tree/v0.7.5) (2016-10-27) | ||
[Full Changelog](https://github.com/shelljs/shelljs/compare/v0.7.4...v0.7.5) | ||
**Closed issues:** | ||
- Project objectives: there is some higher goal to achieve? [\#533](https://github.com/shelljs/shelljs/issues/533) | ||
@@ -11,0 +112,0 @@ - fs.existsSync is un-deprecated [\#531](https://github.com/shelljs/shelljs/issues/531) |
{ | ||
"name": "shelljs", | ||
"version": "0.7.5", | ||
"version": "0.7.6", | ||
"description": "Portable Unix shell commands for Node.js", | ||
@@ -16,4 +16,4 @@ "keywords": [ | ||
"contributors": [ | ||
"Ari Porad <ari@ariporad.com> (http://ariporad.com/)", | ||
"Nate Fischer <ntfschr@gmail.com> (https://github.com/nfischer)" | ||
"Nate Fischer <ntfschr@gmail.com> (https://github.com/nfischer)", | ||
"Brandon Freitag <freitagbr@gmail.com> (https://github.com/freitagbr)" | ||
], | ||
@@ -27,5 +27,15 @@ "repository": { | ||
"main": "./shell.js", | ||
"files": [ | ||
"commands.json", | ||
"global.js", | ||
"make.js", | ||
"plugin.js", | ||
"shell.js", | ||
"bin", | ||
"src" | ||
], | ||
"scripts": { | ||
"posttest": "npm run lint", | ||
"test": "node scripts/run-tests", | ||
"test": "nyc --reporter=text --reporter=lcov ava --serial test/*.js", | ||
"test-no-coverage": "ava --serial test/*.js", | ||
"gendocs": "node scripts/generate-docs", | ||
@@ -48,8 +58,11 @@ "lint": "eslint .", | ||
"devDependencies": { | ||
"ava": "^0.16.0", | ||
"coffee-script": "^1.10.0", | ||
"eslint": "^2.0.0", | ||
"eslint-config-airbnb-base": "^3.0.0", | ||
"eslint-plugin-import": "^1.11.1", | ||
"coffee-script": "^1.10.0", | ||
"nyc": "^10.0.0", | ||
"shelljs-changelog": "^0.2.0", | ||
"shelljs-release": "^0.2.0", | ||
"shx": "^0.2.0", | ||
"travis-check-changes": "^0.2.0" | ||
@@ -56,0 +69,0 @@ }, |
547
README.md
@@ -14,3 +14,3 @@ # ShellJS - Unix shell commands for Node.js | ||
ShellJS supports node `v0.11`, `v0.12`, `v4`, `v5`, `v6`, and all releases of iojs. | ||
ShellJS is proudly tested on every node release since `v0.11`! | ||
@@ -160,49 +160,48 @@ The project is [unit-tested](http://travis-ci.org/shelljs/shelljs) and battled-tested in projects like: | ||
### cd([dir]) | ||
Changes to directory `dir` for the duration of the script. Changes to home | ||
directory if no argument is supplied. | ||
### cat(file [, file ...]) | ||
### cat(file_array) | ||
Examples: | ||
### pwd() | ||
Returns the current directory. | ||
```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). | ||
### ls([options,] [path, ...]) | ||
### ls([options,] path_array) | ||
Available options: | ||
+ `-R`: recursive | ||
+ `-A`: all files (include files beginning with `.`, except for `.` and `..`) | ||
+ `-d`: list directories themselves, not their contents | ||
+ `-l`: list objects representing each file, each with fields containing `ls | ||
-l` output fields. See | ||
[fs.Stats](https://nodejs.org/api/fs.html#fs_class_fs_stats) | ||
for more info | ||
### cd([dir]) | ||
Changes to directory `dir` for the duration of the script. Changes to home | ||
directory if no argument is supplied. | ||
Examples: | ||
```javascript | ||
ls('projs/*.js'); | ||
ls('-R', '/users/me', '/tmp'); | ||
ls('-R', ['/users/me', '/tmp']); // same as above | ||
ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...} | ||
``` | ||
### chmod(octal_mode || octal_string, file) | ||
### chmod(symbolic_mode, file) | ||
Returns array of files in the given path, or in current directory if no path provided. | ||
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 | ||
### 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$/); }); | ||
chmod(755, '/Users/brandon'); | ||
chmod('755', '/Users/brandon'); // same as above | ||
chmod('u+x', '/Users/brandon'); | ||
``` | ||
Returns array of all files (however deep) in the given paths. | ||
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: | ||
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`. | ||
+ 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. | ||
@@ -233,65 +232,87 @@ | ||
### rm([options,] file [, file ...]) | ||
### rm([options,] file_array) | ||
### pushd([options,] [dir | '-N' | '+N']) | ||
Available options: | ||
+ `-f`: force | ||
+ `-r, -R`: recursive | ||
+ `-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 | ||
rm('-rf', '/tmp/*'); | ||
rm('some_file.txt', 'another_file.txt'); | ||
rm(['some_file.txt', 'another_file.txt']); // same as above | ||
// process.cwd() === '/usr' | ||
pushd('/etc'); // Returns /etc /usr | ||
pushd('+1'); // Returns /usr /etc | ||
``` | ||
Removes files. | ||
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. | ||
### popd([options,] ['-N' | '+N']) | ||
### mv([options ,] source [, source ...], dest') | ||
### mv([options ,] source_array, dest') | ||
Available options: | ||
+ `-f`: force (default behavior) | ||
+ `-n`: no-clobber | ||
+ `-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 | ||
mv('-n', 'file', 'dir/'); | ||
mv('file1', 'file2', 'dir/'); | ||
mv(['file1', 'file2'], 'dir/'); // same as above | ||
echo(process.cwd()); // '/usr' | ||
pushd('/etc'); // '/etc /usr' | ||
echo(process.cwd()); // '/etc' | ||
popd(); // '/usr' | ||
echo(process.cwd()); // '/usr' | ||
``` | ||
Moves files. | ||
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']) | ||
### mkdir([options,] dir [, dir ...]) | ||
### mkdir([options,] dir_array) | ||
Available options: | ||
+ `-p`: full path (will create intermediate dirs if necessary) | ||
+ `-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 | ||
### echo([options,] string [, string ...]) | ||
Available options: | ||
+ `-e`: interpret backslash escapes (default) | ||
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 | ||
echo('hello world'); | ||
var str = echo('hello world'); | ||
``` | ||
Creates directories. | ||
Prints string to stdout, and returns string with additional utility methods | ||
like `.to()`. | ||
### test(expression) | ||
Available expression primaries: | ||
### exec(command [, options] [, callback]) | ||
Available options (all `false` by default): | ||
+ `'-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 symbolic link | ||
+ `'-p', 'path'`: true if path is a pipe (FIFO) | ||
+ `'-S', 'path'`: true if path is a socket | ||
+ `async`: Asynchronous execution. If a callback is provided, it will be set to | ||
`true`, regardless of the passed value. | ||
+ `silent`: Do not echo program output to console. | ||
+ and any option available to NodeJS's | ||
[child_process.exec()](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) | ||
@@ -301,25 +322,64 @@ Examples: | ||
```javascript | ||
if (test('-d', path)) { /* do something with dir */ }; | ||
if (!test('-f', path)) continue; // skip if it's a regular file | ||
var version = exec('node --version', {silent:true}).stdout; | ||
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, stdout, stderr) { | ||
console.log('Exit code:', code); | ||
console.log('Program output:', stdout); | ||
console.log('Program stderr:', stderr); | ||
}); | ||
``` | ||
Evaluates expression using the available primaries and returns corresponding value. | ||
Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous | ||
mode, this returns a ShellString (compatible with ShellJS v0.6.x, which returns an object | ||
of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process | ||
object, and the `callback` gets the arguments `(code, stdout, stderr)`. | ||
Not seeing the behavior you want? `exec()` runs everything through `sh` | ||
by default (or `cmd.exe` on Windows), which differs from `bash`. If you | ||
need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option. | ||
### cat(file [, file ...]) | ||
### cat(file_array) | ||
**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. | ||
### find(path [, path ...]) | ||
### find(path_array) | ||
Examples: | ||
```javascript | ||
var str = cat('file*.txt'); | ||
var str = cat('file1', 'file2'); | ||
var str = cat(['file1', 'file2']); // same as above | ||
find('src', 'lib'); | ||
find(['src', 'lib']); // same as above | ||
find('.').filter(function(file) { return file.match(/\.js$/); }); | ||
``` | ||
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). | ||
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`. | ||
### 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. | ||
+ `-l`: Print only filenames of matching files | ||
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`. | ||
### head([{'-n': \<num\>},] file [, file ...]) | ||
@@ -342,7 +402,7 @@ ### head([{'-n': \<num\>},] file_array) | ||
### tail([{'-n': \<num\>},] file [, file ...]) | ||
### tail([{'-n': \<num\>},] file_array) | ||
### ln([options,] source, dest) | ||
Available options: | ||
+ `-n <num>`: Show the last `<num>` lines of the files | ||
+ `-s`: symlink | ||
+ `-f`: force | ||
@@ -352,40 +412,38 @@ Examples: | ||
```javascript | ||
var str = tail({'-n': 1}, 'file*.txt'); | ||
var str = tail('file1', 'file2'); | ||
var str = tail(['file1', 'file2']); // same as above | ||
ln('file', 'newlink'); | ||
ln('-sf', 'file', 'existing'); | ||
``` | ||
Read the end of a file. | ||
Links source to dest. Use -f to force the link, should dest already exist. | ||
### ShellString.prototype.to(file) | ||
### ls([options,] [path, ...]) | ||
### ls([options,] path_array) | ||
Available options: | ||
Examples: | ||
+ `-R`: recursive | ||
+ `-A`: all files (include files beginning with `.`, except for `.` and `..`) | ||
+ `-d`: list directories themselves, not their contents | ||
+ `-l`: list objects representing each file, each with fields containing `ls | ||
-l` output fields. See | ||
[fs.Stats](https://nodejs.org/api/fs.html#fs_class_fs_stats) | ||
for more info | ||
```javascript | ||
cat('input.txt').to('output.txt'); | ||
``` | ||
Analogous to the redirection operator `>` in Unix, but works with | ||
ShellStrings (such as those returned by `cat`, `grep`, etc). _Like Unix | ||
redirections, `to()` will overwrite any existing file!_ | ||
### ShellString.prototype.toEnd(file) | ||
Examples: | ||
```javascript | ||
cat('input.txt').toEnd('output.txt'); | ||
ls('projs/*.js'); | ||
ls('-R', '/users/me', '/tmp'); | ||
ls('-R', ['/users/me', '/tmp']); // same as above | ||
ls('-l', 'file.txt'); // { name: 'file.txt', mode: 33188, nlink: 1, ...} | ||
``` | ||
Analogous to the redirect-and-append operator `>>` in Unix, but works with | ||
ShellStrings (such as those returned by `cat`, `grep`, etc). | ||
Returns array of files in the given path, or in current directory if no path provided. | ||
### sed([options,] search_regex, replacement, file [, file ...]) | ||
### sed([options,] search_regex, replacement, file_array) | ||
### mkdir([options,] dir [, dir ...]) | ||
### mkdir([options,] dir_array) | ||
Available options: | ||
+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ | ||
+ `-p`: full path (will create intermediate dirs if necessary) | ||
@@ -395,16 +453,15 @@ Examples: | ||
```javascript | ||
sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js'); | ||
sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); | ||
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 | ||
``` | ||
Reads an input string from `files` and performs a JavaScript `replace()` on the input | ||
using the given search regex and replacement string or function. Returns the new string after replacement. | ||
Creates directories. | ||
### sort([options,] file [, file ...]) | ||
### sort([options,] file_array) | ||
### mv([options ,] source [, source ...], dest') | ||
### mv([options ,] source_array, dest') | ||
Available options: | ||
+ `-r`: Reverse the result of comparisons | ||
+ `-n`: Compare according to numerical value | ||
+ `-f`: force (default behavior) | ||
+ `-n`: no-clobber | ||
@@ -414,16 +471,20 @@ Examples: | ||
```javascript | ||
sort('foo.txt', 'bar.txt'); | ||
sort('-r', 'foo.txt'); | ||
mv('-n', 'file', 'dir/'); | ||
mv('file1', 'file2', 'dir/'); | ||
mv(['file1', 'file2'], 'dir/'); // same as above | ||
``` | ||
Return the contents of the files, sorted line-by-line. Sorting multiple | ||
files mixes their content, just like unix sort does. | ||
Moves files. | ||
### uniq([options,] [input, [output]]) | ||
### pwd() | ||
Returns the current directory. | ||
### rm([options,] file [, file ...]) | ||
### rm([options,] file_array) | ||
Available options: | ||
+ `-i`: Ignore case while comparing | ||
+ `-c`: Prefix lines by the number of occurrences | ||
+ `-d`: Only print duplicate lines, one for each group of identical lines | ||
+ `-f`: force | ||
+ `-r, -R`: recursive | ||
@@ -433,16 +494,15 @@ Examples: | ||
```javascript | ||
uniq('foo.txt'); | ||
uniq('-i', 'foo.txt'); | ||
uniq('-cd', 'foo.txt', 'bar.txt'); | ||
rm('-rf', '/tmp/*'); | ||
rm('some_file.txt', 'another_file.txt'); | ||
rm(['some_file.txt', 'another_file.txt']); // same as above | ||
``` | ||
Filter adjacent matching lines from input | ||
Removes files. | ||
### grep([options,] regex_filter, file [, file ...]) | ||
### grep([options,] regex_filter, file_array) | ||
### sed([options,] search_regex, replacement, file [, file ...]) | ||
### sed([options,] search_regex, replacement, file_array) | ||
Available options: | ||
+ `-v`: Inverse the sense of the regex and print the lines not matching the criteria. | ||
+ `-l`: Print only filenames of matching files | ||
+ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_ | ||
@@ -452,27 +512,25 @@ Examples: | ||
```javascript | ||
grep('-v', 'GLOBAL_VARIABLE', '*.js'); | ||
grep('GLOBAL_VARIABLE', '*.js'); | ||
sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js'); | ||
sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js'); | ||
``` | ||
Reads input string from given files and returns a string containing all lines of the | ||
file that match the given `regex_filter`. | ||
Reads an input string from `files` and performs a JavaScript `replace()` on the input | ||
using the given search regex and replacement string or function. Returns the new string after replacement. | ||
Note: | ||
### which(command) | ||
Like unix `sed`, ShellJS `sed` supports capture groups. Capture groups are specified | ||
using the `$n` syntax: | ||
Examples: | ||
```javascript | ||
var nodeExec = which('node'); | ||
sed(/(\w+)\s(\w+)/, '$2, $1', 'file.txt'); | ||
``` | ||
Searches for `command` in the system's PATH. On Windows, this uses the | ||
`PATHEXT` variable to append the extension if it's not already executable. | ||
Returns string containing the absolute path to the command. | ||
### echo([options,] string [, string ...]) | ||
### set(options) | ||
Available options: | ||
+ `-e`: interpret backslash escapes (default) | ||
+ `+/-e`: exit upon error (`config.fatal`) | ||
+ `+/-v`: verbose: show all commands (`config.verbose`) | ||
+ `+/-f`: disable filename expansion (globbing) | ||
@@ -482,160 +540,103 @@ Examples: | ||
```javascript | ||
echo('hello world'); | ||
var str = echo('hello world'); | ||
set('-e'); // exit upon first error | ||
set('+e'); // this undoes a "set('-e')" | ||
``` | ||
Prints string to stdout, and returns string with additional utility methods | ||
like `.to()`. | ||
Sets global configuration variables | ||
### pushd([options,] [dir | '-N' | '+N']) | ||
### sort([options,] file [, file ...]) | ||
### sort([options,] file_array) | ||
Available options: | ||
+ `-n`: Suppresses the normal change of directory when adding directories to the stack, so that only the stack is manipulated. | ||
+ `-r`: Reverse the result of comparisons | ||
+ `-n`: Compare according to numerical value | ||
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 | ||
sort('foo.txt', 'bar.txt'); | ||
sort('-r', 'foo.txt'); | ||
``` | ||
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. | ||
Return the contents of the files, sorted line-by-line. Sorting multiple | ||
files mixes their content, just like unix sort does. | ||
### popd([options,] ['-N' | '+N']) | ||
### tail([{'-n': \<num\>},] file [, file ...]) | ||
### tail([{'-n': \<num\>},] file_array) | ||
Available options: | ||
+ `-n`: Suppresses the normal change of directory when removing directories from the stack, so that only the stack is manipulated. | ||
+ `-n <num>`: Show the last `<num>` lines of the files | ||
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' | ||
var str = tail({'-n': 1}, 'file*.txt'); | ||
var str = tail('file1', 'file2'); | ||
var str = tail(['file1', 'file2']); // same as above | ||
``` | ||
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. | ||
Read the end of a file. | ||
### dirs([options | '+N' | '-N']) | ||
Available options: | ||
### tempdir() | ||
+ `-c`: Clears the directory stack by deleting all of the elements. | ||
Examples: | ||
Arguments: | ||
```javascript | ||
var tmp = tempdir(); // "/tmp" for most *nix platforms | ||
``` | ||
+ `+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. | ||
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). | ||
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 | ||
### 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 symbolic link | ||
+ `'-p', 'path'`: true if path is a pipe (FIFO) | ||
+ `'-S', 'path'`: true if path is a socket | ||
### ln([options,] source, dest) | ||
Available options: | ||
+ `-s`: symlink | ||
+ `-f`: force | ||
Examples: | ||
```javascript | ||
ln('file', 'newlink'); | ||
ln('-sf', 'file', 'existing'); | ||
if (test('-d', path)) { /* do something with dir */ }; | ||
if (!test('-f', path)) continue; // skip if it's a regular file | ||
``` | ||
Links source to dest. Use -f to force the link, should dest already exist. | ||
Evaluates expression using the available primaries and returns corresponding value. | ||
### exit(code) | ||
Exits the current process with the given exit code. | ||
### ShellString.prototype.to(file) | ||
### env['VAR_NAME'] | ||
Object containing environment variables (both getter and setter). Shortcut to process.env. | ||
### exec(command [, options] [, callback]) | ||
Available options (all `false` by default): | ||
+ `async`: Asynchronous execution. If a callback is provided, it will be set to | ||
`true`, regardless of the passed value. | ||
+ `silent`: Do not echo program output to console. | ||
+ and any option available to NodeJS's | ||
[child_process.exec()](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) | ||
Examples: | ||
```javascript | ||
var version = exec('node --version', {silent:true}).stdout; | ||
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, stdout, stderr) { | ||
console.log('Exit code:', code); | ||
console.log('Program output:', stdout); | ||
console.log('Program stderr:', stderr); | ||
}); | ||
cat('input.txt').to('output.txt'); | ||
``` | ||
Executes the given `command` _synchronously_, unless otherwise specified. When in synchronous | ||
mode, this returns a ShellString (compatible with ShellJS v0.6.x, which returns an object | ||
of the form `{ code:..., stdout:... , stderr:... }`). Otherwise, this returns the child process | ||
object, and the `callback` gets the arguments `(code, stdout, stderr)`. | ||
Analogous to the redirection operator `>` in Unix, but works with | ||
ShellStrings (such as those returned by `cat`, `grep`, etc). _Like Unix | ||
redirections, `to()` will overwrite any existing file!_ | ||
Not seeing the behavior you want? `exec()` runs everything through `sh` | ||
by default (or `cmd.exe` on Windows), which differs from `bash`. If you | ||
need bash-specific behavior, try out the `{shell: 'path/to/bash'}` option. | ||
**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. | ||
### ShellString.prototype.toEnd(file) | ||
### 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'); | ||
cat('input.txt').toEnd('output.txt'); | ||
``` | ||
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: | ||
Analogous to the redirect-and-append operator `>>` in Unix, but works with | ||
ShellStrings (such as those returned by `cat`, `grep`, etc). | ||
+ 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. | ||
### touch([options,] file [, file ...]) | ||
@@ -664,8 +665,8 @@ ### touch([options,] file_array) | ||
### set(options) | ||
### uniq([options,] [input, [output]]) | ||
Available options: | ||
+ `+/-e`: exit upon error (`config.fatal`) | ||
+ `+/-v`: verbose: show all commands (`config.verbose`) | ||
+ `+/-f`: disable filename expansion (globbing) | ||
+ `-i`: Ignore case while comparing | ||
+ `-c`: Prefix lines by the number of occurrences | ||
+ `-d`: Only print duplicate lines, one for each group of identical lines | ||
@@ -675,24 +676,26 @@ Examples: | ||
```javascript | ||
set('-e'); // exit upon first error | ||
set('+e'); // this undoes a "set('-e')" | ||
uniq('foo.txt'); | ||
uniq('-i', 'foo.txt'); | ||
uniq('-cd', 'foo.txt', 'bar.txt'); | ||
``` | ||
Sets global configuration variables | ||
Filter adjacent matching lines from input | ||
## Non-Unix commands | ||
### which(command) | ||
### tempdir() | ||
Examples: | ||
```javascript | ||
var tmp = tempdir(); // "/tmp" for most *nix platforms | ||
var nodeExec = which('node'); | ||
``` | ||
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). | ||
Searches for `command` in the system's PATH. On Windows, this uses the | ||
`PATHEXT` variable to append the extension if it's not already executable. | ||
Returns string containing the absolute path to the command. | ||
### exit(code) | ||
Exits the current process with the given exit code. | ||
### error() | ||
@@ -719,2 +722,6 @@ Tests if error occurred in the last command. Returns a truthy value if an | ||
### env['VAR_NAME'] | ||
Object containing environment variables (both getter and setter). Shortcut | ||
to process.env. | ||
### Pipes | ||
@@ -794,2 +801,28 @@ | ||
### config.reset() | ||
Example: | ||
```javascript | ||
var shell = require('shelljs'); | ||
// Make changes to shell.config, and do stuff... | ||
/* ... */ | ||
shell.config.reset(); // reset to original state | ||
// Do more stuff, but with original settings | ||
/* ... */ | ||
``` | ||
Reset shell.config to the defaults: | ||
```javascript | ||
{ | ||
fatal: false, | ||
globOptions: {}, | ||
maxdepth: 255, | ||
noglob: false, | ||
silent: false, | ||
verbose: false, | ||
} | ||
``` | ||
## Team | ||
@@ -796,0 +829,0 @@ |
146
shell.js
@@ -6,3 +6,3 @@ // | ||
// Copyright (c) 2012 Artur Adib | ||
// http://github.com/arturadib/shelljs | ||
// http://github.com/shelljs/shelljs | ||
// | ||
@@ -21,83 +21,10 @@ | ||
// Boilerplate | ||
// ----------- | ||
// Copy the code block below here & replace variables with appropiate values | ||
// ``` | ||
// //@include ./src/fileName | ||
// var functionName = require('./src/fileName'); | ||
// exports.nameOfCommand = common.wrap(nameOfCommand, functionName, {globStart: firstIndexToExpand}); | ||
// ``` | ||
// | ||
// The //@include includes the docs for that command | ||
// | ||
// firstIndexToExpand should usually be 1 (so, put {globStart: 1}) | ||
// Increase this value if the command takes arguments that shouldn't be expanded | ||
// with wildcards, such as with the regexes for sed & grep | ||
// Include the docs for all the default commands | ||
//@commands | ||
//@include ./src/cd | ||
require('./src/cd'); | ||
// Load all default commands | ||
require('./commands.json').forEach(function (command) { | ||
require('./src/' + command); | ||
}); | ||
//@include ./src/pwd | ||
require('./src/pwd'); | ||
//@include ./src/ls | ||
require('./src/ls'); | ||
//@include ./src/find | ||
require('./src/find'); | ||
//@include ./src/cp | ||
require('./src/cp'); | ||
//@include ./src/rm | ||
require('./src/rm'); | ||
//@include ./src/mv | ||
require('./src/mv'); | ||
//@include ./src/mkdir | ||
require('./src/mkdir'); | ||
//@include ./src/test | ||
require('./src/test'); | ||
//@include ./src/cat | ||
require('./src/cat'); | ||
//@include ./src/head | ||
require('./src/head'); | ||
//@include ./src/tail | ||
require('./src/tail'); | ||
//@include ./src/to | ||
require('./src/to'); | ||
//@include ./src/toEnd | ||
require('./src/toEnd'); | ||
//@include ./src/sed | ||
require('./src/sed'); | ||
//@include ./src/sort | ||
require('./src/sort'); | ||
//@include ./src/uniq | ||
require('./src/uniq'); | ||
//@include ./src/grep | ||
require('./src/grep'); | ||
//@include ./src/which | ||
require('./src/which'); | ||
//@include ./src/echo | ||
require('./src/echo'); | ||
//@include ./src/dirs | ||
require('./src/dirs'); | ||
//@include ./src/ln | ||
require('./src/ln'); | ||
//@ | ||
@@ -108,29 +35,3 @@ //@ ### exit(code) | ||
//@ | ||
//@ ### env['VAR_NAME'] | ||
//@ Object containing environment variables (both getter and setter). Shortcut to process.env. | ||
exports.env = process.env; | ||
//@include ./src/exec | ||
require('./src/exec'); | ||
//@include ./src/chmod | ||
require('./src/chmod'); | ||
//@include ./src/touch | ||
require('./src/touch'); | ||
//@include ./src/set | ||
require('./src/set'); | ||
//@ | ||
//@ ## Non-Unix commands | ||
//@ | ||
//@include ./src/tempdir | ||
require('./src/tempdir'); | ||
//@include ./src/error | ||
exports.error = require('./src/error'); | ||
@@ -142,2 +43,8 @@ | ||
//@ | ||
//@ ### env['VAR_NAME'] | ||
//@ Object containing environment variables (both getter and setter). Shortcut | ||
//@ to process.env. | ||
exports.env = process.env; | ||
//@ | ||
//@ ### Pipes | ||
@@ -223,1 +130,28 @@ //@ | ||
//@ Use this value for calls to `glob.sync()` instead of the default options. | ||
//@ | ||
//@ ### config.reset() | ||
//@ | ||
//@ Example: | ||
//@ | ||
//@ ```javascript | ||
//@ var shell = require('shelljs'); | ||
//@ // Make changes to shell.config, and do stuff... | ||
//@ /* ... */ | ||
//@ shell.config.reset(); // reset to original state | ||
//@ // Do more stuff, but with original settings | ||
//@ /* ... */ | ||
//@ ``` | ||
//@ | ||
//@ Reset shell.config to the defaults: | ||
//@ | ||
//@ ```javascript | ||
//@ { | ||
//@ fatal: false, | ||
//@ globOptions: {}, | ||
//@ maxdepth: 255, | ||
//@ noglob: false, | ||
//@ silent: false, | ||
//@ verbose: false, | ||
//@ } | ||
//@ ``` |
@@ -12,11 +12,47 @@ // Ignore warning about 'new String()' | ||
// Module globals | ||
var config = { | ||
// objectAssign(target_obj, source_obj1 [, source_obj2 ...]) | ||
// "Ponyfill" for Object.assign | ||
// objectAssign({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3} | ||
var objectAssign = typeof Object.assign === 'function' ? | ||
Object.assign : | ||
function objectAssign(target) { | ||
var sources = [].slice.call(arguments, 1); | ||
sources.forEach(function (source) { | ||
Object.keys(source).forEach(function (key) { | ||
target[key] = source[key]; | ||
}); | ||
}); | ||
return target; | ||
}; | ||
exports.extend = objectAssign; | ||
// Check if we're running under electron | ||
var isElectron = Boolean(process.versions.electron); | ||
// Module globals (assume no execPath by default) | ||
var DEFAULT_CONFIG = { | ||
fatal: false, | ||
globOptions: {}, | ||
maxdepth: 255, | ||
noglob: false, | ||
silent: false, | ||
fatal: false, | ||
verbose: false, | ||
noglob: false, | ||
globOptions: {}, | ||
maxdepth: 255 | ||
execPath: null, | ||
}; | ||
var config = { | ||
reset: function () { | ||
objectAssign(this, DEFAULT_CONFIG); | ||
if (!isElectron) { | ||
this.execPath = process.execPath; | ||
} | ||
}, | ||
resetForTesting: function () { | ||
this.reset(); | ||
this.silent = true; | ||
}, | ||
}; | ||
config.reset(); | ||
exports.config = config; | ||
@@ -139,3 +175,3 @@ | ||
// parseOptions({'-r': 'string-value'}, {'r':'reference', 'b':'bob'}); | ||
function parseOptions(opt, map) { | ||
function parseOptions(opt, map, errorOptions) { | ||
if (!map) error('parseOptions() internal error: no map given'); | ||
@@ -170,2 +206,4 @@ | ||
} | ||
} else if (typeof errorOptions === 'object') { | ||
error('option not recognized: ' + c, errorOptions); | ||
} else { | ||
@@ -182,2 +220,4 @@ error('option not recognized: ' + c); | ||
options[optionName] = opt[key]; // assign the given value | ||
} else if (typeof errorOptions === 'object') { | ||
error('option not recognized: ' + c, errorOptions); | ||
} else { | ||
@@ -187,2 +227,4 @@ error('option not recognized: ' + c); | ||
}); | ||
} else if (typeof errorOptions === 'object') { | ||
error('options must be strings or key-value pairs', errorOptions); | ||
} else { | ||
@@ -252,17 +294,2 @@ error('options must be strings or key-value pairs'); | ||
// objectAssign(target_obj, source_obj1 [, source_obj2 ...]) | ||
// Ponyfill for Object.assign | ||
// objectAssign({A:1}, {b:2}, {c:3}) returns {A:1, b:2, c:3} | ||
function objectAssign(target) { | ||
var sources = [].slice.call(arguments, 1); | ||
sources.forEach(function (source) { | ||
Object.keys(source).forEach(function (key) { | ||
target[key] = source[key]; | ||
}); | ||
}); | ||
return target; | ||
} | ||
exports.extend = Object.assign || objectAssign; | ||
// Common wrapper for all Unix-like commands that performs glob expansion, | ||
@@ -269,0 +296,0 @@ // command-logging, and other nice things |
@@ -87,14 +87,8 @@ var fs = require('fs'); | ||
// http://www.opensource.org/licenses/mit-license.php | ||
function cpdirSyncRecursive(sourceDir, destDir, opts) { | ||
function cpdirSyncRecursive(sourceDir, destDir, currentDepth, opts) { | ||
if (!opts) opts = {}; | ||
/* Ensure there is not a run away recursive copy. */ | ||
if (typeof opts.depth === 'undefined') { | ||
opts.depth = 0; | ||
} | ||
if (opts.depth >= common.config.maxdepth) { | ||
// Max depth has been reached, end copy. | ||
return; | ||
} | ||
opts.depth++; | ||
// Ensure there is not a run away recursive copy | ||
if (currentDepth >= common.config.maxdepth) return; | ||
currentDepth++; | ||
@@ -130,3 +124,3 @@ // Create the directory where all our junk is moving to; read the mode of the | ||
/* recursion this thing right on back. */ | ||
cpdirSyncRecursive(srcFile, destFile, opts); | ||
cpdirSyncRecursive(srcFile, destFile, currentDepth, opts); | ||
} else if (srcFileStat.isSymbolicLink() && !opts.followsymlink) { | ||
@@ -144,3 +138,3 @@ symlinkFull = fs.readlinkSync(srcFile); | ||
if (srcFileStat.isDirectory()) { | ||
cpdirSyncRecursive(srcFile, destFile, opts); | ||
cpdirSyncRecursive(srcFile, destFile, currentDepth, opts); | ||
} else { | ||
@@ -253,3 +247,3 @@ copyFileSync(srcFile, destFile, opts); | ||
fs.statSync(path.dirname(dest)); | ||
cpdirSyncRecursive(src, newDest, { no_force: options.no_force, followsymlink: options.followsymlink }); | ||
cpdirSyncRecursive(src, newDest, 0, { no_force: options.no_force, followsymlink: options.followsymlink }); | ||
} catch (e) { | ||
@@ -256,0 +250,0 @@ common.error("cannot create directory '" + dest + "': No such file or directory"); |
@@ -22,2 +22,6 @@ var common = require('./common'); | ||
function execSync(cmd, opts, pipe) { | ||
if (!common.config.execPath) { | ||
common.error('Unable to find a path to the node binary. Please manually set config.execPath'); | ||
} | ||
var tempDir = _tempDir(); | ||
@@ -70,3 +74,3 @@ var stdoutFile = path.resolve(tempDir + '/' + common.randomFileName()); | ||
var execCommand = JSON.stringify(process.execPath) + ' ' + JSON.stringify(scriptFile); | ||
var execCommand = JSON.stringify(common.config.execPath) + ' ' + JSON.stringify(scriptFile); | ||
var script; | ||
@@ -82,3 +86,10 @@ | ||
'var childProcess = child.exec(' + JSON.stringify(cmd) + ', ' + optString + ', function(err) {', | ||
' fs.writeFileSync(' + JSON.stringify(codeFile) + ", err ? err.code.toString() : '0');", | ||
' var fname = ' + JSON.stringify(codeFile) + ';', | ||
' if (!err) {', | ||
' fs.writeFileSync(fname, "0");', | ||
' } else if (err.code === undefined) {', | ||
' fs.writeFileSync(fname, "1");', | ||
' } else {', | ||
' fs.writeFileSync(fname, err.code.toString());', | ||
' }', | ||
'});', | ||
@@ -90,3 +101,3 @@ 'var stdoutStream = fs.createWriteStream(' + JSON.stringify(stdoutFile) + ');', | ||
'childProcess.stdout.pipe(process.stdout);', | ||
'childProcess.stderr.pipe(process.stderr);' | ||
'childProcess.stderr.pipe(process.stderr);', | ||
].join('\n') + | ||
@@ -99,3 +110,3 @@ (pipe ? '\nchildProcess.stdin.end(' + JSON.stringify(pipe) + ');\n' : '\n') + | ||
"childProcess.stdout.on('end', function(){ stdoutEnded = true; tryClosingStdout(); });", | ||
"childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosingStderr(); });" | ||
"childProcess.stderr.on('end', function(){ stderrEnded = true; tryClosingStderr(); });", | ||
].join('\n'); | ||
@@ -129,4 +140,11 @@ | ||
'var childProcess = child.exec(' + JSON.stringify(cmd) + ', ' + optString + ', function(err) {', | ||
' fs.writeFileSync(' + JSON.stringify(codeFile) + ", err ? err.code.toString() : '0');", | ||
'});' | ||
' var fname = ' + JSON.stringify(codeFile) + ';', | ||
' if (!err) {', | ||
' fs.writeFileSync(fname, "0");', | ||
' } else if (err.code === undefined) {', | ||
' fs.writeFileSync(fname, "1");', | ||
' } else {', | ||
' fs.writeFileSync(fname, err.code.toString());', | ||
' }', | ||
'});', | ||
].join('\n') + | ||
@@ -186,3 +204,10 @@ (pipe ? '\nchildProcess.stdin.end(' + JSON.stringify(pipe) + ');\n' : '\n'); | ||
if (callback) { | ||
callback(err ? err.code : 0, stdout, stderr); | ||
if (!err) { | ||
callback(0, stdout, stderr); | ||
} else if (err.code === undefined) { | ||
// See issue #536 | ||
callback(1, stdout, stderr); | ||
} else { | ||
callback(err.code, stdout, stderr); | ||
} | ||
} | ||
@@ -189,0 +214,0 @@ }); |
@@ -78,3 +78,3 @@ var common = require('./common'); | ||
if (options.fullpath) { | ||
mkdirSyncRecursive(dir); | ||
mkdirSyncRecursive(path.resolve(dir)); | ||
} else { | ||
@@ -81,0 +81,0 @@ fs.mkdirSync(dir, parseInt('0777', 8)); |
@@ -50,3 +50,5 @@ var common = require('./common'); | ||
var start = Date.now(); | ||
while (true) { | ||
// TODO: replace this with a finite loop | ||
for (;;) { | ||
try { | ||
@@ -125,28 +127,19 @@ result = fs.rmdirSync(dir); | ||
// If here, path exists | ||
if (stats.isFile() || stats.isSymbolicLink()) { | ||
// Do not check for file writing permissions | ||
if (options.force) { | ||
if (stats.isFile()) { | ||
if (options.force || isWriteable(file)) { | ||
// -f was passed, or file is writable, so it can be removed | ||
common.unlinkSync(file); | ||
return; | ||
} | ||
if (isWriteable(file)) { | ||
common.unlinkSync(file); | ||
} else { | ||
common.error('permission denied: ' + file, { continue: true }); | ||
} | ||
return; | ||
} // simple file | ||
// Path is an existing directory, but no -r flag given | ||
if (stats.isDirectory() && !options.recursive) { | ||
common.error('path is a directory', { continue: true }); | ||
return; // skip path | ||
} else if (stats.isDirectory()) { | ||
if (options.recursive) { | ||
// -r was passed, so directory can be removed | ||
rmdirSyncRecursive(file, options.force); | ||
} else { | ||
common.error('path is a directory', { continue: true }); | ||
} | ||
} else if (stats.isSymbolicLink()) { | ||
common.unlinkSync(file); | ||
} | ||
// Recursively remove existing directory | ||
if (stats.isDirectory() && options.recursive) { | ||
rmdirSyncRecursive(file, options.force); | ||
} | ||
}); // forEach(file) | ||
@@ -153,0 +146,0 @@ return ''; |
@@ -28,2 +28,11 @@ var common = require('./common'); | ||
//@ using the given search regex and replacement string or function. Returns the new string after replacement. | ||
//@ | ||
//@ Note: | ||
//@ | ||
//@ Like unix `sed`, ShellJS `sed` supports capture groups. Capture groups are specified | ||
//@ using the `$n` syntax: | ||
//@ | ||
//@ ```javascript | ||
//@ sed(/(\w+)\s(\w+)/, '$2, $1', 'file.txt'); | ||
//@ ``` | ||
function _sed(options, regex, replacement, files) { | ||
@@ -30,0 +39,0 @@ // Check if this is coming from a pipe |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
178966
818
10
41
2953
41
2