///|
/// Output format selected by the command-line interface.
pub(all) enum OutputFormat {
Text
Json
Sarif
} derive(Debug, Eq)
///|
pub fn OutputFormat::label(self : OutputFormat) -> String {
match self {
Text => "text"
Json => "json"
Sarif => "sarif"
}
}
///|
/// Parsed Moon Doctor command-line options.
pub(all) struct CliOptions {
target : String
format : OutputFormat
strict : Bool
help : Bool
} derive(Debug, Eq)
///|
fn parse_format(value : String) -> OutputFormat? {
match value {
"text" => Some(Text)
"json" => Some(Json)
"sarif" => Some(Sarif)
_ => None
}
}
///|
fn parse_options_at(
args : Array[String],
index : Int,
format : OutputFormat,
strict : Bool,
target : String?,
help : Bool,
) -> Result[CliOptions, String] {
if index >= args.length() {
let resolved_target = match target {
Some(value) => value
None => "."
}
return Ok({ target: resolved_target, format, strict, help })
}
let arg = args[index]
match arg {
"--help" | "-h" =>
parse_options_at(args, index + 1, format, strict, target, true)
"--strict" => parse_options_at(args, index + 1, format, true, target, help)
"--format" =>
if index + 1 >= args.length() {
Err("--format requires text or json")
} else {
match parse_format(args[index + 1]) {
Some(next_format) =>
parse_options_at(args, index + 2, next_format, strict, target, help)
None => Err("unsupported format: " + args[index + 1])
}
}
_ =>
if arg.has_prefix("-") {
Err("unsupported option: " + arg)
} else {
match target {
None =>
parse_options_at(args, index + 1, format, strict, Some(arg), help)
Some(_) => Err("only one project path is supported")
}
}
}
}
///|
/// Parse process arguments, including the executable name at index zero.
pub fn parse_cli_args(args : Array[String]) -> Result[CliOptions, String] {
parse_options_at(args, 1, Text, false, None, false)
}
///|
/// Return the stable command-line usage text.
pub fn cli_usage() -> String {
let usage =
#|Usage: moon run cmd/main -- [--format text|json] [--strict] [path]
#|
#|Check a MoonBit project directory. The default path is the current directory.
#|
#|Options:
#| --format text|json Select a human-readable or machine-readable report.
#| --strict Exit with failure when ERROR or WARN diagnostics exist.
#| -h, --help Show this help text.
#|
usage
}
///|
/// Strict mode blocks release workflows on errors and warnings, not INFO advice.
pub fn should_fail_strict(options : CliOptions, report : DoctorReport) -> Bool {
options.strict && (report.score.errors > 0 || report.score.warnings > 0)
}