2023-06-05 11:27:29 +00:00
|
|
|
import { toml } from "./dependencies.ts";
|
|
|
|
|
2023-07-30 15:57:38 +00:00
|
|
|
/**
|
|
|
|
* Check if a path exists by running {@linkcode Deno.stat} on it.
|
|
|
|
*/
|
2023-06-05 11:27:29 +00:00
|
|
|
export async function pathExists(path: string): Promise<boolean> {
|
|
|
|
try {
|
|
|
|
await Deno.stat(path);
|
|
|
|
return true;
|
|
|
|
} catch {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2022-12-09 11:26:08 +00:00
|
|
|
|
2023-07-30 15:57:38 +00:00
|
|
|
/**
|
|
|
|
* Run `JSON.stringify` with 2 spaces of indentation.
|
|
|
|
*/
|
2023-02-22 10:31:26 +00:00
|
|
|
export function stringifyJsonPretty(input: unknown): string {
|
|
|
|
return JSON.stringify(input, null, 2);
|
|
|
|
}
|
|
|
|
|
2023-07-30 15:57:38 +00:00
|
|
|
/**
|
|
|
|
* Run a command with by default inherited `stderr` and `stdout`.
|
|
|
|
*/
|
2023-06-07 13:43:02 +00:00
|
|
|
export async function runCommand(
|
|
|
|
command: string,
|
2023-06-07 13:43:59 +00:00
|
|
|
options: Deno.CommandOptions = {},
|
|
|
|
): Promise<void> {
|
|
|
|
await new Deno.Command(command, {
|
2023-06-07 13:43:02 +00:00
|
|
|
stderr: "inherit",
|
|
|
|
stdout: "inherit",
|
2023-06-07 13:43:59 +00:00
|
|
|
...options,
|
|
|
|
}).output();
|
2023-06-07 13:43:02 +00:00
|
|
|
}
|
|
|
|
|
2023-07-30 15:57:38 +00:00
|
|
|
/**
|
|
|
|
* Run a command and return its `stdout` output.
|
|
|
|
*/
|
2022-12-09 11:26:08 +00:00
|
|
|
export async function runAndReturnStdout(
|
2023-06-05 11:27:29 +00:00
|
|
|
command: string,
|
|
|
|
options: Deno.CommandOptions = {},
|
2022-12-09 11:26:08 +00:00
|
|
|
): Promise<string> {
|
2023-06-05 11:27:29 +00:00
|
|
|
const process = new Deno.Command(command, { stdout: "piped", ...options });
|
|
|
|
const { stdout } = await process.output();
|
|
|
|
return new TextDecoder().decode(stdout);
|
2022-12-09 11:26:08 +00:00
|
|
|
}
|
2023-01-11 14:39:51 +00:00
|
|
|
|
2023-07-29 19:12:14 +00:00
|
|
|
/**
|
|
|
|
* Parse the TOML frontmatter of a string, throwing an error if there is no
|
|
|
|
* frontmatter or returning the parsed frontmatter with the remaining text
|
|
|
|
* string. For example the following snippet:
|
|
|
|
*
|
|
|
|
* ```txt
|
|
|
|
* ---toml
|
|
|
|
* example_value = "Hello, world!"
|
|
|
|
* ---
|
|
|
|
*
|
|
|
|
* # Markdown
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* Will return:
|
|
|
|
*
|
|
|
|
* ```js
|
|
|
|
* [
|
|
|
|
* {
|
|
|
|
* example_value: "Hello, world!"
|
|
|
|
* },
|
|
|
|
* "# Markdown\n"
|
|
|
|
* ]
|
|
|
|
* ```
|
|
|
|
*/
|
2023-01-11 14:39:51 +00:00
|
|
|
export function tomlFrontmatter<T>(
|
|
|
|
data: string,
|
|
|
|
): [T, string] {
|
|
|
|
const startMarker = "---toml\n";
|
|
|
|
const endMarker = "\n---\n";
|
|
|
|
|
|
|
|
let start = data.indexOf(startMarker);
|
|
|
|
let end = data.indexOf(endMarker);
|
|
|
|
|
|
|
|
if (start === -1 || end === -1) {
|
|
|
|
throw new Error("Missing frontmatter");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (start !== 0) {
|
|
|
|
throw new Error("Frontmatter not at beginning of data");
|
|
|
|
}
|
|
|
|
|
|
|
|
start += startMarker.length;
|
|
|
|
const frontmatter = data.slice(start, end);
|
|
|
|
|
|
|
|
end += endMarker.length;
|
|
|
|
const extra = data.slice(end);
|
2023-02-26 11:34:26 +00:00
|
|
|
return [toml.parse(frontmatter) as T, extra.trimStart()];
|
2023-01-11 14:39:51 +00:00
|
|
|
}
|