MichaReiser/speedy.js

View on GitHub
packages/compiler/src/external-tools/tools.ts

Summary

Maintainability
A
0 mins
Test Coverage
import * as child_process from "child_process";
import * as debug from "debug";
import * as path from "path";
import * as ts from "typescript";

const CONFIGURATION_FILE = path.normalize(path.join(__dirname, "../../tools/configuration.json"));

const log = debug("external-tools/tools");
let llvmBinDir: string | undefined;

interface ToolsConfiguration {
    LLVM_CONFIG: string;
    BINARYEN: string;
}

/**
 * Returns the path where the llvm executables are located
 */
export function getConfiguration(): ToolsConfiguration {
    if (!ts.sys.fileExists(CONFIGURATION_FILE)) {
        throw new Error(`The configuration file '${CONFIGURATION_FILE} for the installations does not exist. Install the package again`);
    }

    const content = ts.sys.readFile(CONFIGURATION_FILE);
    return JSON.parse(content) as ToolsConfiguration;
}

function getLLVMBinDirectory() {
    if (!llvmBinDir) {
        llvmBinDir = execute(getConfiguration().LLVM_CONFIG, ["--bindir"]).trim();
    }

    return llvmBinDir;
}

/**
 * executes a llvm tool
 * @param tool the name of the binary
 * @param args the arguments to pass
 * @param cwd optionally, the working directory where the command is to be executed
 * @return {string} the result of executing this command
 */
export function execLLVM(tool: string, args: string[], cwd?: string): string {
    const toolPath = path.join(getLLVMBinDirectory(), tool);

    if (!ts.sys.fileExists(toolPath)) {
        throw new Error(`LLVM executable ${toolPath} is missing`);
    }

    return execute(toolPath, args, cwd);
}

/**
 * Executes a binaryen command
 * @param tool the name of the binaryen executable
 * @param args the arguments to pass
 * @return {string} the output of the execution
 */
export function execBinaryen(tool: string, args: string[]): string {
    const binaryenPath = path.resolve(`${__dirname}/../../`, getConfiguration().BINARYEN);
    const toolPath = path.join(binaryenPath, "bin", tool);

    if (!ts.sys.fileExists(toolPath)) {
        throw new Error(`BINARYEN executable ${toolPath} is missing`);
    }

    return execute(toolPath, args);
}

function execute(tool: string, args: string[], cwd?: string) {
    const env = Object.create(process.env);
    const command = `${tool} ${args}`;

    log(`Execute command '${command}'`);
    const output = child_process.execFileSync(tool, args, { env, cwd });

    return outputToString(output);
}

function outputToString(output: string | Buffer): string {
    if (typeof(output) === "string") {
        return output;
    }

    return output.toString("utf-8");
}