CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/project/formatters/gofmt.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { callback } from "awaiting";
7
import { spawn } from "child_process";
8
import { readFile, unlink, writeFile } from "node:fs";
9
import * as tmp from "tmp";
10
11
import { Options } from "./index";
12
13
function close(proc, cb): void {
14
proc.on("close", (code) => cb(undefined, code));
15
}
16
17
// ref: https://golang.org/cmd/gofmt/ ... but there isn't anything to configure
18
19
function run_gofmt(input_path: string) {
20
const args = ["-w", input_path];
21
return spawn("gofmt", args);
22
}
23
24
function cleanup_error(err: string, tmpfn: string): string {
25
const ret: string[] = [];
26
for (let line of err.split("\n")) {
27
if (line.startsWith(tmpfn)) {
28
line = line.slice(tmpfn.length + 1);
29
}
30
ret.push(line);
31
}
32
return ret.join("\n");
33
}
34
35
export async function gofmt(
36
input: string,
37
options: Options,
38
logger: any
39
): Promise<string> {
40
// create input temp file
41
const input_path: string = await callback(tmp.file);
42
try {
43
// logger.debug(`gofmt tmp file: ${input_path}`);
44
await callback(writeFile, input_path, input);
45
46
// spawn the html formatter
47
let formatter;
48
49
switch (options.parser) {
50
case "gofmt":
51
formatter = run_gofmt(input_path /*, logger*/);
52
break;
53
default:
54
throw Error(`Unknown Go code formatting utility '${options.parser}'`);
55
}
56
// stdout/err capture
57
let stdout: string = "";
58
let stderr: string = "";
59
// read data as it is produced.
60
formatter.stdout.on("data", (data) => (stdout += data.toString()));
61
formatter.stderr.on("data", (data) => (stderr += data.toString()));
62
// wait for subprocess to close.
63
const code = await callback(close, formatter);
64
if (code >= 1) {
65
stdout = cleanup_error(stdout, input_path);
66
stderr = cleanup_error(stderr, input_path);
67
const err_msg = `Gofmt code formatting utility "${options.parser}" exited with code ${code}\nOutput:\n${stdout}\n${stderr}`;
68
logger.debug(`gofmt error: ${err_msg}`);
69
throw Error(err_msg);
70
}
71
72
// all fine, we read from the temp file
73
const output: Buffer = await callback(readFile, input_path);
74
const s: string = output.toString("utf-8");
75
// logger.debug(`gofmt_format output s ${s}`);
76
77
return s;
78
} finally {
79
unlink(input_path, () => {});
80
}
81
}
82
83