@hpcc-js/comms
Version:
hpcc-js - Communications
585 lines • 24.5 kB
JavaScript
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