UNPKG

jsheader

Version:
231 lines (184 loc) 5.89 kB
/* SPECIFICATION FOR CONFIG FILE: JSON file with fields: - Mandatory: - header: String - Optional: - directory: String. Uses pwd as default. Root directory of the project - exclude: Array<String>. The strings must be regexes (without the //), excludes paths that match - headerTest: String. Stringifed regex (without //). Used to match old headers - extension: Array<String>. Extensions of the files to modify. Default: ['js', 'jsx'] */ const path = require('path'); const fs = require('fs'); // Getting config const configFile = process.argv[2]; if (!configFile) { throw 'Config file not provided'; } const config = (() => { const config = {}; try { const configFileContent = JSON.parse(fs.readFileSync(configFile).toString()); if (!configFileContent.header) { throw `Configuration not valid: missing parameter header`; } // Building regex for excluded config.exclude = configFileContent.exclude && configFileContent.exclude.map && configFileContent.exclude.map((e) => new RegExp(e)) || []; // Adding directory if (!configFileContent.directory) { // No directory provided, using pwd try { const pwd = /^(.*\/)(?:[^\/]*)$/.exec(process.argv[1])[1]; if (pwd.length > 1) { config.directory = pwd; } else { throw 1; } } catch (e) { throw `Directory not provided and could not determine the present working directory`; } } else { config.directory = configFileContent.directory; } // Adding header config.header = configFileContent.header + ''; // Extension config.extension = configFileContent.extension && configFileContent.extension.constructor === Array ? configFileContent.extension : ['js', 'jsx']; config.extension = config.extension.map((extension) => new RegExp(`.${extension}$`)); // Pattern for detecting header (detects any /** */ that has @license */ const detectHeaderDefault = /^\/(.|\n)+?@license(.|\n)+?\*\/[\n]*/; config.detectHeader = configFileContent.headerTest ? new RegExp(configFileContent.headerTest) : detectHeaderDefault; return config; } catch (e) { console.log(`Could not use config file.`); console.log(e); process.exit(); } })(); // Printing settings console.log(`Header to be written:`); console.log(`=== START ===`); console.log(config.header); console.log(`=== END ===`); console.log(''); console.log(`Files directory: ${config.directory}`); console.log(''); console.log(`File extension: ${config.extension}`); console.log(''); console.log('Test for exclusion:'); config.exclude.forEach((e) => console.log(`- ${e.toString()}`)); console.log(''); console.log(`Test for detecting old headers: ${JSON.stringify(config.detectHeader.toString())}`); console.log(''); // Getting files in the directory let files = (function () { const files = []; const rootPath = config.directory; readDir([ rootPath ]); function readDir(path = []) { const stringPath = path.join('/'); const dirFiles = fs.readdirSync(stringPath); dirFiles.forEach((file) => { const thisPathString = [ ...path, file ].join('/'); const isDirectory = fs.lstatSync(thisPathString).isDirectory(); // Invalid path if (!allowedPath(thisPathString)) { return; } if (isDirectory) { readDir([ ...path, file ]); } else { // Invalid extension if (!allowedExtension(thisPathString)) { return; } files.push(thisPathString); } }); } return files; })(); if (files.length < 1) { console.log('No files matched!'); process.exit(); } console.log(`${files.length} files found:`); files.forEach(file => console.log(`- ${file}`)); console.log('\nDo you want to continue? (y/n)'); process.stdin.on('data', (input) => { input = (input + '').replace(/[ \n]/g, '').toLowerCase(); if (input === 'y') { console.log('Writing headers'); // Writing headers on every file Promise .all(files.map(file => writeHeader(file))) .then(() => { console.log('All done'); process.exit(); }) .catch((err) => { console.log(err); process.exit(); }); } else { console.log('Canceled'); process.exit(); } }); /** * Writes the header to a file * @return {Promise} */ function writeHeader(file) { return new Promise((resolve) => { const existingDataBuffer = fs.readFileSync(file); // Removing old headers const newData = config.header + existingDataBuffer .toString() .replace(config.detectHeader, ''); const handler = fs.openSync(file, 'w+'); // Writing new data fs.writeFile(file, newData, () => { fs.close(handler); resolve(); }); }); } /** * Tests if a path is allowed or not * @return {Boolean} */ function allowedPath(path) { // Empty path if (path.length < 1) { return false; } return config.exclude.reduce((result, test) => { // We matched the pattern, so the path is not allowed if (test.test(path)) { return false; } return result; }, true); } /** * Tests if an extension is allowed * @return {Boolean} */ function allowedExtension(path) { // Empty path if (path.length < 1) { return false; } // No filters if (config.extension.length < 1) { return true; } return config.extension.reduce((result, test) => { // We did match the pattern, so the path is allowed if (test.test(path)) { return true; } return result; }, false); }