UNPKG

caml

Version:
215 lines (177 loc) 5.55 kB
/** * Parses @include statements. * * @param yaml * @param dir * @returns {String} */ module.exports.parseIncludes = function (yaml, dir) { const fs = require('fs'); const os = require('os'); const path = require('path'); var yamlLines = yaml.split(/\n/); var index = 0; var hasInclude = true; while (hasInclude) { hasInclude = false; for (var i = 0; i < yamlLines.length; i++) { var line = yamlLines[i]; if (line.trim().length > 0 && line.trim().indexOf("#") > -1 && line.indexOf("@include") > -1) { // hasInclude = true; var include = line.replace(/#.*@include\s*/, ''); // Add .yml if need be // istanbul ignore else if (path.extname(include) !== 'yml') { include = include + ".yml"; } // If relative path, resolve it // istanbul ignore else if (!path.isAbsolute(include)) { include = path.join(dir, include) } var includeContentLines = ""; try { includeContentLines = fs.readFileSync(include, "UTF8").split(/\r?\n/); } catch (err) { console.error("File to include " + include + ' not found.'); throw (err); } yamlLines.splice.apply(yamlLines, [index, 1].concat(includeContentLines)); } index++; } hasInclude = false; } return yamlLines.join('\n'); }; /** * Strips empty lines and comments from a given array of YAML lines. * * @param yamlLines * @returns {Array} */ module.exports.stripEmptyLinesAndComments = function (yamlLines) { var strippedLines = []; yamlLines.forEach(function (line) { if (line.trim().length > 0 && line.trim().indexOf("#") === -1) { strippedLines.push(line); } else if ((line.match(/.*:\s['].*#.*[']/))) { // e.g. param: "git://caml.git#1.2.3" strippedLines.push(line); } }); return strippedLines; }; /** * Strips anchors from a given array of YAML lines. * * @param yamlLines * @returns {Array} */ module.exports.stripAnchors = function (yamlLines) { var strippedLines = []; yamlLines.forEach(function (line) { if (line.indexOf(": &") > -1) { strippedLines.push(line.replace(line.match(/&.*/)[0], "")); } else { strippedLines.push(line); } }); return strippedLines; }; /** * Retrieves the anchors from a given array of YAML lines. * * @param yamlLines (yaml as an array of lines) * @returns {Object} */ module.exports.retrieveAnchors = function (yamlLines) { var anchors = {}; // Find anchors, with their indentation and block content yamlLines.forEach(function (line, index) { if (line.indexOf("&") > -1) { var anchorName = line.match("&(.*)")[1]; var me = anchors[anchorName]; var indentDiff = 0; // If the anchor already exists, push additional content if (me) { indentDiff = me.indent - line.search(/\S|$/); } else { me = anchors[anchorName] = { indent: line.search(/\S|$/), block: [] }; } // Store the block content for (var i = index + 1; i < yamlLines.length; i++) { // when encountering an equal or lower indentation, the block ends if (yamlLines[i].search(/\S|$/) <= me.indent - indentDiff) { break; } // check for circular references if (yamlLines[i].match(new RegExp("<<: \\*" + anchorName + "$"))) { break; } var str = yamlLines[i]; // Fix the indentation levels for the original block content if (indentDiff !== 0) { // Shift indentations of the block content if (indentDiff > 0) { str = new Array(indentDiff + 1).join(' ') + yamlLines[i]; } else { for (var j = 0; j > indentDiff; j--) { str = str.replace(' ', ' '); } } } me.block.push(str.replace(/&.*/, "")); } } }); return anchors; }; /** * Adds block content from the anchors to the aliases * * @param yamlLines (yaml as an array of lines) * @param anchors * @returns {Array} */ module.exports.replaceAliases = function (yamlLines, anchors) { var replacedLines = []; // Find aliases, strip them and add anchor content yamlLines.forEach(function (line) { // << :* alias if (line.trim().indexOf("<<: *") === 0 || line.trim().indexOf(": *") > -1) { var alias = line.trim().replace("<<: *", ""); var indentUp = -2; if (line.trim().indexOf("<<: *") === -1 && line.trim().indexOf(": *") > -1) { alias = line.trim().replace(/.*: \*/, ""); replacedLines.push(line.replace(" *" + alias, "")); indentUp = 0; } /* istanbul ignore else */ if (anchors[alias]) { var indentDiff = line.search(/\S|$/) - anchors[alias].indent + indentUp; anchors[alias].block.forEach(function (blockLine) { var str; // Shift indentations of the block content if (indentDiff > 0) { str = new Array(indentDiff + 1).join(' ') + blockLine; } else { str = blockLine; for (var i = 0; i > indentDiff; i--) { str = str.replace(' ', ' '); } } replacedLines.push(str); }); } else { throw new Error("Alias " + alias + " does not have an anchor reference. Line content = '" + line + "'"); } } else { replacedLines.push(line); } }); return replacedLines; };