UNPKG

@cocalc/project

Version:
78 lines 3.07 kB
"use strict"; /* * This file is part of CoCalc: Copyright © 2020 Sagemath, Inc. * License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details */ Object.defineProperty(exports, "__esModule", { value: true }); exports.python_format = void 0; const fs_1 = require("fs"); const tmp_1 = require("tmp"); const awaiting_1 = require("awaiting"); const child_process_1 = require("child_process"); function close(proc, cb) { proc.on("close", (code) => cb(undefined, code)); } // TODO: diversify this via options to support autopep8, black (requires python 3.6), and others... function yapf(input_path) { return (0, child_process_1.spawn)("yapf", ["-i", input_path]); } // from a full stacktrace, only show user the last line (encodes some reason and line number) ... everything else does not help. function tail(str, lines = 4) { if (str == null) { return "Problem running formatter."; } else { return (str .trim() .split(/\r?\n/) .slice(-lines) .filter((x) => x.trim().length > 0) .join("\n") || ""); } } async function python_format(input, options, logger) { // create input temp file const input_path = await (0, awaiting_1.callback)(tmp_1.file); try { await (0, awaiting_1.callback)(fs_1.writeFile, input_path, input); // spawn the python formatter const util = options.util || "yapf"; if (util !== "yapf") { throw new Error("This project only supports 'yapf' for formatting Python"); } const py_formatter = yapf(input_path); py_formatter.on("error", (err) => { // ATTN do not throw an error here, because this is triggered by the subprocess! logger.debug(`Formatting utility exited with error no ${err.errno}`); }); // stdout/err capture let stdout = ""; let stderr = ""; // read data as it is produced. py_formatter.stdout.on("data", (data) => (stdout += data.toString())); py_formatter.stderr.on("data", (data) => (stderr += data.toString())); // wait for subprocess to close. const code = await (0, awaiting_1.callback)(close, py_formatter); // only last line // stdout = last_line(stdout); if (code) { if (code === -2) { // ENOENT throw new Error(`Formatting utility "${util}" is not installed`); } stderr = tail(stderr); const err_msg = `Python formatter "${util}" exited with code ${code}:\n${stdout}\n${stderr}`; logger.debug(`format python error: ${err_msg}`); throw new Error(err_msg); } // all fine, we read from the temp file const output = await (0, awaiting_1.callback)(fs_1.readFile, input_path); const s = output.toString("utf-8"); return s; } finally { (0, fs_1.unlink)(input_path, () => { }); } } exports.python_format = python_format; //# sourceMappingURL=python-format.js.map