Permalink
Browse files

Refactor

  • Loading branch information...
1 parent 46673eb commit 0e43e6a5c9b7de61b0981843a2053f0b58269947 mde committed Aug 2, 2012
Showing with 197 additions and 47 deletions.
  1. +92 −0 lib/file.js
  2. +4 −1 lib/index.js
  3. +101 −46 lib/string.js
View
@@ -18,6 +18,7 @@
var fs = require('fs')
, path = require('path')
+ , JS_PAT = /\.js$/
, logger;
var logger = new (function () {
@@ -152,6 +153,28 @@ var fileUtils = new (function () {
}
});
fs.rmdirSync(dir);
+ }
+
+ // Recursively watch files with a callback
+ , _watch = function (path, callback) {
+ fs.stat(path, function (err, stats) {
+ if (err) {
+ return false;
+ }
+ if (stats.isFile() && JS_PAT.test(path)) {
+ fs.watchFile(path, callback);
+ }
+ else if (stats.isDirectory()) {
+ fs.readdir(path, function (err, files) {
+ if (err) {
+ return log.fatal(err);
+ }
+ for (var f in files) {
+ _watch(path + '/' + files[f], callback);
+ }
+ });
+ }
+ });
};
this.cpR = function (fromPath, toPath, options) {
@@ -298,6 +321,75 @@ var fileUtils = new (function () {
}
};
+ // Search for a directory in parent directories if it can't be found in cwd
+ this.searchParentPath = function(location, callback) {
+ var cwd = process.cwd();
+
+ if(!location) {
+ // Return if no path is given
+ return;
+ }
+ var relPath = ''
+ , i = 5 // Only search up to 5 directories
+ , pathLoc
+ , pathExists;
+
+ while(--i >= 0) {
+ pathLoc = path.join(cwd, relPath, location);
+ pathExists = this.existsSync(pathLoc);
+
+ if(pathExists) {
+ callback && callback(undefined, pathLoc);
+ break;
+ } else {
+ // Dir could not be found
+ if(i === 0) {
+ callback && callback(new Error("Path \"" + pathLoc + "\" not found"), undefined);
+ break;
+ }
+
+ // Add a relative parent directory
+ relPath += '../';
+ // Switch to relative parent directory
+ process.chdir(path.join(cwd, relPath));
+ }
+ }
+ };
+
+ this.watch = function () {
+ _watch.apply(this, arguments);
+ };
+
+ // Compatibility for fs.exists(0.8) and path.exists(0.6)
+ this.exists = (typeof fs.exists === 'function') ? fs.exists : path.exists;
+
+ // Compatibility for fs.existsSync(0.8) and path.existsSync(0.6)
+ this.existsSync = (typeof fs.existsSync === 'function') ? fs.existsSync : path.existsSync;
+
+ // Used to require external dependencies(Either globally or locally in users application)
+ this.dependency = function(module, message) {
+ var dep;
+
+ try {
+ // Try to require globally
+ dep = require(module);
+ } catch(err) {
+ // Try to require in the application directory
+ try {
+ // This is the main reason this method is created, if we try to do a regular require
+ // - to find a local package it assume it'll be in Geddy's node_modules instead of
+ // - the application
+ dep = require(path.join(process.cwd(), 'node_modules', module));
+ } catch(err) {
+ if(message) {
+ throw new Error(message);
+ }
+ throw new Error('Module "' + module + '" could not be found please install it by doing "npm install ' + module + '"');
+ }
+ }
+ return dep;
+ };
+
})();
module.exports = fileUtils;
View
@@ -15,7 +15,7 @@
* limitations under the License.
*
*/
-var var utils = {}
+var utils = {}
// Core methods
, core = require('./core')
// Namespaces with methods
@@ -27,6 +27,8 @@ var var utils = {}
, object = require('./object')
, date = require('./date')
, request = require('./request')
+// Third-party -- remove this if possible
+ , inflection = require('../deps/inflection')
// Constructors
, EventBuffer = require('./event_buffer').EventBuffer
, XML = require('./xml').XML
@@ -42,6 +44,7 @@ utils.array = array;
utils.object = object;
utils.date = date;
utils.request = request;
+utils.inflection = inflection;
utils.SortedCollection = SortedCollection;
utils.EventBuffer = EventBuffer;
utils.XML = XML;
View
@@ -16,6 +16,7 @@
*
*/
var core = require('./core')
+ , inflection = require('../deps/inflection')
, string;
string = new (function () {
@@ -282,50 +283,64 @@ string = new (function () {
};
// Converts someVariableName to some_variable_name
- this.snakeize = function (s) {
- return s.replace(/([A-Z]+)/g, '_$1').toLowerCase()
- .replace(/^_/, '');
- };
+ this.snakeize = (function () {
+ // Only create regexes once on initial load
+ var repl = /([A-Z]+)/g
+ , lead = /^_/g;
+ return function (str, separ) {
+ if (!str) {
+ return;
+ }
+ var sep = separ || '_'
+ , leading = separ ? new RegExp('^' + sep, 'g') : lead;
+ return str.replace(repl, sep + '$1').toLowerCase().
+ replace(leading, '');
+ };
+ }).call(this);
- // Backward-compat
+ // Aliases
this.decamelize = this.snakeize;
+ this.underscoreize = this.snakeize;
// Converts some_variable_name to someVariableName or SomeVariableName
- this.camelize = function (str, options) {
- var ret
- , config = {
- initialCap: false
- , leadingUnderscore: false
- }
- , opts = options || {};
-
- if (!str) {
- return;
- }
+ this.camelize = (function () {
+ // Only create regex once on initial load
+ var repl = /[-_](\w)/g;
+ return function (str, options) {
+ var ret
+ , config = {
+ initialCap: false
+ , leadingUnderscore: false
+ }
+ , opts = options || {};
- // Backward-compat
- if (typeof opts == 'boolean') {
- config = {
- initialCap: true
- };
- }
- else {
- core.mixin(config, opts);
- }
+ if (!str) {
+ return;
+ }
- ret = str.replace(/_[a-z]{1}/g, function (s) {
- return s.replace('_', '').toUpperCase();
- });
+ // Backward-compat
+ if (typeof opts == 'boolean') {
+ config = {
+ initialCap: true
+ };
+ }
+ else {
+ core.mixin(config, opts);
+ }
- if (config.leadingUnderscore & str.indexOf('_') === 0) {
- ret = '_' + this.decapitalize(ret);
- }
+ ret = str.replace(repl, function (m, m1) {
+ return m1.toUpperCase();
+ });
- // If initialCap is true capitalize it
- ret = config.initialCap ? this.capitalize(ret) : this.decapitalize(ret);
+ if (config.leadingUnderscore & str.indexOf('_') === 0) {
+ ret = '_' + this.decapitalize(ret);
+ }
+ // If initialCap is true capitalize it
+ ret = config.initialCap ? this.capitalize(ret) : this.decapitalize(ret);
- return ret;
- };
+ return ret;
+ };
+ }).call(this);
this.capitalize = function (s) {
return s.substr(0, 1).toUpperCase() + s.substr(1);
@@ -336,19 +351,59 @@ string = new (function () {
};
this.dasherize = function(s, replace) {
- if (!replace) replace = '-';
-
- // Todo: Make this simpler, but it needs to change work for the following types:
- // `example_text` => `example-text`
- // `example_Text` => `example-text`
- // `exampleText` => `example-text`
- return s.replace(/.(_([a-z]|[A-Z])|[A-Z]){1}/g, function(s) {
- return s.replace(/(_([a-z]|[A-Z])|[A-Z])/, s.replace(/[a-z]_?/, replace).toLowerCase());
- });
+ return this.snakeize(s, '-');
};
- this.underscorize = function(s) {
- return this.dasherize(s, '_');
+ /*
+ * getInflections(name<String>, initialCap<String>)
+ *
+ * Returns an object that contains different inflections
+ * created from the given `name`
+ */
+ this.getInflections = function (name, options) {
+ var opts = options || {}
+ , initialCap;
+
+ if (!name) {
+ return;
+ }
+
+ // Backward-compat
+ if (typeof opts == 'boolean') {
+ opts = {
+ initialCap: true
+ };
+ }
+
+ initialCap = opts.initialCap;
+
+ var self = this
+ , normalizedName = this.snakeize(name)
+ , nameSingular = inflection.singularize(normalizedName)
+ , namePlural = inflection.pluralize(normalizedName);
+
+ return {
+ // For filepaths or URLs
+ filename: {
+ // neil_peart
+ singular: nameSingular
+ // neil_pearts
+ , plural: namePlural
+ }
+ // Constructor names
+ , constructor: {
+ // NeilPeart
+ singular: self.camelize(nameSingular, {initialCap: true})
+ // NeilPearts
+ , plural: self.camelize(namePlural, {initialCap: true})
+ }
+ , property: {
+ // neilPeart
+ singular: self.camelize(nameSingular)
+ // neilPearts
+ , plural: self.camelize(namePlural)
+ }
+ };
};
// From Math.uuid.js, http://www.broofa.com/Tools/Math.uuid.js

0 comments on commit 0e43e6a

Please sign in to comment.