123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132(*---------------------------------------------------------------------------
Copyright (c) 2025 The more programmers. All rights reserved.
SPDX-License-Identifier: ISC
---------------------------------------------------------------------------*)openB0_stdopenCmdlineropenCmdliner.Term.SyntaxmoduleExit=structletecdoc=Cmd.Exit.info(Os.Exit.get_codec)~docletinfos=eOs.Exit.no_such_name"if a specified name does not exist."::Cmd.Exit.defaults(* FIXME remove this once we release Cmdliner with
Cmd.eval_value' *)letof_eval_result?(term_error=Os.Exit.cli_error)=function|Ok(`Oke)->e|Ok_->Os.Exit.ok|Error`Term->Os.Exit.cli_error|Error`Parse->Os.Exit.cli_error|Error`Exn->Os.Exit.internal_errorend(* Argument converters *)letpath=letparser=Fpath.of_stringandpp=Fpath.pp_unquotedinletcompletion=Arg.Completion.complete_pathsinArg.Conv.make~docv:"PATH"~parser~pp~completion()letfilepath=letparser=Fpath.of_stringandpp=Fpath.pp_unquotedinletcompletion=Arg.Completion.complete_filesinArg.Conv.make~docv:"FILE"~parser~pp~completion()letdirpath=letparser=Fpath.of_stringandpp=Fpath.pp_unquotedinletcompletion=Arg.Completion.complete_dirsinArg.Conv.make~docv:"DIR"~parser~pp~completion()letcmd=letparser=B0_std.Cmd.of_stringandpp=B0_std.Cmd.ppinletcompletion=Arg.Completion.complete_filesinArg.Conv.make~docv:"CMD"~parser~pp~completion()(* ANSI styling *)letno_color_var=letdoc="See $(opt). Enabled if set to anything but the empty string."inCmd.Env.info~doc"NO_COLOR"letno_color?(docs=Manpage.s_common_options)?(env=(Someno_color_var))()=letdoc="Disable ANSI text styling."in(* We can't use Arg.flag here because it doesn't parse
like https://no-color.org wants. *)letno_color=[true,Arg.info["no-color"]?env~doc~docs]inlet+no_color=Arg.(value&vflagfalseno_color)and+env=Term.envinletenv_no_color=functionNone|Some""->false|Some_->trueinno_color||env_no_color(env"NO_COLOR")letset_no_color?docs?env()=letsetno_color=ifno_colorthenFmt.set_stylerFmt.Plaininlet+no_color=no_color?docs?env()insetno_color(* Logging *)letlog_level_assoc=["quiet",Log.Quiet;"stdout",Log.Stdout;"stderr",Log.Stderr;"error",Log.Error;"warning",Log.Warning;"info",Log.Info;"debug",Log.Debug]letlog_level_conv=Arg.enum~docv:"LEVEL"log_level_assocletlog_level_var=Cmd.Env.info"LOG_LEVEL"letlog_level?(docs=Manpage.s_common_options)?(absent=Log.Warning)?(env=Somelog_level_var)()=letchoose~quiet~verbose~log_level=ifquietthenLog.Quietelsematchverbosewith|[]->Option.value~default:absentlog_level|[_]->ifabsent=Log.InfothenLog.DebugelseLog.Info|_->Log.Debuginlet+quiet=letdoc="Be quiet. Takes over $(b,-v) and $(b,--log-level)."inArg.(value&flag&info["q";"quiet"]~doc~docs)and+verbose=letdoc="Repeatable. Increase log verbosity. Once sets the log level to \
$(b,info), twice to $(b,debug), more does not bring more. Takes over \
$(b,--log-level)."(* The reason for taking over --log-level is due to cmdliner
limitation: we cannot distinguish in choose below if
verbosity was set via an env var. And cli args should always
take over env var. So verbosity set through the env var would
take over -v otherwise. *)inArg.(value&flag_all&info["v";"verbose"]~doc~docs)and+log_level=letdoc_alts=Arg.doc_alts_enumlog_level_associnletdoc=Fmt.str"Set log level to $(docv). Must be %s."doc_altsinletlevel=Arg.some'~none:absentlog_level_convinArg.(value&optlevelNone&info["log-level"]?env~doc~docs)inchoose~quiet~log_level~verboseletset_log_level?docs?absent?env()=let+log_level=log_level?docs?absent?env()inB0_std.Log.set_levellog_level(* Specifying output level of details *)typeoutput_details=[`Short|`Normal|`Long]lets_output_details_options="OUTPUT DETAILS OPTIONS"letoutput_details?(docs=s_output_details_options)()=letshort=letdoc="Short line-based output with essential details."inArg.info["s";"short"]~doc~docsinletlong=letdoc="Long output with as much details as possible."inArg.info["l";"long"]~doc~docsinArg.(value&vflag`Normal[`Short,short;`Long,long])