Permalink
Browse files

Added initial file list support.

Reviewed by tolmasky.
  • Loading branch information...
Ross Boucher authored and tolmasky committed Sep 28, 2009
1 parent 9d27c73 commit 7aa6e34aa9aa393806c9a030ce4cc3e70d28b55c
Showing with 94 additions and 55 deletions.
  1. +94 −55 lib/jake/filelist.js
View
@@ -1,9 +1,7 @@
-require 'rake/cloneable'
-require 'rake/rake_file_utils'
-
-######################################################################
-module Rake
-
+
+var FILE = require("file");
+
+/*
# #########################################################################
# A FileList is essentially an array with a few helper methods defined to
# make file manipulation a bit easier.
@@ -17,11 +15,7 @@ module Rake
# actually used. The key is that the first time an element of the
# FileList/Array is requested, the pending patterns are resolved into a real
# list of file names.
- #
- class FileList
-
- include Cloneable
-
+
# == Method Delegation
#
# The lazy evaluation magic of FileLists happens by implementing all the
@@ -81,7 +75,18 @@ module Rake
}, __FILE__, ln
end
end
-
+*/
+
+var DEFAULT_IGNORE_PATTERNS = [
+ /(^|[\/\\])CVS([\/\\]|$)/,
+ /(^|[\/\\])\.svn([\/\\]|$)/,
+ /\.bak$/,
+ /~$/
+ ],
+ DEFAULT_IGNORE_PROCS = [
+ function(fn) { return /(^|[\/\\])core$/.test(fn) && !FILE.isDirectory(fn) }
+ ];
+
// Create a file list from the globbable patterns given. If you wish to
// perform multiple includes or excludes at object build time, use the
// "yield self" pattern.
@@ -93,20 +98,42 @@ module Rake
// fl.exclude(/\bCVS\b/)
// end
//
-function FileList(/*Strings*/)
+function FileList(/*Strings, vararg*/)
{
this._pendingAdd = [];
this._pending = false;
this._excludedPatterns = DEFAULT_IGNORE_PATTERNS.slice();
this._excludedProcs = DEFAULT_IGNORE_PROCS.slice();
this._items = [];
- Array.prototype.forEach.apply(arguments, function(/*String*/ aPattern)
+ Array.prototype.forEach.apply(arguments, function(anArgument)
{
- this.include(aPattern);
+ this.include(anArgument);
}, this);
+
+ this.__defineGetter__("length", FileList.prototype.size);
}
-
+
+["forEach", "filter", "map", "select",
+"sort", "uniq", "push", "pop", "shift",
+"unshift"].forEach(function(string)
+{
+ FileList.prototype[string] = function() {
+ return (Array.prototype[string]).apply(this.items(), arguments);
+ };
+});
+
+FileList.prototype.items = function()
+{
+ this.resolve();
+ return this._items;
+}
+
+FileList.prototype.size = function()
+{
+ return this.items().length;
+}
+
// Add file names defined by glob patterns to the file list. If an array
// is given, add each element of the array.
//
@@ -117,25 +144,25 @@ function FileList(/*Strings*/)
FileList.prototype.include = function(/*Strings | Arrays*/)
{
// TODO: check for pending
- Array.prototype.forEach.apply(arguments, function(/*String|Array|FileList*/ anObject)
+ Array.prototype.forEach.apply(arguments, [function(/*String|Array|FileList*/ anObject)
{
if (Array.isArray(anObject))
this.include.apply(this, anObject);
-
- else if (typeof aFilename.toArray === "function")
+
+ else if (typeof anObject.toArray === "function")
this.include.apply(this, anObject.toArray());
-
+
else
this._pendingAdd.push(anObject);
- }, this);
+ }, this]);
this._pending = true;
-
+
return this;
}
FileList.prototype.add = FileList.prototype.include;
-
+
// Register a list of file name patterns that should be excluded from the
// list. Patterns may be regular expressions, glob patterns or regular
// strings. In addition, a block given to exclude will remove entries that
@@ -162,11 +189,11 @@ FileList.prototype.exclude = function(/*Strings|Functions*/)
{
if (typeof anObject === "function")
this._excludedProcs.push(anObject);
-
+
else
this._excludedPatterns.push(anObject);
}, this);
-
+
if (!this._pending)
this._resolveExclude();
@@ -181,6 +208,7 @@ FileList.prototype.clearExclude = function()
return this;
}
+
/*
# Define equality.
def ==(array)
@@ -191,8 +219,7 @@ FileList.prototype.clearExclude = function()
// Return the internal array object.
FileList.prototype.toArray = function()
{
- this.resolve();
- return this._items.slice();
+ return this.items().slice();
}
/*
# Lie about our class.
@@ -223,8 +250,9 @@ FileList.prototype.resolve = function()
{
this._resolveAdd(aFilename);
}, this);
+
this._pendingAdd = [];
- this.resolveExclude();
+ this._resolveExclude();
}
return this;
@@ -235,18 +263,32 @@ FileList.prototype._resolveAdd = function(aFilename)
if (aFilename.match(/[\*?\[\{]/))
this._addMatching(aFilename);
else
- _items.push(aFilename);
+ this._items.push(aFilename);
}
FileList.prototype._resolveExclude = function()
{
this._items = this._items.filter(function(/*String*/ aFilename)
{
- return this.shouldExclude(aFilename);
+ return !this._shouldExclude(aFilename);
}, this);
return this;
}
+
+FileList.prototype._shouldExclude = function(aFilename)
+{
+ var failedFilters = this._excludedPatterns.filter(function(aPattern){
+ return aPattern.test(aFilename);
+ }, this);
+
+ var failedProcs = this._excludedProcs.filter(function(aFunction){
+ return aFunction.apply(this, [aFilename]);
+ }, this);
+
+ return (failedFilters.length !== 0 || failedProcs.length !== 0);
+}
+
/*
# Return a new FileList with the results of running +sub+ against each
# element of the oringal list.
@@ -327,21 +369,20 @@ end
// file list that exist on the file system.
FileList.prototype.existing = function(/*String*/ aFilename)
{
- return new FileList().import(this.items().filter(function(aFilename
+ return (new FileList())._import(this.items().filter(function(aFilename)
{
return FILE.exists(aFilename);
- }, this)));
+ }, this));
}
// Modify the current file list so that it contains only file name that
// exist on the file system.
FileList.prototype.keepExisting = function()
{
- this.resolve();
- this._items = this._items.filter(function(aFilename
+ this._items = this.filter(function(aFilename)
{
return FILE.exists(aFilename);
- }, this));
+ }, this);
return this;
}
@@ -360,17 +401,21 @@ FileList.prototype.keepExisting = function()
// Convert a FileList to a string by joining all elements with a space.
FileList.prototype.toString = function()
{
- this.resolve();
- return this.join(' ');
+ return this.items().join(' ');
}
// Add matching glob patterns.
FileList.prototype._addMatching = function(/*String*/ aPattern)
-{
+{
+ FILE.glob(aPattern).forEach(function(fileName){
+ this._items.push(fileName);
+ }, this);
+
/* Dir[pattern].each do |fn|
self << fn unless exclude?(fn)
end*/
-}
+}
+/*
# Should the given file name be excluded?
def exclude?(fn)
return true if @exclude_patterns.any? do |pat|
@@ -385,24 +430,17 @@ FileList.prototype._addMatching = function(/*String*/ aPattern)
end
@exclude_procs.any? { |p| p.call(fn) }
end
-
- DEFAULT_IGNORE_PATTERNS = [
- /(^|[\/\\])CVS([\/\\]|$)/,
- /(^|[\/\\])\.svn([\/\\]|$)/,
- /\.bak$/,
- /~$/
- ]
- DEFAULT_IGNORE_PROCS = [
- proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) }
- ]
+*/
-FileList.prototype.import = function(/*Array*/ anArray)
+FileList.prototype._import = function(/*Array*/ anArray)
{
- this._items = anArray;
-
+ this._items = anArray.slice();
return this;
-}
-/*
+}
+
+exports.FileList = FileList;
+
+/*
module Rake
class << self
@@ -416,4 +454,5 @@ module Rake
end
end
end
-end # module Rake*/
+end # module Rake
+*/

0 comments on commit 7aa6e34

Please sign in to comment.