mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
* move tslint ADF rules in principal repo * fix style issues * change pacakge.json position * update to angular cli 6.0.0 * reorganization package.json * remove node modules2 folder * exclude integration * rollback alfresco-js-api * solve types problems * fix pdf test * fix errors and exclude two tests * fix e2e * fix test * copy all the new packages in node_modules * fix test * fix packaging script * scss issue fix * move test export in tools
374 lines
12 KiB
TypeScript
374 lines
12 KiB
TypeScript
import * as ts from "typescript";
|
|
import * as fs from "fs";
|
|
import chalk from "chalk";
|
|
|
|
var nconf = require('nconf');
|
|
var basePath = "./tools/export-check/";
|
|
|
|
nconf.add('config', { type: 'file', file: `${basePath}export-check-config.json` });
|
|
|
|
var newLibExports = basePath + nconf.get('export-last-version');
|
|
var exportFilesVersions = nconf.get('export-versions').map((currentFile) => {
|
|
return basePath + currentFile;
|
|
});
|
|
|
|
interface DocEntry {
|
|
position?: {
|
|
line: number,
|
|
character: number,
|
|
fileName: string
|
|
},
|
|
name?: string,
|
|
skipError?: boolean
|
|
};
|
|
|
|
let error_array = [];
|
|
let warning_array = [];
|
|
let exportedAllPath: Array<string> = [];
|
|
let classList: Array<any> = [];
|
|
|
|
let add_error = function (error: string, nameClass: string) {
|
|
let findErrorClass = false;
|
|
|
|
error_array.forEach((currentError) => {
|
|
|
|
if (currentError.nameClass === nameClass) {
|
|
findErrorClass = true;
|
|
return;
|
|
}
|
|
});
|
|
|
|
if (!findErrorClass) {
|
|
error_array.push({
|
|
error: error,
|
|
nameClass: nameClass
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
let count_error = 0;
|
|
let count_warning = 0;
|
|
|
|
let print_errors = function () {
|
|
error_array.forEach((current_error) => {
|
|
console.log(chalk.red(`[${++count_error}] ${current_error.error}\n`));
|
|
});
|
|
}
|
|
|
|
|
|
let add_warning = function (warning: string, nameClass: string, arrayCall: string[]) {
|
|
|
|
let findWarningClass = false;
|
|
|
|
warning_array.forEach((currentWarning) => {
|
|
|
|
if (currentWarning.nameClass === nameClass) {
|
|
findWarningClass = true;
|
|
return;
|
|
}
|
|
});
|
|
|
|
if (!findWarningClass) {
|
|
warning_array.push({
|
|
warning: warning,
|
|
nameClass: nameClass,
|
|
arrayCall: arrayCall
|
|
});
|
|
}
|
|
}
|
|
|
|
let print_warnings = function () {
|
|
warning_array.forEach((current_warning) => {
|
|
console.log(chalk.yellow(`[${++count_warning}] ${current_warning.warning} \n ${current_warning.arrayCall} \n`));
|
|
});
|
|
}
|
|
|
|
let currentErrorPostion = function (exportEntry) {
|
|
return ` ${exportEntry.position.fileName} (${exportEntry.position.line},${exportEntry.position.character})`
|
|
}
|
|
|
|
let check_export = function (exportLastMajor: any, exportNew: any) {
|
|
|
|
exportLastMajor.forEach((currentexportLastMajor) => {
|
|
|
|
let currentexportNew = exportNew.filter((currentexportNew) => {
|
|
return currentexportNew.name === currentexportLastMajor.name;
|
|
});
|
|
|
|
if (currentexportNew.length > 1) {
|
|
|
|
let arrayCall = [];
|
|
|
|
currentexportNew.forEach((error) => {
|
|
arrayCall.push(`${currentErrorPostion(error)}`);
|
|
})
|
|
|
|
add_warning(`Multiple export ${currentexportNew[0].name} times ${currentexportNew.length}`, currentexportNew[0].name, arrayCall);
|
|
|
|
} else if (currentexportNew.length === 0) {
|
|
if (!currentexportLastMajor.skipError) {
|
|
add_error(`Not find export ${currentexportLastMajor.name} , old path: [${currentErrorPostion(currentexportLastMajor)}]`, currentexportLastMajor.name);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
let expandStarExport = function (node: ts.Node): ts.ExportDeclaration {
|
|
const ed = node as ts.Node as ts.ExportDeclaration;
|
|
const exports = [{ name: "x" }];
|
|
const exportSpecifiers = exports.map(e => ts.createExportSpecifier(e.name, e.name));
|
|
const exportClause = ts.createNamedExports(exportSpecifiers);
|
|
const newEd = ts.updateExportDeclaration(ed, ed.decorators, ed.modifiers, exportClause, ed.moduleSpecifier);
|
|
|
|
return newEd as ts.ExportDeclaration
|
|
};
|
|
|
|
/** Generate documentation for all classes in a set of .ts files */
|
|
function generatExportList(fileNames: string[], options: ts.CompilerOptions): void {
|
|
// Build a program using the set of root file names in fileNames
|
|
let program = ts.createProgram(fileNames, options);
|
|
// Get the checker, we will use it to find more about classes
|
|
let checker = program.getTypeChecker();
|
|
|
|
let exportCurrentVersion: DocEntry[] = [];
|
|
|
|
// Visit every sourceFile in the program
|
|
for (const sourceFile of program.getSourceFiles()) {
|
|
if (!sourceFile.isDeclarationFile) {
|
|
// Walk the tree to search for classes
|
|
ts.forEachChild(sourceFile, visit);
|
|
}
|
|
}
|
|
|
|
classList.forEach((classNode) => {
|
|
if (classNode.symbol.parent) {
|
|
let pathClass = classNode.symbol.parent.escapedName.replace(/"/g, "");
|
|
|
|
exportedAllPath.forEach((currenPath) => {
|
|
let pathNoExtension = currenPath.replace(/\.[^/.]+$/, "");
|
|
|
|
if (pathNoExtension === pathClass) {
|
|
// console.log('pathClass'+ pathClass);
|
|
// console.log('pathNoExtension '+ pathNoExtension);
|
|
extractExport(classNode);
|
|
return;
|
|
}
|
|
|
|
});
|
|
}
|
|
});
|
|
|
|
exportCurrentVersion.sort((nameA, nameB) => nameA.name.localeCompare(nameB.name));
|
|
|
|
console.log(chalk.green(`Saving new export in ${newLibExports}`));
|
|
|
|
fs.writeFileSync(newLibExports, JSON.stringify(exportCurrentVersion, undefined, 4));
|
|
|
|
var exportNewJSON = JSON.parse(JSON.stringify(exportCurrentVersion));
|
|
|
|
exportFilesVersions.forEach((currentExportVersionFile) => {
|
|
|
|
error_array = [];
|
|
warning_array = [];
|
|
|
|
try {
|
|
var currentExportVersionJSON = JSON.parse(fs.readFileSync(`${currentExportVersionFile}`, 'utf8'));
|
|
} catch (error) {
|
|
console.log(chalk.red(`${currentExportVersionFile} json not present`));
|
|
throw new Error(`Undetected export comapring file ${currentExportVersionFile}`);
|
|
}
|
|
|
|
|
|
console.log(chalk.green(`Comparing ${newLibExports} and ${currentExportVersionFile}`));
|
|
|
|
check_export(currentExportVersionJSON, exportNewJSON);
|
|
|
|
print_warnings();
|
|
print_errors();
|
|
|
|
|
|
if (error_array.length > 0) {
|
|
throw new Error('Export problems detected');
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
})
|
|
|
|
function extractExport(node: ts.Node) {
|
|
//skip file with export-check: exclude comment
|
|
if (node.getFullText(node.getSourceFile()).indexOf('export-check: exclude') > 0) {
|
|
return;
|
|
}
|
|
|
|
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
|
|
//console.log(line + " " + character + " " + node.getSourceFile().fileName);
|
|
|
|
let symbol = checker.getSymbolAtLocation(node);
|
|
|
|
if (symbol) {
|
|
let arryCalls = recursiveStackSave(node);
|
|
|
|
let className: any = symbol.escapedName;
|
|
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
|
|
exportCurrentVersion.push(serializeClass(className, line, character, filename, arryCalls));
|
|
|
|
// if (className === "ContentMetadataService") {
|
|
// console.log(chalk.red("exportedAllPath" + exportedAllPath));
|
|
// console.log(chalk.red("ContentMetadataService"));
|
|
// recursiveStack(node);
|
|
// }
|
|
|
|
} else {
|
|
|
|
let arryCalls = recursiveStackSave(node);
|
|
|
|
let className: any = (node as ts.ClassDeclaration).name.escapedText;
|
|
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
|
|
exportCurrentVersion.push(serializeClass(className, line, character, filename, arryCalls));
|
|
|
|
// if (className === "ContentMetadataService") {
|
|
// console.log(chalk.greenBright("exportedAllPath" + exportedAllPath));
|
|
// console.log(chalk.greenBright("ContentMetadataService"));
|
|
// recursiveStack(node);
|
|
// }
|
|
|
|
}
|
|
}
|
|
|
|
function recursiveStackSave(node: ts.Node, arrayCalls?: string[]) {
|
|
if (!arrayCalls) {
|
|
arrayCalls = [];
|
|
}
|
|
|
|
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
|
|
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
|
|
|
|
arrayCalls.push(node.getSourceFile().fileName);
|
|
|
|
if (node.parent) {
|
|
recursiveStackSave(node.parent, arrayCalls)
|
|
}
|
|
|
|
return arrayCalls;
|
|
|
|
}
|
|
|
|
function recursiveStack(node: ts.Node) {
|
|
let filename = node.getSourceFile().fileName.substring(node.getSourceFile().fileName.indexOf('lib'), node.getSourceFile().fileName.length);
|
|
let { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
|
|
console.log(chalk.bgCyan(line + " " + character + " " + node.getSourceFile().fileName));
|
|
|
|
if (node.parent) {
|
|
recursiveStack(node.parent)
|
|
}
|
|
|
|
}
|
|
|
|
/** visit nodes finding exported classes */
|
|
function visit(node: ts.Node) {
|
|
// Only consider exported nodes
|
|
|
|
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
|
|
|
|
if (node.decorators) {
|
|
node.decorators.forEach((decorator) => {
|
|
visit(decorator as ts.Node);
|
|
});
|
|
}
|
|
|
|
classList.push(node);
|
|
}
|
|
|
|
if (node.kind === ts.SyntaxKind.PropertyAssignment) {
|
|
const initializer = (node as ts.PropertyAssignment).initializer;
|
|
|
|
visit(initializer as ts.Node);
|
|
}
|
|
|
|
if (node.kind === ts.SyntaxKind.Identifier) {
|
|
extractExport(node);
|
|
}
|
|
|
|
if (node.kind === ts.SyntaxKind.ArrayLiteralExpression) {
|
|
(node as ts.ArrayLiteralExpression).elements.forEach((element) => {
|
|
visit(element as ts.Node);
|
|
});
|
|
}
|
|
|
|
if (node.kind === ts.SyntaxKind.Decorator &&
|
|
((node as ts.Decorator).expression as any).expression.text === "NgModule") {
|
|
|
|
((node as ts.Decorator).expression as any).arguments.forEach((argument) => {
|
|
argument.properties.forEach((property) => {
|
|
if (property.name.escapedText === "exports") {
|
|
visit(property as ts.Node);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
if (ts.isExportDeclaration(node)) {
|
|
if (node.exportClause) {
|
|
node.exportClause.elements.forEach(exportCurrent => {
|
|
extractExport(exportCurrent as ts.Node);
|
|
});
|
|
} else {
|
|
(node.parent as any).resolvedModules.forEach((currentModule) => {
|
|
|
|
if (currentModule) {
|
|
let find;
|
|
exportedAllPath.forEach((currentExported) => {
|
|
if (currentModule.resolvedFileName === currentExported) {
|
|
find = currentExported;
|
|
}
|
|
})
|
|
|
|
if (!find) {
|
|
exportedAllPath.push(currentModule.resolvedFileName);
|
|
}
|
|
}
|
|
})
|
|
|
|
visit(node.moduleSpecifier);
|
|
}
|
|
|
|
}
|
|
|
|
if (ts.isModuleDeclaration(node)) {
|
|
// This is a namespace, visit its children
|
|
ts.forEachChild(node, visit);
|
|
}
|
|
}
|
|
|
|
/** Serialize a symbol into a json object */
|
|
function serializeSymbol(className: string, line?: number, character?: number, fileName?: string, arryCalls?: string[]): DocEntry {
|
|
|
|
return {
|
|
position: {
|
|
line: line,
|
|
character: character,
|
|
fileName: fileName
|
|
},
|
|
name: className
|
|
};
|
|
}
|
|
|
|
/** Serialize a class symbol information */
|
|
function serializeClass(className: string, line?: number, character?: number, fileName?: string, arryCalls?: string[]) {
|
|
let details = serializeSymbol(className, line, character, fileName, arryCalls);
|
|
|
|
return details;
|
|
}
|
|
|
|
/** True if this is visible outside this file, false otherwise */
|
|
function isNodeExported(node: ts.Node): boolean {
|
|
return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 || (!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile);
|
|
}
|
|
}
|
|
|
|
generatExportList(process.argv.slice(2), {
|
|
target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS, removeComments: false
|
|
});
|