UNPKG

@hpcc-js/comms

Version:
585 lines 24.5 kB
import { __extends, __spreadArray } from "tslib"; import * as cp from "child_process"; import * as fs from "fs"; import * as os from "os"; import * as path from "path"; import * as tmp from "tmp"; import { exists, scopedLogger, xml2json } from "@hpcc-js/util"; import { attachWorkspace } from "./eclMeta"; var logger = scopedLogger("clienttools/eclcc"); var exeExt = os.type() === "Windows_NT" ? ".exe" : ""; function tidyCRLF(inStr) { return inStr.split("\r\n").join("\n").split("\r").join("\n"); } var Version = /** @class */ (function () { function Version(build) { this.prefix = ""; this.major = 0; this.minor = 0; this.patch = 0; this.postfix = ""; var parts = build.split(" "); if (parts.length) { var match = /(?:(\w+)_)?(\d+)\.(\d+)\.(\d+)(?:-(.*))?/.exec(parts[parts.length - 1]); if (match) { this.prefix = match[1] || ""; this.major = +match[2] || 0; this.minor = +match[3] || 0; this.patch = +match[4] || 0; this.postfix = match[5] || ""; } } } Version.prototype.parse = function (build) { }; Version.prototype.exists = function () { return this.major !== 0 || this.minor !== 0 || this.patch !== 0 || this.postfix !== ""; }; Version.prototype.compare = function (other) { if (this.major > other.major) return 1; if (this.major < other.major) return -1; if (this.minor > other.minor) return 1; if (this.minor < other.minor) return -1; if (this.patch > other.patch) return 1; if (this.patch < other.patch) return -1; if (this.postfix === "" && other.postfix !== "") return 1; return this.postfix.localeCompare(other.postfix); }; Version.prototype.toString = function () { return "".concat(this.prefix, "_").concat(this.major, ".").concat(this.minor, ".").concat(this.patch, "-").concat(this.postfix); }; return Version; }()); export { Version }; var ERROR = "error"; var WARN = "warning"; var Errors = /** @class */ (function () { function Errors(checked) { this.errWarn = []; this.errOther = []; this._checked = checked; } Errors.prototype.checked = function () { return this._checked; }; Errors.prototype.all = function () { return this.errWarn; }; Errors.prototype.errors = function () { return this.errWarn.filter(function (e) { return e.severity === ERROR; }); }; Errors.prototype.hasError = function () { return this.errors().length > 0; }; Errors.prototype.warnings = function () { return this.errWarn.filter(function (e) { return e.severity === WARN; }); }; Errors.prototype.hasWarning = function () { return this.warnings().length > 0; }; Errors.prototype.info = function () { return this.errWarn.filter(function (e) { return [ERROR, WARN].indexOf(e.severity) < 0; }); }; Errors.prototype.hasOther = function () { return this.info().length > 0; }; Errors.prototype.unknown = function () { return this.errOther; }; Errors.prototype.hasUnknown = function () { return this.unknown().length > 0; }; return Errors; }()); export { Errors }; var EclccErrors = /** @class */ (function (_super) { __extends(EclccErrors, _super); function EclccErrors(stdErr, checked) { var _this = _super.call(this, checked) || this; if (stdErr && stdErr.length) { for (var _i = 0, _a = stdErr.split(os.EOL); _i < _a.length; _i++) { var errLine = _a[_i]; var match = /([a-zA-Z]:\\(?:[- \w\.\d]+\\)*(?:[- \w\.\d]+)?|(?:\/[\w\.\-]+)+)\((\d*),(\d*)\) ?: ?(error|warning|info) C(\d*) ?: ?(.*)/.exec(errLine); if (match) { var filePath = match[1], row = match[2], _col = match[3], severity = match[4], code = match[5], _msg = match[6]; var line = +row; var col = +_col; var msg = code + ": " + _msg; _this.errWarn.push({ filePath: filePath, line: line, col: col, msg: msg, severity: severity }); continue; } match = /(error|warning|info): (.*)/i.exec(errLine); if (match) { var severity = match[1], msg = match[2]; _this.errWarn.push({ filePath: "", line: 0, col: 0, msg: msg, severity: severity }); continue; } match = /\d error(s?), \d warning(s?)/.exec(errLine); if (match) { continue; } logger.warning("parseECLErrors: Unable to parse \"".concat(errLine, "\"")); _this.errOther.push(errLine); } } _this._checked = checked; return _this; } return EclccErrors; }(Errors)); export { EclccErrors }; var EnvchkErrors = /** @class */ (function (_super) { __extends(EnvchkErrors, _super); function EnvchkErrors(filePath, stdErr, checked) { var _this = _super.call(this, checked) || this; var content = fs.readFileSync(filePath, "utf8"); content = content.replace(/\r\n/g, "\n"); _this._lines = content.split("\n"); if (stdErr && stdErr.length) { for (var _i = 0, _a = stdErr.split(os.EOL); _i < _a.length; _i++) { var errLine = _a[_i]; var match = /(Warning|Error) : Path\=(\S*?)(\[\S*\])? Message\=(.*)/.exec(errLine); if (match) { var severity = match[1], _path = match[2], _attr = match[3], _msg = match[4]; var msg = "".concat(_path, " ").concat(_attr ? _attr : "", ": ").concat(_msg); var _b = _this.locate(_path), line = _b[0], col = _b[1]; _this.errWarn.push({ filePath: filePath, line: line, col: col, msg: msg, severity: severity }); continue; } if (match) { continue; } logger.warning("parseECLErrors: Unable to parse \"".concat(errLine, "\"")); _this.errOther.push(errLine); } } _this._checked = checked; return _this; } EnvchkErrors.prototype.locate = function (path) { var pathParts = path.split("/"); if (pathParts.length && pathParts[0] === "") { pathParts.shift(); } if (pathParts.length > 0) { var lineIdx = 0; for (var _i = 0, _a = this._lines; _i < _a.length; _i++) { var line = _a[_i]; var testStr = "<" + pathParts[0]; if (line.indexOf(testStr + " ") >= 0 || line.indexOf(testStr + ">") >= 0) { pathParts.shift(); if (pathParts.length === 0) { return [lineIdx + 1, line.indexOf(testStr) + 1]; } } ++lineIdx; } } return [0, 0]; }; return EnvchkErrors; }(Errors)); export { EnvchkErrors }; export function walkXmlJson(node, callback, stack) { stack = stack || []; stack.push(node); for (var key in node) { if (node.hasOwnProperty(key)) { var childNode = node[key]; callback(key, childNode, stack); if (childNode instanceof Array) { childNode.forEach(function (child) { walkXmlJson(child, callback, stack); }); } else if (typeof childNode === "object") { walkXmlJson(childNode, callback, stack); } } } stack.pop(); } var LocalWorkunit = /** @class */ (function () { function LocalWorkunit(jsonWU) { this.jsonWU = jsonWU; } LocalWorkunit.prototype.bpGetValidLocations = function (filePath) { var retVal = []; if (exists("W_LOCAL.Graphs", this.jsonWU)) { var id_1 = ""; walkXmlJson(this.jsonWU.W_LOCAL.Graphs, function (key, item, _stack) { if (key === "$" && item.id) { id_1 = item.id; } if (key === "$" && item.name === "definition") { var match = /([a-z,A-Z]:\\(?:[-\w\.\d]+\\)*(?:[-\w\.\d]+)?|(?:\/[\w\.\-]+)+)\((\d*),(\d*)\)/.exec(item.value); if (match) { var file = match[1], row = match[2], _col = match[3]; var line = +row; var col = +_col; if (filePath === file) { retVal.push({ file: file, line: line, col: col, id: id_1 }); } } } // console.log(`${key}: ` + JSON.stringify(item)); }); } return retVal; }; return LocalWorkunit; }()); export { LocalWorkunit }; var ClientTools = /** @class */ (function () { function ClientTools(eclccPath, cwd, includeFolders, legacyMode, args, version) { if (includeFolders === void 0) { includeFolders = []; } if (legacyMode === void 0) { legacyMode = false; } if (args === void 0) { args = []; } this._paths = {}; this.eclccPath = eclccPath; this.binPath = path.dirname(this.eclccPath); this.envchkPath = path.join(this.binPath, "envchk" + exeExt); this.eclBundlePath = path.join(this.binPath, "ecl-bundle" + exeExt); this.cwd = path.normalize(cwd || this.binPath); this.includeFolders = includeFolders; this._legacyMode = legacyMode; this._args = args; this._version = version; } ClientTools.prototype.clone = function (cwd, includeFolders, legacyMode, args) { if (legacyMode === void 0) { legacyMode = false; } if (args === void 0) { args = []; } return new ClientTools(this.eclccPath, cwd, includeFolders, legacyMode, args, this._version); }; ClientTools.prototype.exists = function (filePath) { try { fs.accessSync(filePath); return true; } catch (e) { } return false; }; ClientTools.prototype.args = function (additionalItems) { if (additionalItems === void 0) { additionalItems = []; } var retVal = __spreadArray([], this._args, true); if (this._legacyMode) { retVal.push("-legacy"); } return retVal.concat(this.includeFolders.map(function (includePath) { return "-I" + path.normalize(includePath); })).concat(additionalItems); }; ClientTools.prototype.version = function () { var _this = this; if (this._version) { return Promise.resolve(this._version); } return this.execFile(this.eclccPath, this.binPath, this.args(["--version"]), "eclcc", "Cannot find ".concat(this.eclccPath)).then(function (response) { _this._version = new Version(response.stdout); return _this._version; }); }; ClientTools.prototype.versionSync = function () { return this._version; }; ClientTools.prototype.paths = function () { var _this = this; return this.execFile(this.eclccPath, this.cwd, this.args(["-showpaths"]), "eclcc", "Cannot find ".concat(this.eclccPath)).then(function (response) { if (response && response.stdout && response.stdout.length) { var paths = response.stdout.split(/\r?\n/); for (var _i = 0, paths_1 = paths; _i < paths_1.length; _i++) { var path_1 = paths_1[_i]; var parts = path_1.split("="); if (parts.length === 2) { _this._paths[parts[0]] = parts[1]; } } } return _this._paths; }); }; ClientTools.prototype.loadXMLDoc = function (filePath, removeOnRead) { return new Promise(function (resolve, _reject) { var fileData = fs.readFileSync(filePath, "ascii"); var retVal = xml2json(fileData); if (removeOnRead) { fs.unlink(filePath, function (err) { }); } resolve(retVal); }); }; ClientTools.prototype.createWU = function (filename) { var _this = this; var tmpName = tmp.tmpNameSync({ prefix: "eclcc-wu-tmp", postfix: "" }); var args = ["-o" + tmpName, "-wu"].concat([filename]); return this.execFile(this.eclccPath, this.cwd, this.args(args), "eclcc", "Cannot find ".concat(this.eclccPath)).then(function (_response) { var xmlPath = path.normalize(tmpName + ".xml"); var contentPromise = _this.exists(xmlPath) ? _this.loadXMLDoc(xmlPath, true) : Promise.resolve({}); return contentPromise.then(function (content) { return new LocalWorkunit(content); }); }); }; ClientTools.prototype.createArchive = function (filename) { var args = ["-E"].concat([filename]); return this.execFile(this.eclccPath, this.cwd, this.args(args), "eclcc", "Cannot find ".concat(this.eclccPath)).then(function (response) { return { content: response.stdout, err: new EclccErrors(response.stderr, []) }; }); }; ClientTools.prototype.attachWorkspace = function () { return attachWorkspace(this.cwd); }; ClientTools.prototype.fetchMeta = function (filePath) { return Promise.all([ attachWorkspace(this.cwd), this.execFile(this.eclccPath, this.cwd, this.args(["-M", filePath]), "eclcc", "Cannot find ".concat(this.eclccPath)) ]).then(function (_a) { var metaWorkspace = _a[0], execFileResponse = _a[1]; if (execFileResponse && execFileResponse.stdout && execFileResponse.stdout.length) { metaWorkspace.parseMetaXML(execFileResponse.stdout); } return metaWorkspace; }); }; ClientTools.prototype.syntaxCheck = function (filePath, args) { if (args === void 0) { args = ["-syntax"]; } return Promise.all([ attachWorkspace(this.cwd), this.execFile(this.eclccPath, this.cwd, this.args(__spreadArray(__spreadArray([], args, true), ["-M", filePath], false)), "eclcc", "Cannot find ".concat(this.eclccPath)) ]).then(function (_a) { var metaWorkspace = _a[0], execFileResponse = _a[1]; var checked = []; if (execFileResponse && execFileResponse.stdout && execFileResponse.stdout.length) { checked = metaWorkspace.parseMetaXML(execFileResponse.stdout); } return new EclccErrors(execFileResponse ? execFileResponse.stderr : "", checked); }); }; ClientTools.prototype.envCheck = function (filePath, args) { if (args === void 0) { args = []; } return Promise.all([ attachWorkspace(this.cwd), this.execFile(this.envchkPath, this.cwd, this.args(__spreadArray(__spreadArray([], args, true), [filePath], false)), "envchk", "Cannot find ".concat(this.envchkPath)) ]).then(function (_a) { var metaWorkspace = _a[0], execFileResponse = _a[1]; return new EnvchkErrors(filePath, execFileResponse ? execFileResponse.stderr : "", []); }); }; ClientTools.prototype.bundleList = function () { var _this = this; var bundlesRegEx = /\|(.*)\|(.*)\|(.*)\|/g; return Promise.all([ fetch("https://raw.githubusercontent.com/hpcc-systems/ecl-bundles/master/README.rst") .then(function (response) { return response.text(); }) .then(function (readme) { var retVal = []; var m = bundlesRegEx.exec(readme); while (m) { retVal.push({ name: m[1].trim(), description: m[2].trim(), url: m[3].trim() }); m = bundlesRegEx.exec(readme); } return retVal; }), this.execFile(this.eclBundlePath, this.cwd, this.args(["list"]), "ecl-bundle", "Cannot find ".concat(this.eclBundlePath)) .then(function (installedText) { return tidyCRLF(installedText.stdout).split("\n"); }).then(function (installedItems) { var allProps = {}; return Promise.all(installedItems.filter(function (ii) { return !!ii; }).map(function (ii) { return _this.execFile(_this.eclBundlePath, _this.cwd, _this.args(["info", ii]), "ecl-bundle", "Cannot find ".concat(_this.eclBundlePath)) .then(function (infoText) { return tidyCRLF(infoText.stdout).split("\n"); }).then(function (info) { var props = {}; info.forEach(function (line) { var parts = line.split(":"); props[parts.shift().trim()] = parts.join(":").trim(); }); allProps[ii] = { name: ii, props: props }; }); })).then(function () { return allProps; }); }) ]).then(function (_a) { var bundles = _a[0], installed = _a[1]; bundles.forEach(function (b) { if (installed[b.name]) { b.props = installed[b.name].props; delete installed[b.name]; } }); for (var key in installed) { bundles.push({ name: key, url: "", description: "", props: installed[key].props }); } return bundles; }).catch(function (e) { return []; }); }; ClientTools.prototype.bundleInstall = function (bundleUrl) { return Promise.all([ attachWorkspace(this.cwd), this.execFile(this.eclBundlePath, this.cwd, this.args(["install", bundleUrl]), "ecl-bundle", "Cannot find ".concat(this.eclBundlePath)) ]).then(function (_a) { var metaWorkspace = _a[0], execFileResponse = _a[1]; return execFileResponse; }); }; ClientTools.prototype.bundleUninstall = function (name) { return Promise.all([ attachWorkspace(this.cwd), this.execFile(this.eclBundlePath, this.cwd, this.args(["uninstall", name]), "ecl-bundle", "Cannot find ".concat(this.eclBundlePath)) ]).then(function (_a) { var metaWorkspace = _a[0], execFileResponse = _a[1]; return execFileResponse; }); }; ClientTools.prototype.execFile = function (cmd, cwd, args, _toolName, _notFoundError) { return new Promise(function (resolve, _reject) { logger.debug("".concat(cmd, " ").concat(args.join(" "))); var child = cp.spawn(cmd, args, { cwd: cwd }); var stdOut = ""; var stdErr = ""; child.stdout.on("data", function (data) { stdOut += data.toString(); }); child.stderr.on("data", function (data) { stdErr += data.toString(); }); child.on("close", function (_code, _signal) { resolve({ code: _code, stdout: stdOut.trim(), stderr: stdErr.trim() }); }); }); }; return ClientTools; }()); export { ClientTools }; function locateClientToolsInFolder(rootFolder, clientTools) { if (rootFolder) { var hpccSystemsFolder_1 = path.join(rootFolder, "HPCCSystems"); if (fs.existsSync(hpccSystemsFolder_1) && fs.statSync(hpccSystemsFolder_1).isDirectory()) { if (os.type() !== "Windows_NT") { var eclccPath = path.join(hpccSystemsFolder_1, "bin", "eclcc"); if (fs.existsSync(eclccPath)) { clientTools.push(new ClientTools(eclccPath)); } } fs.readdirSync(hpccSystemsFolder_1).forEach(function (versionFolder) { var eclccPath = path.join(hpccSystemsFolder_1, versionFolder, "clienttools", "bin", "eclcc" + exeExt); if (fs.existsSync(eclccPath)) { var name_1 = path.basename(versionFolder); var version = new Version(name_1); if (version.exists()) { clientTools.push(new ClientTools(eclccPath)); } } }); } } } var allClientToolsCache; export function clearAllClientToolsCache() { allClientToolsCache = undefined; } export function locateAllClientTools() { if (allClientToolsCache) return allClientToolsCache; var clientTools = []; switch (os.type()) { case "Windows_NT": var rootFolder86 = process.env["ProgramFiles(x86)"] || ""; if (rootFolder86) { locateClientToolsInFolder(rootFolder86, clientTools); } var rootFolder = process.env["ProgramFiles"] || ""; if (rootFolder) { locateClientToolsInFolder(rootFolder, clientTools); } if (!rootFolder86 && !rootFolder) { locateClientToolsInFolder("c:\\Program Files (x86)", clientTools); } break; case "Linux": case "Darwin": locateClientToolsInFolder("/opt", clientTools); break; default: break; } allClientToolsCache = Promise.all(clientTools.map(function (ct) { return ct.version(); })).then(function () { clientTools.sort(function (l, r) { return r.versionSync().compare(l.versionSync()); }); return clientTools; }); return allClientToolsCache; } var eclccPathMsg = ""; function logEclccPath(eclccPath) { var msg = "Using eclccPath setting: ".concat(eclccPath); if (eclccPathMsg !== msg) { logger.info(msg); eclccPathMsg = msg; } } export function locateClientTools(overridePath, build, cwd, includeFolders, legacyMode, args) { if (overridePath === void 0) { overridePath = ""; } if (build === void 0) { build = ""; } if (cwd === void 0) { cwd = "."; } if (includeFolders === void 0) { includeFolders = []; } if (legacyMode === void 0) { legacyMode = false; } if (args === void 0) { args = []; } if (overridePath && fs.existsSync(overridePath)) { logEclccPath(overridePath); return Promise.resolve(new ClientTools(overridePath, cwd, includeFolders, legacyMode, args)); } return locateAllClientTools().then(function (allClientToolsCache2) { if (!allClientToolsCache2.length) { throw new Error("Unable to locate ECL Client Tools."); } var buildVersion = new Version(build); var latest; var bestMajor; for (var _i = 0, allClientToolsCache2_1 = allClientToolsCache2; _i < allClientToolsCache2_1.length; _i++) { var ct = allClientToolsCache2_1[_i]; var ctVersion = ct.versionSync(); if (ctVersion.exists()) { if (!latest) latest = ct; if (!bestMajor && buildVersion.major === ctVersion.major) bestMajor = ct; if (buildVersion.major === ctVersion.major && buildVersion.minor === ctVersion.minor) return ct.clone(cwd, includeFolders, legacyMode, args); } } var best = bestMajor || latest; logEclccPath(best.eclccPath); return best.clone(cwd, includeFolders, legacyMode, args); }); } //# sourceMappingURL=eclcc.js.map