Simplify JS wrapper function
This commit is contained in:
parent
d0dd65dde7
commit
b42818a2e7
|
@ -14,8 +14,8 @@ export interface IHyperbuildSettings {
|
||||||
verbose?: boolean;
|
verbose?: boolean;
|
||||||
|
|
||||||
code?: string | ReadableStream;
|
code?: string | ReadableStream;
|
||||||
inputFile?: string;
|
in?: string;
|
||||||
outputFile?: string;
|
out?: string;
|
||||||
|
|
||||||
suppress?: string[];
|
suppress?: string[];
|
||||||
|
|
||||||
|
@ -32,75 +32,53 @@ export interface IHyperbuildSettings {
|
||||||
MXtagWS?: boolean;
|
MXtagWS?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IHyperbuildMessage {
|
export type IHyperbuildMessage = IHyperbuildUnknownMessage | IHyperbuildDebugMessage | IHyperbuildInfoMessage | IHyperbuildWarnMessage | IHyperbuildFatalMessage;
|
||||||
|
|
||||||
|
export interface IHyperbuildUnknownMessage {
|
||||||
|
type: "UNKNOWN";
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HyperbuildUnknownMessage implements IHyperbuildMessage {
|
export interface IHyperbuildDebugMessage {
|
||||||
|
type: "DEBUG";
|
||||||
message: string;
|
message: string;
|
||||||
|
|
||||||
constructor (message: string) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HyperbuildDebugMessage implements IHyperbuildMessage {
|
export interface IHyperbuildInfoMessage {
|
||||||
|
type: "INFO";
|
||||||
message: string;
|
message: string;
|
||||||
|
|
||||||
constructor (message: string) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HyperbuildInfoMessage implements IHyperbuildMessage {
|
export interface IHyperbuildWarnMessage {
|
||||||
|
type: "WARN";
|
||||||
message: string;
|
message: string;
|
||||||
|
|
||||||
constructor (message: string) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HyperbuildWarnMessage implements IHyperbuildMessage {
|
export interface IHyperbuildFatalMessage {
|
||||||
|
type: "FATAL";
|
||||||
message: string;
|
message: string;
|
||||||
|
|
||||||
constructor (message: string) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class HyperbuildFatalMessage implements IHyperbuildMessage {
|
|
||||||
message: string;
|
|
||||||
|
|
||||||
constructor (message: string) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HyperbuildError extends Error {
|
export class HyperbuildError extends Error {
|
||||||
code: number;
|
code: number;
|
||||||
constructor (status: number, error: HyperbuildFatalMessage) {
|
constructor(status: number, message: string) {
|
||||||
super();
|
super();
|
||||||
this.code = status;
|
this.code = status;
|
||||||
this.message = `hyperbuild exited with status ${status} and encountered the following errors:\n\n${error.message}`;
|
this.message = `hyperbuild exited with status ${status} and encountered the following errors:\n\n${message}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IHyperbuildResult {
|
export interface IHyperbuildResult {
|
||||||
code?: string;
|
code?: string;
|
||||||
unknown: HyperbuildUnknownMessage[];
|
messages: {
|
||||||
debug: HyperbuildDebugMessage[];
|
unknown: IHyperbuildUnknownMessage[];
|
||||||
info: HyperbuildInfoMessage[];
|
debug: IHyperbuildDebugMessage[];
|
||||||
warnings: HyperbuildWarnMessage[];
|
info: IHyperbuildInfoMessage[];
|
||||||
|
};
|
||||||
|
warnings: IHyperbuildWarnMessage[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const MESSAGE_PREFIX_TO_CLASS_MAP: { [prefix: string]: new (message: string) => IHyperbuildMessage } = {
|
function processHyperbuildMessages(stderrOutput: string): IHyperbuildMessage[] {
|
||||||
"DEBUG": HyperbuildDebugMessage,
|
|
||||||
"INFO": HyperbuildInfoMessage,
|
|
||||||
"WARN": HyperbuildWarnMessage,
|
|
||||||
"FATAL": HyperbuildFatalMessage,
|
|
||||||
};
|
|
||||||
|
|
||||||
function processHyperbuildMessages (stderrOutput: string): IHyperbuildMessage[] {
|
|
||||||
let messages: IHyperbuildMessage[] = [];
|
let messages: IHyperbuildMessage[] = [];
|
||||||
|
|
||||||
// Be careful to keep messages intact, including keeping CR, LF, and CRLF differences
|
// Be careful to keep messages intact, including keeping CR, LF, and CRLF differences
|
||||||
|
@ -112,15 +90,20 @@ function processHyperbuildMessages (stderrOutput: string): IHyperbuildMessage[]
|
||||||
let prefixMatch = /^\[([A-Z]+)] /.exec(line);
|
let prefixMatch = /^\[([A-Z]+)] /.exec(line);
|
||||||
|
|
||||||
if (prefixMatch) {
|
if (prefixMatch) {
|
||||||
let cls = MESSAGE_PREFIX_TO_CLASS_MAP[prefixMatch[1]];
|
|
||||||
// Don't trim: it's possible trailing newline is part of message,
|
// Don't trim: it's possible trailing newline is part of message,
|
||||||
// and if message continues past newline, the newline is intentional
|
// and if message continues past newline, the newline is intentional
|
||||||
messages.push(new cls(line.slice(prefixMatch[0].length)));
|
messages.push({
|
||||||
|
type: prefixMatch[1],
|
||||||
|
message: line.slice(prefixMatch[0].length),
|
||||||
|
} as IHyperbuildMessage);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Assume if no prefix, line is continuation of previous message
|
// Assume if no prefix, line is continuation of previous message
|
||||||
if (!messages.length) {
|
if (!messages.length) {
|
||||||
messages.push(new HyperbuildUnknownMessage(line));
|
messages.push({
|
||||||
|
type: "UNKNOWN",
|
||||||
|
message: line,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
messages[messages.length - 1].message += line;
|
messages[messages.length - 1].message += line;
|
||||||
}
|
}
|
||||||
|
@ -132,107 +115,76 @@ function processHyperbuildMessages (stderrOutput: string): IHyperbuildMessage[]
|
||||||
|
|
||||||
const BIN_PATH = __dirname + "/hyperbuild";
|
const BIN_PATH = __dirname + "/hyperbuild";
|
||||||
|
|
||||||
function escapeOptionValue (val: string): string {
|
function escapeOptionValue(val: string): string {
|
||||||
return `'${val.replace(/'/g, "\\'")}'`;
|
return `'${val.replace(/'/g, "\\'")}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hyperbuild (settings: IHyperbuildSettings): Promise<IHyperbuildResult> {
|
function stringifyToArguments(args: object): string {
|
||||||
|
return Object.keys(args).map(k => {
|
||||||
|
let a = `--${k}`;
|
||||||
|
let v = args[k];
|
||||||
|
|
||||||
|
if (typeof v == "boolean") {
|
||||||
|
return v ? a : null;
|
||||||
|
|
||||||
|
} else if (typeof v == "string" || typeof v == "number") {
|
||||||
|
return `${a} ${escapeOptionValue(`${v}`)}`;
|
||||||
|
|
||||||
|
} else if (Array.isArray(v)) {
|
||||||
|
return !v.length ? null : `${a} ${escapeOptionValue(v.join(","))}`;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new TypeError(`Unknown argument value type for argument "${k}" with value: ${v}`);
|
||||||
|
}
|
||||||
|
}).join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hyperbuild(settings: IHyperbuildSettings): Promise<IHyperbuildResult> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let args = [];
|
let { showLogging, code, ...argsRaw } = settings;
|
||||||
|
let args = stringifyToArguments(argsRaw);
|
||||||
|
|
||||||
if (settings.keep) {
|
let cmd = `${BIN_PATH} ${args}`;
|
||||||
args.push("--keep");
|
|
||||||
}
|
|
||||||
if (settings.buffer) {
|
|
||||||
args.push("--buffer");
|
|
||||||
}
|
|
||||||
if (settings.verbose) {
|
|
||||||
args.push("--verbose");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.inputFile) {
|
|
||||||
args.push(`--in ${escapeOptionValue(settings.inputFile)}`);
|
|
||||||
args.push(`--out ${escapeOptionValue(settings.inputFile)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.suppress && settings.suppress.length) {
|
|
||||||
args.push(`--suppress ${escapeOptionValue(settings.suppress.join(","))}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.MXcollapseWhitespace && settings.MXcollapseWhitespace.length) {
|
|
||||||
args.push(
|
|
||||||
`--MXcollapseWhitespace ${escapeOptionValue(settings.MXcollapseWhitespace.join(","))}`);
|
|
||||||
}
|
|
||||||
if (settings.MXdestroyWholeWhitespace && settings.MXdestroyWholeWhitespace.length) {
|
|
||||||
args.push(
|
|
||||||
`--MXdestroyWholeWhitespace ${escapeOptionValue(settings.MXdestroyWholeWhitespace.join(","))}`);
|
|
||||||
}
|
|
||||||
if (settings.MXtrimWhitespace && settings.MXtrimWhitespace.length) {
|
|
||||||
args.push(
|
|
||||||
`--MXtrimWhitespace ${escapeOptionValue(settings.MXtrimWhitespace.join(","))}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.MXtrimClassAttr) {
|
|
||||||
args.push("--MXtrimClassAttr");
|
|
||||||
}
|
|
||||||
if (settings.MXdecEnt) {
|
|
||||||
args.push("--MXdecEnt");
|
|
||||||
}
|
|
||||||
if (settings.MXcondComments) {
|
|
||||||
args.push("--MXcondComments");
|
|
||||||
}
|
|
||||||
if (settings.MXattrQuotes) {
|
|
||||||
args.push("--MXattrQuotes");
|
|
||||||
}
|
|
||||||
if (settings.MXcomments) {
|
|
||||||
args.push("--MXcomments");
|
|
||||||
}
|
|
||||||
if (settings.MXoptTags) {
|
|
||||||
args.push("--MXoptTags");
|
|
||||||
}
|
|
||||||
if (settings.MXtagWS) {
|
|
||||||
args.push("--MXtagWS");
|
|
||||||
}
|
|
||||||
|
|
||||||
let code = settings.code;
|
|
||||||
|
|
||||||
let cmd = `${BIN_PATH} ${args.join(" ")}`;
|
|
||||||
|
|
||||||
let proc = shelljs.exec(cmd, {
|
let proc = shelljs.exec(cmd, {
|
||||||
async: true,
|
async: true,
|
||||||
silent: true,
|
silent: true,
|
||||||
}, (status, stdout, stderr) => {
|
}, (status, stdout, stderr) => {
|
||||||
if (settings.showLogging) {
|
if (showLogging) {
|
||||||
console.error(stderr);
|
console.error(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result: IHyperbuildResult = {
|
let result: IHyperbuildResult = {
|
||||||
code: code == undefined ? undefined : stdout,
|
code: code == undefined ? undefined : stdout,
|
||||||
unknown: [],
|
messages: {
|
||||||
debug: [],
|
unknown: [],
|
||||||
info: [],
|
debug: [],
|
||||||
|
info: [],
|
||||||
|
},
|
||||||
warnings: [],
|
warnings: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let message of processHyperbuildMessages(stderr)) {
|
for (let message of processHyperbuildMessages(stderr)) {
|
||||||
if (message instanceof HyperbuildFatalMessage) {
|
switch (message.type) {
|
||||||
reject(new HyperbuildError(status, message));
|
case "FATAL":
|
||||||
return;
|
reject(new HyperbuildError(status, message.message));
|
||||||
|
return;
|
||||||
|
|
||||||
} else if (message instanceof HyperbuildUnknownMessage) {
|
case "UNKNOWN":
|
||||||
result.unknown.push(message);
|
result.messages.unknown.push(message);
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (message instanceof HyperbuildDebugMessage) {
|
case "DEBUG":
|
||||||
result.debug.push(message);
|
result.messages.debug.push(message);
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (message instanceof HyperbuildInfoMessage) {
|
case "INFO":
|
||||||
result.info.push(message);
|
result.messages.info.push(message);
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (message instanceof HyperbuildWarnMessage) {
|
case "WARN":
|
||||||
result.warnings.push(message);
|
result.warnings.push(message);
|
||||||
|
break;
|
||||||
} else {
|
|
||||||
throw new Error(`INTERR Unknown message type with message: ${message}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"outDir": "out",
|
"outDir": "out",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"suppressImplicitAnyIndexErrors": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
|
|
Loading…
Reference in New Issue