UNPKG

@tangelo/tangelo-configuration-toolkit

Version:

Tangelo Configuration Toolkit is a command-line toolkit which offers support for developing a Tangelo configuration.

83 lines (68 loc) 3 kB
const fs = require('fs-extra'); const globby = require('globby'); const minimatch = require('minimatch'); const path = require('path'); const rif = require('replace-in-file'); class PathSearcher { #filter; #ignorePaths = [_paths.tdi + '/**', 'config/cmscustom/tdi/**', '**/node_modules/**', '**/fonto/packages_shared/**', '**/fonto/platform/**']; constructor (filter, ignoreProjectPaths) { this.#filter = filter; this.#ignorePaths.push(...ignoreProjectPaths); } #doFilter (paths) { return this.#filter ? paths.filter(p => minimatch(p, this.#filter)) : paths; } get(globPath) { return this.#doFilter(globby.sync(globPath, {dot: true, ignore: this.#ignorePaths})); } } module.exports = function steps (step, dry, passedFilter, projectsWithType) { if (Array.isArray(step)) { step.forEach(substep => steps(substep, dry, passedFilter, projectsWithType)); return; } const {projectType = 'all', applyFilter = true, deletePaths, renamePaths, replaceInFiles, customAction} = step; const projectsToIgnore = projectType === 'all' ? [] : projectsWithType.filter(p => p.tcl !== (projectType === 'tcl')); const pathSearcher = new PathSearcher(applyFilter && passedFilter, projectsToIgnore.map(p => p.path + '/**')); if (deletePaths) { deletePaths.forEach(curpath => { _info(`Deleting paths: ${curpath}`); const paths = pathSearcher.get(curpath); if (!dry) paths.forEach(p => fs.removeSync(p)); _write('Paths deleted:', paths.length); }); } if (renamePaths) { renamePaths.forEach(([curpath, change]) => { _info(`Renaming paths: ${curpath}`); const paths = pathSearcher.get(curpath); if (!dry) paths.forEach(p => fs.moveSync(p, path.join(p, change), {overwrite: true})); _write('Paths renamed:', paths.length); }); } if (replaceInFiles) { replaceInFiles.forEach(r => { _info(`Executing replacements in files: ${r.files}`); r.files = r.files.map(curpath => pathSearcher.get(curpath)).flat(); r.dry = dry; if (r.fromtoPairs) { r.from = r.fromtoPairs.map(p => p[0]); r.to = r.fromtoPairs.map(p => p[1]); } let filesModCount; for (let i=15/* safety limit*/; i>0 && r.files[0]; i--) { // execute repeatedly for modified files only r.files = rif.sync(r).filter(f => f.hasChanged).map(f => f.file); filesModCount ??= r.files.length; // save count only after first run (after this only subsets are processed) if (i===1 && r.files[0]) _warn(`Repeated replacement stopped by safety limit - check file changes for too many content occurrences`); if (dry) break; } _write('Files modified:', filesModCount); }); } if (!dry && customAction) { customAction.forEach(([dirpath, actionFn]) => { pathSearcher.get(dirpath).forEach(p => actionFn(p)); }); } };