///|
fn normalize_args(args : Array[String]) -> ArrayView[String] {
let start = command_start(args)
args[start:]
}
///|
fn command_start(args : Array[String]) -> Int {
for i in 0.. Result[(String, String, Int), String] {
if args.length() >= 3 && !is_option_arg(args[1]) && !is_option_arg(args[2]) {
Ok((args[1].to_string(), args[2].to_string(), 3))
} else if args.length() >= 2 && !is_option_arg(args[1]) {
Err("error: \{error_message}")
} else {
Ok(("", "", 1))
}
}
///|
fn parse_optional_path(
args : ArrayView[String],
error_message : String,
) -> Result[(String, Int), String] {
if args.length() >= 2 && !is_option_arg(args[1]) {
if args.length() >= 3 && !is_option_arg(args[2]) {
Err("error: \{error_message}")
} else {
Ok((args[1].to_string(), 2))
}
} else {
Ok(("", 1))
}
}
///|
fn is_option_arg(value : String) -> Bool {
value.has_prefix("--")
}
///|
fn choose_configured_path(argument : String, configured : String) -> String {
if argument.length() > 0 {
argument
} else {
configured
}
}
///|
fn parse_report_options(
args : ArrayView[String],
start : Int,
) -> Result[ReportOptions, String] {
let mut format = "markdown"
let mut ignore_file = ""
let mut policy_file = ""
let mut policy_version = ""
let baseline = ""
let target = ""
let baseline_dir = ""
let target_dir = ""
let mut config_file = ""
let mut has_format = false
let mut has_ignore_file = false
let mut has_policy_file = false
let mut has_policy_version = false
let mut i = start
while i < args.length() {
let option = args[i]
if option == "--format" {
if i + 1 >= args.length() {
return Err("error: --format requires markdown or json")
}
match normalize_format(args[i + 1]) {
None => return Err("error: unsupported report format '\{args[i + 1]}'")
Some(value) => {
format = value
has_format = true
}
}
i += 2
} else if option == "--ignore-file" {
if i + 1 >= args.length() {
return Err("error: --ignore-file requires a path")
}
ignore_file = args[i + 1]
has_ignore_file = true
i += 2
} else if option == "--policy-file" {
if i + 1 >= args.length() {
return Err("error: --policy-file requires a path")
}
policy_file = args[i + 1]
has_policy_file = true
i += 2
} else if option == "--policy-version" {
if i + 1 >= args.length() {
return Err(
"error: --policy-version requires a major.minor.patch version",
)
}
policy_version = args[i + 1]
has_policy_version = true
i += 2
} else if option == "--config" {
if i + 1 >= args.length() {
return Err("error: --config requires a path")
}
config_file = args[i + 1]
i += 2
} else {
return Err("error: unknown option '\{option}'")
}
}
Ok({
format,
ignore_file,
policy_file,
policy_version,
baseline,
target,
baseline_dir,
target_dir,
config_file,
has_format,
has_ignore_file,
has_policy_file,
has_policy_version,
})
}
///|
fn parse_check_options(
args : ArrayView[String],
start : Int,
) -> Result[CheckOptions, String] {
let mut current = ""
let mut next = ""
let mut format = "markdown"
let mut ignore_file = ""
let mut policy_file = ""
let mut policy_version = ""
let baseline = ""
let target = ""
let baseline_dir = ""
let target_dir = ""
let mut config_file = ""
let mut has_current = false
let mut has_next = false
let mut has_format = false
let mut has_ignore_file = false
let mut has_policy_file = false
let mut has_policy_version = false
let mut i = start
while i < args.length() {
let option = args[i]
if option == "--current" {
if i + 1 >= args.length() {
return Err("error: --current requires a major.minor.patch version")
}
current = args[i + 1]
has_current = true
i += 2
} else if option == "--next" {
if i + 1 >= args.length() {
return Err("error: --next requires a major.minor.patch version")
}
next = args[i + 1]
has_next = true
if !has_policy_version {
policy_version = next
}
i += 2
} else if option == "--format" {
if i + 1 >= args.length() {
return Err("error: --format requires markdown or json")
}
match normalize_format(args[i + 1]) {
None => return Err("error: unsupported report format '\{args[i + 1]}'")
Some(value) => {
format = value
has_format = true
}
}
i += 2
} else if option == "--ignore-file" {
if i + 1 >= args.length() {
return Err("error: --ignore-file requires a path")
}
ignore_file = args[i + 1]
has_ignore_file = true
i += 2
} else if option == "--policy-file" {
if i + 1 >= args.length() {
return Err("error: --policy-file requires a path")
}
policy_file = args[i + 1]
has_policy_file = true
i += 2
} else if option == "--policy-version" {
if i + 1 >= args.length() {
return Err(
"error: --policy-version requires a major.minor.patch version",
)
}
policy_version = args[i + 1]
has_policy_version = true
i += 2
} else if option == "--config" {
if i + 1 >= args.length() {
return Err("error: --config requires a path")
}
config_file = args[i + 1]
i += 2
} else {
return Err("error: unknown option '\{option}'")
}
}
Ok({
current,
next,
format,
ignore_file,
policy_file,
policy_version,
baseline,
target,
baseline_dir,
target_dir,
config_file,
has_current,
has_next,
has_format,
has_ignore_file,
has_policy_file,
has_policy_version,
})
}
///|
fn normalize_format(value : String) -> String? {
if value == "markdown" || value == "md" {
Some("markdown")
} else if value == "json" {
Some("json")
} else {
None
}
}
///|
fn split_lines(text : StringView) -> Array[StringView] {
let lines : Array[StringView] = []
let mut start = 0
for i in 0..