#![allow(dead_code)]
#![allow(clippy::print_stdout)]
use std::path::{Path, PathBuf};
use std::process::Command;
pub fn repository_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
}
pub fn answers(program: &Path) -> bool {
Command::new(program)
.arg("--version")
.output()
.is_ok_and(|output| output.status.success())
}
pub fn compiler() -> Option<PathBuf> {
if let Some(named) = std::env::var_os("ZERODDS_TSC") {
let named = PathBuf::from(named);
return answers(&named).then_some(named);
}
let local = repository_root().join("runtime/typescript/node_modules/.bin/tsc");
if answers(&local) {
return Some(local);
}
let on_path = PathBuf::from("tsc");
answers(&on_path).then_some(on_path)
}
pub fn compiler_or_note(what: &str) -> Option<PathBuf> {
if let Some(program) = compiler() {
return Some(program);
}
assert!(
std::env::var_os("CI").is_none(),
"no TypeScript compiler in a CI job: neither $ZERODDS_TSC nor \
runtime/typescript/node_modules/.bin/tsc nor `tsc` on PATH answers. \
ci/Dockerfile.rust installs typescript — rebuild the ci-rust image (the \
`ci-image` job) rather than leaving {what} unmeasured."
);
println!(
"SKIPPED: no `tsc` on this machine (name one with ZERODDS_TSC) — the generated \
TypeScript was not type-checked"
);
None
}
pub const STRICT_FLAGS: &[&str] = &[
"--ignoreConfig",
"--noEmit",
"--strict",
"--target",
"ES2022",
"--module",
"NodeNext",
"--moduleResolution",
"NodeNext",
"--skipLibCheck",
];
pub fn typecheck(tsc: &Path, name: &str, text: &str, extra: &[&str]) -> String {
let runtime = repository_root().join("runtime/typescript");
let scratch = runtime.join("dist-generated");
std::fs::create_dir_all(&scratch).expect("a directory for the generated file");
let path = scratch.join(format!("{name}.ts"));
std::fs::write(&path, text).expect("the generated file");
said(
Command::new(tsc)
.current_dir(&runtime)
.args(STRICT_FLAGS)
.args(extra)
.arg(&path),
)
}
pub fn said(command: &mut Command) -> String {
let output = command.output().expect("the TypeScript compiler runs");
format!(
"{}{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
)
}