Skip to content
Browse files

change getProjectData algorithm to

* use a breadth-first search
* no longer be recursive or use status globals
* use auxiliary data from package.json when in the same folder a yuidoc.json
  • Loading branch information...
1 parent 3695df5 commit f207741fc273f852c348b631dbdca8ca96a08381 @sjmiles sjmiles committed Mar 4, 2013
Showing with 71 additions and 46 deletions.
  1. +71 −46 lib/utils.js
View
117 lib/utils.js
@@ -220,71 +220,96 @@ function prepare(inDirs, options, callback) {
Y.prepare = prepare;
-
-var projectData, packageData, dirCount = 0;
/**
* Walk the directory tree to locate the yuidoc.json file.
* @method getProjectData
* @param {Path} [dir=process.cwd()] The directory to start from
*/
var getProjectData = function(dir) {
- if (dirCount > 5000) {
- Y.log('Scanned ' + dirCount + ' directories looking for a yuidoc.json file, something is probably wrong here..', 'error', 'yuidoc');
- process.exit(1);
- }
- if (!dir) {
- dir = process.cwd();
- }
- try {
- var dirs = fs.readdirSync(dir);
- dirs.forEach(function(d) {
- var p = path.join(dir, d);
- if (d.indexOf('.') === 0) {
- return;
- }
- if (d === 'node_modules') {
- Y.log('Skipping node_modules directory while scanning for yuidoc.json', 'warn', 'yuidoc');
- return;
- }
+ var dirs = [dir || process.cwd()];
+ var projectData, packageData;
+ var dirCount = 0;
+ // keep looping until
+ // * data is found
+ // * there are no more dirs to process
+ // * we abort due to failsafe
+ while (dirs.length && !projectData) {
+ if (dirCount++ > 5000) {
+ Y.log('Scanned ' + dirCount + ' directories looking for a yuidoc.json file, something is probably wrong here..', 'error', 'yuidoc');
+ process.exit(1);
+ }
+ // accumulator for directories at this level
+ var childDirs = [];
+ // for each directory at the previous level
+ dirs.forEach(function(dir) {
+ // abort iterating if we have project data
if (projectData) {
return;
}
- if (Y.Files.isFile(p)) {
- if (d === 'yuidoc.json') {
- Y.log('Loading project data from: ' + p, 'info', 'yuidoc');
- try {
- projectData = Y.Files.getJSON(p);
- } catch (e) {
- var err = 'Failed to parse yuidoc.json file, please make sure it is valid JSON';
- Y.log(err, 'error', 'yuidoc');
- throw(e+'');
+ // squelch (but log) any complaints about this particular directory
+ try {
+ // for each item in this directory
+ var names = fs.readdirSync(dir);
+ names.forEach(function(name) {
+ // abort iterating a folder if we have found both data
+ if (projectData && packageData) {
+ return;
}
- }
- if (d === 'package.json') {
- Y.log('Loading project data from: ' + p, 'info', 'yuidoc');
- try {
- packageData = Y.Files.getJSON(p);
- } catch (e) {
- var err = 'Failed to parse package.json file, please make sure it is valid JSON';
- Y.log(err, 'error', 'yuidoc');
- throw(e+'');
+ // build a full path
+ var p = path.join(dir, name);
+ // acquire project data from this item if possible
+ if (Y.Files.isFile(p)) {
+ projectData = getFileData(p, name, 'yuidoc.json');
+ // 'package.json' is used for auxilliary configuration
+ // if it's found. Formerly, it was only found if it
+ // came _before_'yuidoc.json' in the folder tree
+ // (never in the same folder).
+ // This code will find 'package.json' in the same
+ // folder as 'yuidoc.json'.
+ // If there is no 'yuidoc.json', former algorithm would
+ // use the deepest 'package.json' it can find, this one
+ // will use the first (most shallow) one.
+ packageData = packageData || getFileData(p, name, 'package.json');
}
- }
- }
- if (!projectData && Y.Files.isDirectory(p)) {
- dirCount++
- projectData = getProjectData(p);
+ // if we are a folder, but not ., .., or node_modules,
+ // then add to directory accumulator
+ if (Y.Files.isDirectory(p)) {
+ if (name.indexOf('.') === 0) {
+ return;
+ }
+ if (name === 'node_modules') {
+ Y.log('Skipping node_modules directory while scanning for yuidoc.json', 'warn', 'yuidoc');
+ return;
+ }
+ childDirs.push(p);
+ }
+ });
+ } catch (dirPerm) {
+ Y.log('Accessing dir (' + dir + ') threw an error', 'warn', 'yuidoc');
}
});
- } catch (dirPerm) {
- Y.log('Accessing dir (' + dir + ') threw an error', 'warn', 'yuidoc');
+ // iterate over new set of folders
+ dirs = childDirs;
}
- if (packageData && projectData || (packageData && packageData.yuidoc)) {
+ if ((packageData && projectData) || (packageData && packageData.yuidoc)) {
projectData = mergeData(packageData, projectData);
}
return projectData;
};
+var getFileData = function(p, name, file) {
+ if (name === file) {
+ Y.log('Loading ' + name + ' data from: ' + p, 'info', 'yuidoc');
+ try {
+ return Y.Files.getJSON(p);
+ } catch (e) {
+ var err = 'Failed to parse ' + name + ' file, please make sure it is valid JSON';
+ Y.log(err, 'error', 'yuidoc');
+ throw(e+'');
+ }
+ }
+};
+
var mergeData = function(pack, project) {
project = project || {};

0 comments on commit f207741

Please sign in to comment.
Something went wrong with that request. Please try again.