-
-
Save cdaringe/f556943b685aff43c292 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
TODO: | |
Address methods that reference other methods as '$this->doSomething()' | |
+ $this->select() Could be addressed by each class extending BaseAppData | |
+ Grep for methods defined in File 'A' that are referenced in File 'B' using $this-> | |
+ Alternatively, change all calls to '$this' to be $AppData. | |
*/ | |
var fs = require('fs'); | |
var Promise = require('es6-promise').Promise; | |
var _ = require('underscore'); | |
var now = (new Date()).getTime(), | |
buildPath = './build-' + now, | |
buildPathClasses = buildPath + '/AppDataClasses'; | |
// src data | |
var splitFilesDirPath = '../micis/AppDataClasses/'; | |
var appDataPath = '../micis/AppData.inc_orig'; | |
// function parsing regex | |
var funcRx = /function *[^\s(]* *\([^)]*\)\s*\{/g; | |
var funcNameRx = /function *([^\s(]*) *\([^)]*\)\s*\{/; | |
// Promise array indicating all files read | |
var subClassFilesParsed = []; | |
//format {'filename':[func1, func2]...} | |
var subFunctionNames = {}, | |
appFunctionNames = []; | |
// parse all sub-class files | |
fs.readdir(splitFilesDirPath, function readFiles(err, files) { | |
if (err) throw err; | |
subClassFilesParsed = files.map(function readFile(filename) { | |
return new Promise(function readFileP(resolve, reject){ | |
var fileFullPath = splitFilesDirPath + filename; | |
subFunctionNames[filename] = []; | |
fs.readFile(fileFullPath, 'utf-8', function parseFunctionNames(err, contents) { | |
if (contents === undefined || err) { | |
reject(); | |
return; | |
} | |
// match function blocks, then function names | |
subFunctionNames[filename] = contents.match(funcRx).map(function extractFunctionName(str) { | |
var groups = str.match(funcNameRx); | |
return groups[1]; | |
}); | |
subFunctionNames[filename] = _.uniq(subFunctionNames[filename]).sort(); | |
resolve(); | |
}); | |
}); | |
}); | |
}); | |
Promise.all(subClassFilesParsed).then(readAppData); | |
function readAppData(){ | |
var appDataReadP = new Promise(function readAppDataP(resolve, reject){ | |
fs.readFile(appDataPath, 'utf-8', function readAppData(err, contents){ | |
if (contents === undefined || err) { | |
console.log('AppData not found!'); | |
reject(); | |
return; | |
} | |
appFunctionNames = contents.match(funcRx).map(function extractFunctionName(str) { | |
var groups = str.match(funcNameRx); | |
//console.log('>>>' + groups[1]); | |
return groups[1]; | |
}); | |
appFunctionNames = _.uniq(appFunctionNames).sort(); // eliminate duplicates (funcs in comment blocks) | |
resolve(); | |
}); | |
}); | |
appDataReadP | |
.then(validateFileNames) | |
.then(buildAppData); | |
} | |
function validateFileNames(){ | |
try{ | |
var currentFuncCount = 0, | |
totalSubFunctions = 0, | |
totalAppFunctions = appFunctionNames.length, | |
missingFunctions = [], | |
duplicateFunctions = []; | |
// function report per file | |
console.log('Num class files: ' + Object.keys(subFunctionNames).length); | |
Object.keys(subFunctionNames).forEach(function printClassFunctionInfo(key){ | |
currentFuncCount = subFunctionNames[key].length; | |
totalSubFunctions += currentFuncCount; | |
console.log('..' + key + ':\t\t\t' + currentFuncCount); | |
}); | |
// totals | |
console.log('Total subClass function count: ' + totalSubFunctions); | |
console.log('Total AppData function count: ' + totalAppFunctions); | |
if (totalSubFunctions !== totalAppFunctions) { | |
console.log('Error: File count mismatch between AppData and SubClasses'); | |
} | |
// ensure all functions in AppData present in sub-classes, no duplicates | |
appFunctionNames.forEach(function validateAllFunctionsPresent(funcName) { | |
var foundCount = 0; | |
Object.keys(subFunctionNames).forEach(function testForPresence(key){ | |
if (subFunctionNames[key].indexOf(funcName) >= 0) ++foundCount; | |
}); | |
if (foundCount === 0) missingFunctions.push(funcName); | |
else if (foundCount > 1) duplicateFunctions.push(funcName); | |
else if (foundCount !== 1) { | |
console.log('Error: ' + funcName + ' // ' + foundCount); | |
throw new Error('Bogus number of functions detected'); | |
} | |
}); | |
// error | |
if (missingFunctions.length || duplicateFunctions.length) { | |
console.log("Missing functions: "); | |
console.dir(missingFunctions); | |
console.log("Duplicate functions: "); | |
console.dir(duplicateFunctions); | |
throw new Error("Expected to find 1:1 mapping between AppData " + | |
"and SubClass functions"); | |
} | |
} | |
catch(e){ | |
console.dir(e); | |
} | |
} | |
function buildAppData(){ | |
fs.mkdirSync(buildPath); | |
fs.mkdirSync(buildPathClasses); | |
writeAppData() | |
.then(writeAppDataClasses) | |
.then(tidyUp); | |
} | |
function writeAppData(){ | |
return new Promise(function writeAppDataP(resolve, reject){ | |
var fileContents, | |
file; | |
try{ | |
// base | |
fileContents = '<?php\n' + | |
'require_once("BaseAppData.inc");\n' + | |
'define ("PHI_LINKED", 1);\n' + | |
'define ("PHI_UNLINKED", 2);\n' + | |
'define ("PHI_NOPRIVILEGE", 3);\n\n'; | |
// requires | |
Object.keys(subFunctionNames).sort().forEach(function appendSubClassRequire(file){ | |
fileContents += 'require_once("./AppDataClasses/' + file + '");\n'; | |
}) | |
// class | |
fileContents += '\nclass AppData extends BaseAppData {\n\n' + | |
'\t\tfunction __construct() {\n'; | |
// constructor | |
Object.keys(subFunctionNames).sort().forEach(function addMemberObjects(file){ | |
fileContents += '\t\t\t\t$this->' + file.substr(0, file.indexOf('.')) + ' = new ' + file.substr(0, file.indexOf('.')) + '($this);\n'; | |
}); | |
fileContents += '\t\t}\n\n'; | |
// member functions | |
for (file in subFunctionNames) { | |
fileContents += '\t\t// ' + file + '\n'; | |
subFunctionNames[file].forEach(function addMemberFunctions(funcName){ | |
fileContents += '\t\tpublic function ' + funcName + '(){ return $this->' + file.substr(0, file.indexOf('.')) + '->' + funcName + '(); }\n'; | |
}); | |
fileContents += '\n'; | |
} | |
fileContents += '}\n'; | |
fs.writeFile(buildPath + '/AppData.inc', | |
fileContents, | |
function(err) { | |
if (err) { | |
console.log(err); | |
reject(); | |
return; | |
} | |
} | |
); | |
resolve(); | |
} catch(e) { | |
console.dir(e); | |
throw e; | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment