UNPKG

@tangelo/tangelo-configuration-toolkit

Version:

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

178 lines (151 loc) 7.59 kB
const fs = require('fs-extra'); const globby = require('globby'); const path = require('path'); const SaxonJS = require('saxon-js'); const spConfigPath = 'build/oxygen/stylesheetPaths.json'; const sefFilePath = 'build/oxygen/createProjectFile.sef.json'; const cmscustomPath = 'config/cmscustom/'; const siteStylesheetsPath = 'config/txp/site-stylesheets/'; const masterFiles = new Set; const transformationScenarios = []; let spConfig, sefFile; const convertToValidFilename = string => string.replace(/[/|\\:*?"<>]/g, ' '); const createProjectFile = (config, newXprFile) => { _info('Initializing xpr file(s):'); const xprFiles = [...globby.sync(`*.xpr`)]; // Add newXprFile at the start of xprFiles if it does not already exists: if (newXprFile && xprFiles.indexOf(newXprFile)===-1) xprFiles.unshift(newXprFile); // Copy xpr file from TDI if it does not exists yet; if (xprFiles[0] && !newXprFile) _write(`Found: ${xprFiles.join(', ')}`); else { if (!newXprFile) { // Set xpr filename to customer name (assumes correct upsert scripts structure) const customers = new Set; _repoconfig.forEach(p => customers.add(p.customer_name)); xprFiles.push(convertToValidFilename([...customers].join(' - ')) + '.xpr'); } // Copy new xpr file fs.copySync(path.join(_paths.repo, 'tangelo-default-implementation/src/[customer].xpr'), path.join(_paths.repo, xprFiles[0])); _write(`Created: '${xprFiles[0]}'`); } // Search for transformationScenarios/masterfiles based on TDI submodule oxygenProjectFile config _info('\nSearching for transformationScenarios/masterfiles'); config.oxygenProjectFile.forEach( pf => { // Collect transformation scenarios and add them to the transformationScenarios array; add individual stylesheets to the masterFiles set. if (pf.transformation) getTransformations(pf.transformation); // Add files to the masterfiles set. else if (pf.masterfile) getMasterfiles(pf.masterfile); } ); // update all .xpr files with collected transformation scenarios and masterfiles. transformXprFile(xprFiles); }; const getTransformations = config => { _repoconfig.forEach(rc => { // get pathname of customer/project const [customerPath, projectPath] = config.location === 'database' ? rc.path_dbconfig : rc.path_cmscustom; // set pathname of customer/project in location glob-expression const location = path.join( _paths.repo, config.files.replace(/\[customer\]/, customerPath).replace(/\[project\]/, projectPath) ); globby .sync(`${location}`) .forEach(f => { // extract baseStrings from file const fileString = fs.readFileSync(f).toString(); const baseStrings = fileString.match(RegExp(config.extracts.base, 'gm')); if (fileString.replace(/\s|^prompt\s.*$/gm, '') !== '') { if (baseStrings) { baseStrings.forEach(s => { // extract type, name, files info from baseString const type = config.extracts.type ? s.match(RegExp(config.extracts.type))[1] : config.values.type; const name = config.extracts.name ? s.match(RegExp(config.extracts.name))[1] : config.values.name; const files = s.match(RegExp(config.extracts.files))[1]; // Add transformation scenario to the transformationScenario array transformationScenarios.push({ name: `${type}: ${name} (${rc.customer_name}, ${rc.project_name})`, // note that in createProjectFile.xsl a regex is added that matches scenarios based on this name. This to preserve manually added scenarios. transformationScenario: files, location: config.location === 'txp' ? siteStylesheetsPath : cmscustomPath }); // Add each non-tdi stylesheet in transformation scenario to the masterFiles set files.split(',').forEach(f => { const filePath = `${config.location === 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`; if (!f.startsWith('tdi')) masterFiles.add(filePath); }); }); } else { _write(`No transformation scenarios found in ${f} for '${config.extracts.base}'`); } } }); }); }; const getMasterfiles = config => { globby .sync(`${path.join(_paths.repo, config.files)}`) .forEach(cf => { // Check if masterfile should be extracted from file const fileString = fs.readFileSync(cf).toString(); if (fileString.replace(/\s|^prompt\s.*$/gm, '')!=='') { if (config.extracts) { // extract baseStrings from file const baseStrings = fileString.match(RegExp(config.extracts.base, 'gm')); if (baseStrings) { baseStrings.forEach(s => { // extract (comma-separated) list of masterfiles const filesString = s.match(RegExp(config.extracts.files))[1]; if (!filesString) _error(`No masterfiles found in '${s}' for '${config.extracts.files}'`); // Add each non-tdi masterfile to the masterFiles set filesString.split(',').forEach(f => { if (!f.startsWith('tdi')){ const filePath = `${config.location === 'txp' ? siteStylesheetsPath : cmscustomPath}${f}`; masterFiles.add(filePath); } }); }); } else { _write(`No masterfiles found in ${cf} for '${config.extracts.base}'`); } } else { // Add synced file to masterfiles; strip path from c:/... hence it starts with config/cmscustom or config/txp/site-stylesheets const filePath = config.location === 'txp' ? `${siteStylesheetsPath}${cf.split(siteStylesheetsPath)[1]}` : `${cmscustomPath}${cf.split(cmscustomPath)[1]}`; masterFiles.add(filePath); } } }); }; const transformXprFile = xprFiles => { _info('\nUpdating xpr file(s):'); // create with: xslt3 -t -xsl:createProjectFile.xsl -export:createProjectFile.sef.json v -nogo' xprFiles .forEach(xprFile => { // Transform xpr; add masterfiles and transformationScenarios as parameters of the stylesheet _write(`${xprFile}\n`); SaxonJS.transform({ stylesheetText: JSON.stringify(sefFile), stylesheetBaseURI: 'createProjectFile.sef.json', sourceFileName: path.join(_paths.repo, xprFile), destination: 'serialized', stylesheetParams: { 'masterfiles': [...masterFiles], 'Q{}transformationScenarios': transformationScenarios } }, 'async') .then(output => { // Write result of transformation to xpr file fs.writeFileSync(path.join(_paths.repo, xprFile), output.principalResult); }) .catch(e => _warn(`Failed to update: ${xprFile}\n ${e}`)); }); }; module.exports = function oxygen (arg) { // Set projects transformation scenarios and masterfiles in oXygen project file // - Will try to preserve manually added entries in the transformation scenarios and masterfiles // - Will remove non existing masterfiles or masterfiles that start with a '_' spConfig = _modulesTdi.require(spConfigPath); sefFile = _modulesTdi.require(sefFilePath); if (!spConfig || !sefFile) _error(`Cannot find required files in TDI submodule. Try updating TDI submodule.`); const newXprFile = (typeof arg === 'string') ? convertToValidFilename(arg) + '.xpr' : null; createProjectFile(spConfig, newXprFile); };