UNPKG

abapmerge

Version:

Merge ABAP INCLUDEs into single file

276 lines 12.7 kB
"use strict"; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable @typescript-eslint/no-unused-vars */ var file_list_1 = __importDefault(require("./file_list")); var file_1 = __importDefault(require("./file")); var fast_xml_parser_1 = require("fast-xml-parser"); var PragmaProcessor = /** @class */ (function () { function PragmaProcessor(files, opts) { this.files = files; this.opts = opts || {}; } PragmaProcessor.process = function (files, opts) { var instance = new PragmaProcessor(files, opts); return instance.processFiles(); }; PragmaProcessor.prototype.processFiles = function () { var e_1, _a, e_2, _b; var newFiles = new file_list_1.default(); try { for (var _c = __values(this.files), _d = _c.next(); !_d.done; _d = _c.next()) { var file = _d.value; if (file.isBinary() || !file.isABAP()) { newFiles.push(file); continue; } var lines = file.getContents().split("\n"); var hasPragma = false; var output = []; try { for (var lines_1 = (e_2 = void 0, __values(lines)), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) { var line = lines_1_1.value; var pragma = line.match(/^(\*|(\s*)")\s*@@abapmerge\s+(.+)/i); if (pragma) { var pragmaCmd = pragma[3]; var indent = (pragma[1] === "*") ? "" : pragma[2]; var processed = this.processPragma(indent, pragmaCmd); if (processed && processed.length > 0) { hasPragma = true; output.push.apply(output, __spreadArray([], __read(processed), false)); } else { output.push(line); } } else { output.push(line); } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (lines_1_1 && !lines_1_1.done && (_b = lines_1.return)) _b.call(lines_1); } finally { if (e_2) throw e_2.error; } } newFiles.push(hasPragma ? new file_1.default(file.getFilename(), output.join("\n")) : file); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_1) throw e_1.error; } } return newFiles; }; PragmaProcessor.prototype.comment = function (name) { return this.opts.noComments ? [] : [ "****************************************************", "* abapmerge Pragma [".concat(this.currentPragmaName, "] - ").concat(name.toUpperCase()), "****************************************************", ]; }; PragmaProcessor.prototype.processPragma = function (indent, pragma) { /* pragmas has the following format * @@abapmerge command params * if written as " comment, then indentation before " is also used for output * Currently supported pragmas: * - include {filename} > {string wrapper} * {filename} - path to the file relative to script execution dir (argv[0]) * {string wrapper} is a pattern where $$ is replaced by the include line * $$ is escaped - ' replaced to '' (to fit in abap string), use $$$ to avoid escaping * e.g. include somestyle.css > APPEND '$$' TO styletab. * - include-cua { filaname.xml } > { variable } * parse xml file, find CUA node and convert it to `variable` * zcl_abapgit_objects_program=>ty_cua type is expected for the var */ var result = []; var cmdMatch = pragma.match(/(\S+)\s+(.*)/); if (!cmdMatch) return null; var command = cmdMatch[1].toLowerCase(); var commandParams = cmdMatch[2]; this.currentPragmaName = command; // hack for `comment()` switch (command) { case "include": result.push.apply(result, __spreadArray([], __read(this.pragmaInclude(indent, commandParams)), false)); break; case "include-base64": result.push.apply(result, __spreadArray([], __read(this.pragmaIncludeBase64(indent, commandParams)), false)); break; case "include-cua": result.push.apply(result, __spreadArray([], __read(this.pragmaIncludeCua(indent, commandParams)), false)); break; default: break; } return result; }; PragmaProcessor.prototype.pragmaInclude = function (indent, includeParams) { var params = includeParams.match(/(\S+)\s*>\s*(.*)/i); if (!params) return []; var filename = params[1]; var template = params[2]; var lines = this.files.otherByName(filename).getContents().split("\n"); if (lines.length > 0 && !lines[lines.length - 1]) { lines.pop(); // remove empty string } var result = []; result.push.apply(result, __spreadArray([], __read(this.comment(filename)), false)); result.push.apply(result, __spreadArray([], __read(lines.map(function (line) { var render = template.replace("$$$", line); // unescaped render = render.replace("$$", line.replace(/'/g, "''")); // escape ' -> '' return indent + render; })), false)); return result; }; PragmaProcessor.prototype.pragmaIncludeBase64 = function (indent, includeParams) { var params = includeParams.match(/(\S+)\s*>\s*(.*)/i); if (!params) return []; var filename = params[1]; var template = params[2]; var lines = this.files.otherByName(filename) .getBlob() .toString("base64") .match(/.{1,60}/g); if (!lines || lines.length === 0) return []; return __spreadArray(__spreadArray([], __read(this.comment(filename)), false), __read(lines.map(function (line) { return indent + template.replace(/\${2,3}/, line); })), false); }; PragmaProcessor.prototype.pragmaIncludeCua = function (indent, includeParams) { var params = includeParams.trim().match(/(\S+)\s*>\s*(\S+)/i); if (!params) return []; var filename = params[1]; var varName = params[2]; if (!/\.xml$/i.test(filename)) return []; var xml = this.files.otherByName(filename).getContents(); var lines = new CuaConverter().convert(xml, varName); if (!lines || lines.length === 0) return []; return __spreadArray(__spreadArray([], __read(this.comment(filename)), false), __read(lines.map(function (i) { return indent + i; })), false); }; return PragmaProcessor; }()); exports.default = PragmaProcessor; var CuaConverter = /** @class */ (function () { function CuaConverter() { } CuaConverter.prototype.convert = function (xml, varName) { var e_3, _a; var _b, _c, _d; var parser = new fast_xml_parser_1.XMLParser({ ignoreAttributes: true, numberParseOptions: { leadingZeros: false, hex: true }, // to keep leading zeros isArray: function (_name, jpath, _isLeafNode, _isAttribute) { // single item tables are still arrays (all but ADM branch) if (!jpath.startsWith("abapGit.asx:abap.asx:values.CUA.")) return false; var path = jpath.split("."); if (path.length !== 6) return false; if (path[4] === "ADM") return false; // flat structure return true; }, }); var parsed = parser.parse(xml); if (!parsed) throw Error("CuaConverter: XML parsing error"); var cua = (_d = (_c = (_b = parsed === null || parsed === void 0 ? void 0 : parsed.abapGit) === null || _b === void 0 ? void 0 : _b["asx:abap"]) === null || _c === void 0 ? void 0 : _c["asx:values"]) === null || _d === void 0 ? void 0 : _d.CUA; if (!cua) return null; // cua is not found - nothing to convert but not an exception var defs = []; var code = []; // eslint-disable-next-line guard-for-in for (var key in cua) { var node = cua[key]; key = key.toLowerCase(); if (key === "adm") { code.push.apply(code, __spreadArray([], __read(this.fillStruc("".concat(varName, "-adm"), node)), false)); } else { var itemName = "ls_".concat(key); defs.push("DATA ".concat(itemName, " LIKE LINE OF ").concat(varName, "-").concat(key, ".")); var attrs = Object.keys(node); if (attrs.length !== 1) throw Error("CuaConverter: unexpected structure of [".concat(key, "] node")); node = node[attrs[0]]; if (!Array.isArray(node)) throw Error("CuaConverter: unexpected structure of [".concat(key, "/").concat(attrs[0], "] node")); try { for (var node_1 = (e_3 = void 0, __values(node)), node_1_1 = node_1.next(); !node_1_1.done; node_1_1 = node_1.next()) { var itemData = node_1_1.value; code.push("CLEAR ".concat(itemName, ".")); code.push.apply(code, __spreadArray([], __read(this.fillStruc(itemName, itemData)), false)); code.push("APPEND ".concat(itemName, " TO ").concat(varName, "-").concat(key, ".")); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (node_1_1 && !node_1_1.done && (_a = node_1.return)) _a.call(node_1); } finally { if (e_3) throw e_3.error; } } } } return __spreadArray(__spreadArray([], __read(defs), false), __read(code), false); }; CuaConverter.prototype.fillStruc = function (varName, obj) { return __spreadArray([], __read(Object.entries(obj)), false).map(function (_a) { var _b = __read(_a, 2), key = _b[0], val = _b[1]; return "".concat(varName, "-").concat(key.toLowerCase(), " = '").concat(val, "'."); }); }; return CuaConverter; }()); //# sourceMappingURL=pragma.js.map