From ab19086400da2881661254def1419a9b0a6bf44b Mon Sep 17 00:00:00 2001 From: Karl-Philipp Wulfert Date: Thu, 17 Jan 2019 11:23:05 +0100 Subject: [PATCH] refactor: remove pack --- src/common.ts | 32 -------- src/pack.cli.ts | 65 --------------- src/pack/pack-cli.ts | 88 --------------------- src/pack/pack-definitions.ts | 128 ------------------------------ src/pack/pack-modules.ts | 148 ----------------------------------- src/pack/types.ts | 38 --------- 6 files changed, 499 deletions(-) delete mode 100644 src/pack.cli.ts delete mode 100644 src/pack/pack-cli.ts delete mode 100644 src/pack/pack-definitions.ts delete mode 100644 src/pack/pack-modules.ts delete mode 100644 src/pack/types.ts diff --git a/src/common.ts b/src/common.ts index a6554862..553ba976 100644 --- a/src/common.ts +++ b/src/common.ts @@ -18,10 +18,8 @@ import {Logger} from '@openstapps/logger'; import {asyncPool} from 'async-pool-native/dist/async-pool'; import {readFile, unlink, writeFile} from 'fs'; import * as glob from 'glob'; -import {basename} from 'path'; import {promisify} from 'util'; import {PACK_IDENTIFIER} from './configuration'; -import {JavaScriptModule} from './pack/types'; /** * Instantiated logger @@ -129,33 +127,3 @@ export function getAllInternalDependecies(moduleContent: string): string[] { return []; } - -/** - * Sort modules by their dependencies - * - * @param modules Modules to sort - */ -export function topologicalSort(modules: JavaScriptModule[]): JavaScriptModule[] { - const topoSort = require('toposort'); - - // vertices are modules, an edge from a to b means that b depends on a - const edges: string[][] = []; - const nodes: string[] = []; - - // add all edges - modules.forEach((module) => { - module.dependencies.forEach((dependenciePath) => { - // add edge from dependency to our module - edges.push([basename(dependenciePath), module.name]); - }); - - nodes.push(module.name); - }); - - // sort graph and return as an array of sorted modules - return topoSort.array(nodes, edges).map((moduleName: string) => { - return modules.find((module) => { - return module.name === moduleName; - }); - }); -} diff --git a/src/pack.cli.ts b/src/pack.cli.ts deleted file mode 100644 index f7006391..00000000 --- a/src/pack.cli.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2018 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import * as del from 'del'; -import {logger} from './common'; -import {packCliJs} from './pack/pack-cli'; -import {packTypeDefinitions} from './pack/pack-definitions'; -import {packJavaScriptFiles} from './pack/pack-modules'; - -/** - * Pack - */ -async function pack() { - logger.log(`Packing project in ${process.cwd()}...`); - - // run all tasks in parallel - const promises: Array> = [ - packCliJs(), - packTypeDefinitions(), - packJavaScriptFiles(), - ]; - - await Promise.all(promises); - - // clean up afterwards - logger.info('Deleting extraneous files...'); - - await del([ - // delete all transpiled files - 'lib/*', - - // keep packed files - '!lib/index.d.ts', '!lib/index.js', - - // keep converted schema files - '!lib/schema', '!lib/schema/*.json', - - // keep documentation - '!lib/doc', '!lib/doc/*', '!lib/doc/**/*', - - // keep cli - '!lib/cli.js', - - // keep tests - '!lib/test', '!lib/test/*', '!lib/test/**/*', - ]); -} - -pack().then(() => { - logger.ok('Packed library!'); -}, (err) => { - logger.error(err); - process.exit(-1); -}); diff --git a/src/pack/pack-cli.ts b/src/pack/pack-cli.ts deleted file mode 100644 index 8ec62bda..00000000 --- a/src/pack/pack-cli.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2018 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {existsSync} from 'fs'; -import {join} from 'path'; -import {cwd} from 'process'; -import {logger, writeFilePromisified} from '../common'; -import {readFilePromisified} from '../common'; - -/** - * Pack cli.js - * - * This finds all internal requires and replaces the paths with `./index` or internal requires if it has been - * required already. - * - * Furthermore it checks that no shebang line is present and that it does not export anything. - */ -export async function packCliJs(): Promise { - const path = join(cwd(), 'lib', 'cli.js'); - - if (!existsSync(path)) { - return; - } - - logger.info('Adjusting JavaScript CLI...'); - - const buffer = await readFilePromisified(path); - const content = buffer.toString(); - - if (content.indexOf('#!/') === 0) { - throw new Error('`cli.js` must not contain a shebang line! It is added by this script.'); - } - - let internalRequire: string | null = null; - - const adjustedContent = '#!/usr/bin/env node\n\n' + content - .split('\n') - .map((line, lineNumber) => { - - // check for exports (cli.js is not allowed to export anything) - if (Array.isArray(line.match(/^\s*((exports)|(module\.exports))/))) { - throw new Error( - 'Line ' + - lineNumber + - ' in cli.js has a reference to the exports object. cli.js is not for exporting. Line was: "' - + line - + '"', - ); - } - - // replace lines with internal requires - // extract module name from line - const match = line.match(/^(\s*)(const|var) ([a-z0-9_]*) = require\(("[^"]+"|'[^']+')\);$/i); - - if (match !== null) { - const importedName = match[3]; - const moduleName = match[4].substring(1, match[4].length - 1); - - // if it begins with '.' and not ends with json - if (/^[.]{1,2}\/(?!.*\.json$).*$/i.test(moduleName)) { - - // is the first internal require - if (internalRequire !== null) { - return 'const ' + importedName + ' = ' + internalRequire + ';'; - } - - // only the first import needs a require - internalRequire = importedName; - return 'const ' + importedName + ' = require("./index");'; - } - } - return line; - }) - .join('\n'); - - return await writeFilePromisified(path, adjustedContent); -} diff --git a/src/pack/pack-definitions.ts b/src/pack/pack-definitions.ts deleted file mode 100644 index 7ad76526..00000000 --- a/src/pack/pack-definitions.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2018 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {join} from 'path'; -import {cwd} from 'process'; -import { - deleteFileIfExistingAndPacked, - globPromisified, - logger, - readFilePromisified, - writeFilePromisified, -} from '../common'; -import {PACK_IDENTIFIER} from '../configuration'; - -/** - * Get a list containing the contents of all type definition files - */ -async function getAllTypeDefinitions(): Promise { - const fileNames = await globPromisified(join(cwd(), '*(lib|src)', '**', '*.d.ts'), { - ignore: [ - join(cwd(), 'lib', 'doc', '**', '*.d.ts'), - join(cwd(), 'lib', 'test', '**', '*.d.ts'), - join(cwd(), 'lib', 'cli.d.ts'), - ], - }); - - const promises = fileNames.map((fileName) => { - return readFilePromisified(fileName, 'utf8'); - }); - - return await Promise.all(promises); -} - -/** - * Pack a list of type definitions into one file - */ -export async function packTypeDefinitions(): Promise { - logger.info('Packing TypeScript definition files...'); - - const path = join(cwd(), 'lib', 'index.d.ts'); - - await deleteFileIfExistingAndPacked(path); - - const typeDefinitions = await getAllTypeDefinitions(); - - // pack TypeScript definition files - const imports: { [k: string]: string[] } = {}; - - const referenceLines: string[] = []; - - let allDefinitions = typeDefinitions - // concat them separated by new lines - .join('\n\n\n\n\n') - // split all lines - .split('\n') - .map((line) => { - if (line.indexOf('export =') !== -1) { - throw new Error('`export =` is not allowed by pack. Use named imports instead.'); - } - - if (line.indexOf('/// { - return object.trim(); - }); - - // add list of already imported objects for module - if (typeof imports[module] === 'undefined') { - imports[module] = []; - } - - // count already imported objects and objects to import now - const objectsToImport: string[] = []; - importedObjects.forEach((object) => { - if (imports[module].indexOf(object) === -1) { - imports[module].push(object); - objectsToImport.push(object); - } - }); - - // replace import line - if (objectsToImport.length === 0) { - return '// extraneous removed import'; - } else { - return 'import { ' + objectsToImport.join(', ') + ' } from \'' + module + '\';'; - } - } - - return line; - }) - // filter lines which contain "local" imports - .filter((line) => { - return !line.match(/^import .* from '\./); - }) - // concat all lines separated by new lines - .join('\n'); - - if (allDefinitions.length > 0) { - if (referenceLines.length > 0) { - allDefinitions = referenceLines.join('\n') + '\n\n' + allDefinitions; - } - - // write packed TypeScript definition files - return await writeFilePromisified(path, PACK_IDENTIFIER + '\n\n' + allDefinitions); - } -} diff --git a/src/pack/pack-modules.ts b/src/pack/pack-modules.ts deleted file mode 100644 index 90a9bd06..00000000 --- a/src/pack/pack-modules.ts +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2018 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {existsSync} from 'fs'; -import {basename, dirname, join} from 'path'; -import {cwd} from 'process'; -import { - deleteFileIfExistingAndPacked, - getAllInternalDependecies, - globPromisified, - logger, - readFilePromisified, - topologicalSort, - writeFilePromisified, -} from '../common'; -import {PACK_IDENTIFIER} from '../configuration'; -import {JavaScriptModule} from './types'; - -/** - * Get all JavaScript modules - */ -async function getAllJavaScriptModules(): Promise { - const fileNames = await globPromisified(join(cwd(), 'lib', '**', '*.js'), { - ignore: [ - join(cwd(), 'lib', 'doc', '**', '*.js'), - join(cwd(), 'lib', 'test', '*.js'), - join(cwd(), 'lib', 'cli.js'), - ], - }); - - const promises = fileNames.map(async (fileName) => { - const fileContent = await readFilePromisified(fileName, 'utf8'); - const directory = dirname(fileName).replace(new RegExp('^' + join(cwd(), 'lib')), ''); - - return { - content: '(function() {\n' + fileContent + '\n})();\n', - dependencies: getAllInternalDependecies(fileContent), - directory: directory, - name: basename(fileName, '.js'), - }; - }); - - return await Promise.all(promises); -} - -/** - * Pack all javascript files - */ -export async function packJavaScriptFiles(): Promise { - const path = join(cwd(), 'lib', 'index.js'); - - logger.info('Packing JavaScript files...'); - - await deleteFileIfExistingAndPacked(path); - - // topologically sort the modules (sort by dependencies) - const jsModules = topologicalSort(await getAllJavaScriptModules()); - - let wholeCode = jsModules - // convert modules to strings - .map((module) => { - module.content = module.content - .split('\n') - .map((line) => { - const match = line.match( - /^(\s*)(const|var) ([a-z0-9_]*) = ((require\("([^"]+)"\))|(require\('([^']+)'\)));$/i, - ); - - // replace lines with internal requires - if (match !== null) { - // match[6] or match[8] contain the modulePath - if (typeof match[6] === 'undefined') { - match[6] = match[8]; - } - - const whiteSpace = match[1] ? match[1] : ''; - const importedName = match[3]; - const modulePath = match[6]; - - // leave line unchanged if it is a "global" import - if (modulePath.match(/^[.]{1,2}\//) === null) { - return line; - } - - // replace internal requires with `module.exports` - if (existsSync(join(cwd(), 'lib', module.directory, modulePath + '.js'))) { - return whiteSpace + 'const ' + importedName + ' = module.exports;'; - } - - if (existsSync(join(cwd(), 'src', module.directory, modulePath))) { - return whiteSpace + 'const ' + importedName + ' = require(\'../src/' + modulePath + '\');'; - } - - logger.warn('Import ' + importedName + ' could not be found in module.directory ' + modulePath); - } - - return line; - }) - .join('\n'); - - return '// Module: ' + module.name + '\n' + module.content; - }) - // concat them separated by new lines - .join('\n\n\n\n\n') - // split all lines - .split('\n') - // filter lines - .filter((line) => { - // remove strict usage - if (line === '"use strict";') { - return false; - } - - // remove esModule property - if (line === 'Object.defineProperty(exports, "__esModule", { value: true });') { - return false; - } - - // remove source map references - if (line.indexOf('//# sourceMappingURL=') === 0) { - return false; - } - - // keep all other lines - return true; - }) - // concat all lines separated by new lines - .join('\n'); - - if (wholeCode.length > 0) { - // add meta lines to the file - wholeCode = '"use strict";\nObject.defineProperty(exports, "__esModule", { value: true });\n\n' + wholeCode; - - // write packed JavaScript files - return await writeFilePromisified(path, PACK_IDENTIFIER + '\n\n' + wholeCode); - } -} diff --git a/src/pack/types.ts b/src/pack/types.ts deleted file mode 100644 index 684d02d1..00000000 --- a/src/pack/types.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2018 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -/** - * A JavaScript module representation to sort a list of them by dependencies - */ -export interface JavaScriptModule { - /** - * Content of the module - */ - content: string; - - /** - * List of names of dependencies - */ - dependencies: string[]; - - /** - * Directory the module is in - */ - directory: string; - - /** - * The name of the module - */ - name: string; -}