///|
#cfg(target="wasm")
fn runtime_exit(code : Int) -> Unit = "wasi_snapshot_preview1" "proc_exit"
///|
#cfg(target="native")
extern "c" fn runtime_exit(code : Int) -> Unit = "exit"
///|
async fn write_raw_cli_stdout(output : String) -> Unit {
if output != "" {
if output.strip_suffix("\n") is Some(_) {
@stdio.stdout.write(output)
} else {
@stdio.stdout.write(output + "\n")
}
}
}
///|
async fn write_raw_cli_stderr(output : String) -> Unit {
if output != "" {
if output.strip_suffix("\n") is Some(_) {
@stdio.stderr.write(output)
} else {
@stdio.stderr.write(output + "\n")
}
}
}
///|
#warnings("-alert_internal")
fn cli_errno_reason(errno : Int) -> String {
@os_error.errno_to_string(errno)
}
///|
async fn write_cli_stdout(output : String) -> Unit {
write_raw_cli_stdout(output) catch {
@os_error.OSError(errno, ..) =>
raise @cli.CliError::output_error(
"standard output",
cli_errno_reason(errno),
)
err => raise err
}
}
///|
async fn exit_with_cli_error(error : @cli.CliError) -> Unit {
let exit_code = error.exit_code()
write_raw_cli_stderr("\{error}") catch {
@os_error.OSError(_) => runtime_exit(7)
err => raise err
}
runtime_exit(exit_code)
}
///|
async fn run_cli() -> Unit {
let command = @cli.parse_cli_command(
@cli.runtime_cli_args(@env.args()),
env=@env.get_env_vars(),
)
match command {
Scan(options) => @cli.run_scan_command(options)
Lint(options) => @cli.run_lint_command(options)
DocsList | DocsShow(_) =>
write_cli_stdout(@cli.render_docs_command(command))
DumpImpl(..) | DumpExpr(..) =>
write_cli_stdout(@cli.render_dump_command(command))
}
}
///|
async fn main {
run_cli() catch {
@cli.CliError::Internal(..) as err => exit_with_cli_error(err)
@cli.CliError::Usage(..) as err => exit_with_cli_error(err)
@cli.CliError::DumpInput(..) as err => exit_with_cli_error(err)
@cli.CliError::RuleSource(..) as err => exit_with_cli_error(err)
@cli.CliError::RuleContent(..) as err => exit_with_cli_error(err)
@cli.CliError::ScanInput(..) as err => exit_with_cli_error(err)
@cli.CliError::Output(..) as err => exit_with_cli_error(err)
err => exit_with_cli_error(@cli.CliError::internal("\{err}"))
}
}