Permalink
Browse files

ls() and find() return arrays

  • Loading branch information...
1 parent 9801543 commit 88292eacf8fcd5ddae386122f828537fe8bdb104 @arturadib arturadib committed Mar 22, 2012
Showing with 103 additions and 114 deletions.
  1. +9 −16 README.md
  2. +1 −1 package.json
  3. +2 −2 scripts/run-tests.js
  4. +22 −26 shell.js
  5. +1 −1 test/cp.js
  6. +9 −9 test/find.js
  7. +59 −59 test/ls.js
View
@@ -1,6 +1,7 @@
# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)
-_This project is young and experimental. Use at your own risk._
++ _This project is young and experimental. Use at your own risk._
++ _Major API change as of v0.0.4: `ls()` and `find()` now return arrays._
ShellJS is a **portable** (Windows included) implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands.
@@ -18,11 +19,11 @@ cp('-R', 'stuff/*', 'out/Release');
// Replace macros in each .js file
cd('lib');
-for (file in ls('*.js')) {
+ls('*.js').forEach(function(file) {
sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
-}
+});
cd('..');
// Run external tool synchronously
@@ -73,11 +74,11 @@ target.docs = function() {
cd(__dirname);
mkdir('docs');
cd('lib');
- for (file in ls('*.js')) {
+ ls('*.js').forEach(function(file){
var text = grep('//@', file); // extract special comments
text.replace('//@', ''); // remove comment tags
text.to('docs/my_docs.md');
- }
+ });
}
```
@@ -128,9 +129,7 @@ ls('-R', '/users/me', '/tmp');
ls('-R', ['/users/me', '/tmp']); // same as above
```
-Returns list of files in the given path, or in current directory if no path provided.
-For convenient iteration via `for (file in ls())`, the format returned is a hash object:
-`{ 'file1':null, 'dir1/file2':null, ...}`.
+Returns array of files in the given path, or in current directory if no path provided.
#### find(path [,path ...])
#### find(path_array)
@@ -139,16 +138,10 @@ Examples:
```javascript
find('src', 'lib');
find(['src', 'lib']); // same as above
-for (file in find('.')) {
- if (!file.match(/\.js$/))
- continue;
- // all files at this point end in '.js'
-}
+find('.').filter(function(file) { return file.match(/\.js$/); })
```
-Returns list of all files (however deep) in the given paths. For convenient iteration
-via `for (file in find(...))`, the format returned is a hash object:
-`{ 'file1':null, 'dir1/file2':null, ...}`.
+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`.
View
@@ -1,5 +1,5 @@
{ "name": "shelljs"
-, "version": "0.0.4pre1"
+, "version": "0.0.4"
, "author": "Artur Adib <aadib@mozilla.com>"
, "description": "Portable Unix shell commands for Node.js"
, "keywords": ["unix", "shell", "makefile", "make", "jake", "synchronous"]
View
@@ -4,11 +4,11 @@ require('../global');
var failed = false;
cd(__dirname + '/../test');
-for (file in ls('*.js')) {
+ls('*.js').forEach(function(file) {
echo('Running test:', file);
if (exec('node '+file).code !== 123) // 123 avoids false positives (e.g. premature exit)
failed = true;
-}
+});
if (failed) {
echo();
View
@@ -74,9 +74,7 @@ exports.pwd = wrap('pwd', _pwd);
//@ ls('-R', ['/users/me', '/tmp']); // same as above
//@ ```
//@
-//@ Returns list of files in the given path, or in current directory if no path provided.
-//@ For convenient iteration via `for (file in ls())`, the format returned is a hash object:
-//@ `{ 'file1':null, 'dir1/file2':null, ...}`.
+//@ Returns array of files in the given path, or in current directory if no path provided.
function _ls(options, paths) {
options = parseOptions(options, {
'R': 'recursive',
@@ -90,38 +88,40 @@ function _ls(options, paths) {
else if (typeof paths === 'string')
paths = [].slice.call(arguments, 1);
- var hash = {};
+ var list = [];
- function pushHash(file, query) {
+ // Conditionally pushes file to list
+ // (e.g. prevents hidden files to be included unless explicitly told so)
+ function pushFile(file, query) {
// hidden file?
if (path.basename(file)[0] === '.') {
// not explicitly asking for hidden files?
if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
return;
}
- hash[file] = null;
+ list.push(file);
}
paths.forEach(function(p) {
if (fs.existsSync(p)) {
// Simple file?
if (fs.statSync(p).isFile()) {
- pushHash(p, p);
+ pushFile(p, p);
return; // continue
}
// Simple dir?
if (fs.statSync(p).isDirectory()) {
// Iterate over p contents
fs.readdirSync(p).forEach(function(file) {
- pushHash(file, p);
+ pushFile(file, p);
// Recursive
var oldDir = _pwd();
_cd('', p);
if (fs.statSync(file).isDirectory() && options.recursive)
- hash = extend(hash, _ls('-R', file+'/*'));
+ list = list.concat(_ls('-R', file+'/*'));
_cd('', oldDir);
});
return; // continue
@@ -141,12 +141,12 @@ function _ls(options, paths) {
// Iterate over directory contents
fs.readdirSync(dirname).forEach(function(file) {
if (file.match(new RegExp(regexp))) {
- pushHash(path.normalize(dirname+'/'+file), basename);
+ pushFile(path.normalize(dirname+'/'+file), basename);
// Recursive
var pp = dirname + '/' + file;
if (fs.statSync(pp).isDirectory() && options.recursive)
- hash = extend(hash, _ls('-R', pp+'/*'));
+ list = list.concat(_ls('-R', pp+'/*'));
}
}); // forEach
return;
@@ -155,7 +155,7 @@ function _ls(options, paths) {
error('no such file or directory: ' + p, true);
});
- return hash;
+ return list;
};
exports.ls = wrap('ls', _ls);
@@ -168,16 +168,10 @@ exports.ls = wrap('ls', _ls);
//@ ```javascript
//@ find('src', 'lib');
//@ find(['src', 'lib']); // same as above
-//@ for (file in find('.')) {
-//@ if (!file.match(/\.js$/))
-//@ continue;
-//@ // all files at this point end in '.js'
-//@ }
+//@ find('.').filter(function(file) { return file.match(/\.js$/); });
//@ ```
//@
-//@ Returns list of all files (however deep) in the given paths. For convenient iteration
-//@ via `for (file in find(...))`, the format returned is a hash object:
-//@ `{ 'file1':null, 'dir1/file2':null, ...}`.
+//@ 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`.
@@ -189,21 +183,22 @@ function _find(options, paths) {
else if (typeof paths === 'string')
paths = [].slice.call(arguments, 1);
- var hash = {};
+ var list = [];
// why not simply do ls('-R', paths)? because the output wouldn't give the base dirs
// to get the base dir in the output, we need instead ls('-R', 'dir/*') for every directory
paths.forEach(function(file){
- hash[file] = null;
+ list.push(file);
if (fs.statSync(file).isDirectory()) {
- for (subfile in _ls('-Ra', file+'/*'))
- hash[subfile] = null;
+ _ls('-Ra', file+'/*').forEach(function(subfile) {
+ list.push(subfile);
+ });
}
});
- return hash;
+ return list;
}
exports.find = wrap('find', _find);
@@ -1307,8 +1302,9 @@ function expand(list) {
list.forEach(function(listEl) {
// Wildcard present?
if (listEl.search(/\*/) > -1) {
- for (file in _ls('', listEl))
+ _ls('', listEl).forEach(function(file) {
expanded.push(file);
+ });
} else {
expanded.push(listEl);
}
View
@@ -103,7 +103,7 @@ assert.equal(fs.existsSync('tmp/file2'), true);
shell.rm('-rf', 'tmp/*');
shell.cp('-R', 'resources/cp', 'tmp');
assert.equal(shell.error(), null);
-assert.deepEqual(shell.ls('-R', 'resources/cp'), shell.ls('-R', 'tmp/cp'));
+assert.equal(JSON.stringify(shell.ls('-R', 'resources/cp')), JSON.stringify(shell.ls('-R', 'tmp/cp')));
//recursive, everything exists, no force flag
shell.rm('-rf', 'tmp/*')
View
@@ -27,30 +27,30 @@ assert.ok(shell.error());
shell.cd('resources/find');
var result = shell.find('.');
assert.equal(shell.error(), null);
-assert.equal('.hidden' in result, true);
-assert.equal('dir1/dir11/a_dir11' in result, true);
-assert.equal(Object.keys(result).length, 10);
+assert.equal(result.indexOf('.hidden') > -1, true);
+assert.equal(result.indexOf('dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.length, 10);
shell.cd('../..')
// simple path
var result = shell.find('resources/find');
assert.equal(shell.error(), null);
-assert.equal('resources/find/.hidden' in result, true);
-assert.equal('resources/find/dir1/dir11/a_dir11' in result, true);
+assert.equal(result.indexOf('resources/find/.hidden') > -1, true);
+assert.equal(result.indexOf('resources/find/dir1/dir11/a_dir11') > -1, true);
assert.equal(Object.keys(result).length, 10);
// multiple paths - comma
var result = shell.find('resources/find/dir1', 'resources/find/dir2');
assert.equal(shell.error(), null);
-assert.equal('resources/find/dir1/dir11/a_dir11' in result, true);
-assert.equal('resources/find/dir2/a_dir1' in result, true);
+assert.equal(result.indexOf('resources/find/dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.indexOf('resources/find/dir2/a_dir1') > -1, true);
assert.equal(Object.keys(result).length, 6);
// multiple paths - array
var result = shell.find(['resources/find/dir1', 'resources/find/dir2']);
assert.equal(shell.error(), null);
-assert.equal('resources/find/dir1/dir11/a_dir11' in result, true);
-assert.equal('resources/find/dir2/a_dir1' in result, true);
+assert.equal(result.indexOf('resources/find/dir1/dir11/a_dir11') > -1, true);
+assert.equal(result.indexOf('resources/find/dir2/a_dir1') > -1, true);
assert.equal(Object.keys(result).length, 6);
shell.exit(123);
Oops, something went wrong.

0 comments on commit 88292ea

Please sign in to comment.