UNPKG

@cocalc/project

Version:
63 lines (53 loc) 1.81 kB
/* * This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. * License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details */ import { writeFile, readFile, unlink } from "fs"; import { file } from "tmp"; import { callback } from "awaiting"; import { spawn } from "child_process"; interface ParserOptions { parser?: string; tabWidth?: number; lineWidth?: number; } function close(proc, cb): void { proc.on("close", (code) => cb(undefined, code)); } function formatR(input_path: string) { // in-place is fine, according to my tests const expr = `suppressMessages(require(formatR)); tidy_source(source="${input_path}", file="${input_path}", indent=2, width.cutoff=80)`; return spawn("R", ["--quiet", "--vanilla", "--no-save", "-e", expr]); } export async function r_format( input: string, _: ParserOptions, logger: any ): Promise<string> { // create input temp file const input_path: string = await callback(file); try { await callback(writeFile, input_path, input); // spawn the R formatter const r_formatter = formatR(input_path); // stdout/err capture let stdout: string = ""; let stderr: string = ""; // read data as it is produced. r_formatter.stdout.on("data", (data) => (stdout += data.toString())); r_formatter.stderr.on("data", (data) => (stderr += data.toString())); // wait for subprocess to close. const code = await callback(close, r_formatter); if (code) { const err_msg = `${stderr}`; logger.debug(`R_FORMAT ${err_msg}`); throw new Error(err_msg); } // all fine, we read from the temp file const output: Buffer = await callback(readFile, input_path); const s: string = output.toString("utf-8"); return s; } finally { unlink(input_path, () => {}); } }