Skip to content

Commit

Permalink
#190: refactor file tree parsing to match sourcejs as node_modules se…
Browse files Browse the repository at this point in the history
…t-up
  • Loading branch information
robhrt7 committed Nov 16, 2015
1 parent 17e361b commit cdfa861
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 96 deletions.
121 changes: 30 additions & 91 deletions core/file-tree/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ var extendTillSpec = require(path.join(global.pathToApp,'core/lib/extendTillSpec
var unflatten = require(path.join(global.pathToApp,'core/unflat'));
var specUtils = require(path.join(global.pathToApp,'core/lib/specUtils'));
var utils = require(path.join(global.pathToApp,'core/lib/utils'));
var globArray = require(path.join(global.pathToApp,'core/lib/globArray'));
var isNodeModule = require(path.join(global.pathToApp,'core/lib/isNodeModule'));
var coreOpts = global.opts.core;
var prettyHrtime = require('pretty-hrtime');

Expand All @@ -16,10 +18,9 @@ var userPath = global.userPath.replace(/\\/g, '/');

var config = {
includedDirs: coreOpts.common.includedDirs,
excludedDirs: [],

// TODO: merge with `excludedDirs` in next major release.
excludedDirsGlobal: [],
// Filled from options.js
excludes: [],
cron: false,
cronProd: true,
cronRepeatTime: 60000,
Expand All @@ -32,21 +33,18 @@ var config = {
// Overwriting base options
utils.extendOptions(config, coreOpts.fileTree);

var glob = config.excludes;
glob.unshift('**/info.json');

var prepareExcludesRegex = function(){
var dirsForRegExp = '';
var i = 1;
config.excludedDirs.forEach(function (exlDir) {
if (i < config.excludedDirs.length) {
dirsForRegExp = dirsForRegExp + '^' + config.specsRoot + '\/' + exlDir + '|';
if (Array.isArray(config.includedDirs)) {
config.includedDirs.forEach(function(item){
if (isNodeModule) {
glob.push('node_modules/sourcejs/' + item + '/**/info.json');
} else {
dirsForRegExp = dirsForRegExp + '^' + config.specsRoot + '\/' + exlDir;
glob.push('../' + item + '/**/info.json');
}
i++;
});
return new RegExp(dirsForRegExp);
};

}

/**
* Prepare relative path for web usage (like `/docs/spec`, `/specs/btn`) out of absolute path
Expand All @@ -62,7 +60,7 @@ var getRelativeSpecPath = module.exports.getRelativeSpecPath = function(absolute
// If starts with root (specs)

// Cleaning path to specs root folder
relativeSpecPath = absolutePath.replace(config.specsRoot, '');
relativeSpecPath = absolutePath.replace(config.specsRoot, '').replace('node_modules/sourcejs/', '');
} else {
// Cleaning path for included folders
relativeSpecPath = absolutePath.replace(normalizedPathToApp, '');
Expand All @@ -75,35 +73,6 @@ var getRelativeSpecPath = module.exports.getRelativeSpecPath = function(absolute
return relativeSpecPath;
};

var getSpecLocation = function(specDirOrPath){
// Normalize windows URL and remove trailing slash
var _specDirOrPath = specDirOrPath.replace(/\\/g, '/').replace(/\/$/, '');
var isSpecPath = path.extname(_specDirOrPath) !== '';
var specDir;
var specPath;
var relativeSpecPath = getRelativeSpecPath(_specDirOrPath);

if (isSpecPath) {
relativeSpecPath = path.dirname(relativeSpecPath);
}

// Try to get specPath
if (isSpecPath) {
specDir = path.dirname(_specDirOrPath);
specPath = _specDirOrPath;
} else {
specDir = _specDirOrPath;
specPath = specUtils.getSpecFromDir(_specDirOrPath);
}

return {
relativeSpecPath: relativeSpecPath,
isSpecPath: isSpecPath,
specDir: specDir,
specPath: specPath
};
};

/**
* Get spec thumbnail image path
*
Expand Down Expand Up @@ -157,20 +126,18 @@ var getSpecInfoFile = module.exports.getSpecInfoFile = function(specDir){
/**
* Prepares Spec meta object from specs directory or Spec file path
*
* @param {String} specDirOrPath - path to Spec directory or Spec file
* @param {String} specDir - path to Spec directory
*
* @returns {Object} Return Spec file meta info (used in file-tree.json and in other places)
*/
var getSpecMeta = module.exports.getSpecMeta = function(specDirOrPath){
var getSpecMeta = module.exports.getSpecMeta = function(specDir){
var page = {};

// Check if arg is provided and path exists
if ( !(specDirOrPath && fs.existsSync(specDirOrPath))) return page;
if ( !(specDir && fs.existsSync(specDir)) ) return page;

var specLocation = getSpecLocation(specDirOrPath);
var specPath = specLocation.specPath;
var specDir = specLocation.specDir;
var relativeSpecPath = specLocation.relativeSpecPath;
var relativeSpecPath = getRelativeSpecPath(specDir);
var specPath = specUtils.getSpecFromDir(specDir);

// Remove first slash for ID
page.id = relativeSpecPath === '/' ? '/' : relativeSpecPath.replace(/^\//, '');
Expand All @@ -196,58 +163,30 @@ var getSpecMeta = module.exports.getSpecMeta = function(specDirOrPath){
return page;
};

var fileTree = function (workingDir) {
var processingDir = workingDir;
var fileTree = function(workingDir) {
var outputJSON = {};

// Allow to run app without existing specsRoot
if (!fs.existsSync(workingDir) && workingDir === config.specsRoot) {
global.log.warn('Running SourceJS without user dir. This set-up should be used only for running tests.');
processingDir = global.pathToApp;
workingDir = global.pathToApp;
}

var dirContent = fs.readdirSync(processingDir);
var excludes = prepareExcludesRegex();

// Adding paths to files in array
for (var i = 0; dirContent.length > i; i++) {
dirContent[i] = path.join(processingDir, dirContent[i].replace(/\\/g, '/'));
}

// On first call we add includedDirs
if (processingDir === config.specsRoot) {
config.includedDirs.map(function (includedDir) {
dirContent.push(path.join(normalizedPathToApp, includedDir));
});
}

dirContent.forEach(function(pathToFile) {
// Path is excluded
if (excludes.test(processingDir) || !fs.existsSync(pathToFile)) return;

var infoFileName = coreOpts.common.infoFile;
var targetFile = path.basename(pathToFile);

// Normalizing path for windows
pathToFile = path.normalize(pathToFile).replace(/\\/g, '/');

var fileStats = fs.statSync(pathToFile);
var files = globArray(glob, {
cwd: workingDir
});

if (fileStats.isDirectory()) {
if (config.excludedDirsGlobal.indexOf(targetFile) > -1) return;
files.forEach(function(file){
var realFilePath = path.join(workingDir, file);
var specPath = path.dirname(realFilePath);
var specId = path.dirname(file).replace('node_modules/sourcejs/', '').replace('../', '');

// Going deeper
var childObj = fileTree(pathToFile);
if (Object.getOwnPropertyNames(childObj).length !== 0) {
outputJSON[targetFile] = childObj;
}
specId = specId === '.' ? '' : specId + '/';

} else if (targetFile.toLowerCase() === infoFileName.toLowerCase()) {
outputJSON['specFile'] = getSpecMeta(processingDir);
}
outputJSON[specId + 'specFile'] = getSpecMeta(specPath);
});

return outputJSON;
return unflatten(outputJSON, { delimiter: '/', overwrite: 'root' });
};

// function for write file tree json
Expand Down
34 changes: 34 additions & 0 deletions core/lib/globArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

var glob = require('glob');
var minimatch = require("minimatch");

module.exports = function (patterns, options) {
var i, list = [];
if (!Array.isArray(patterns)) {
patterns = [patterns];
}

patterns.forEach(function (pattern) {
if (pattern[0] === "!") {
i = list.length - 1;
while (i > -1) {
if (!minimatch(list[i], pattern)) {
list.splice(i, 1);
}
i--;
}

}
else {
var newList = glob.sync(pattern, options);
newList.forEach(function (item) {
if (list.indexOf(item) === -1) {
list.push(item);
}
});
}
});

return list;
};
12 changes: 7 additions & 5 deletions options.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ module.exports = {

// Spec catalogs navigation tree
fileTree: {
// Exclude files from file-tree indexing (first level, in user folder)
excludedDirs: ['node_modules', 'bower_components', 'data', 'plugins', '.git', '.idea'],

// Exclude files from file-tree indexing (on any level, by folder name)
excludedDirsGlobal: ['node_modules', '.git', '.idea'],
// Glob excludes for `info.json` search paths
excludes: [
'!**/node_modules/**',
'!**/bower_components/**',
'!**/.git/**',
'!**/.idea/**'
],

// Update navigation tree by cron task (setTimeout)
cron: false,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"log4js": "~0.6.20",
"macaddress": "^0.2.8",
"marked": "^0.3.2",
"minimatch": "^3.0.0",
"pretty-hrtime": "^1.0.0",
"q": "^1.1.1",
"serve-favicon": "^2.2.0",
Expand Down

0 comments on commit cdfa861

Please sign in to comment.