Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions argparse/arg_group.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,28 @@ pub struct ArgGroup {
priv args : Array[String]
priv requires : Array[String]
priv conflicts_with : Array[String]

/// Create an argument group.
fn new(
name : StringView,
required? : Bool,
multiple? : Bool,
args? : ArrayView[String],
requires? : ArrayView[String],
conflicts_with? : ArrayView[String],
) -> ArgGroup
} derive(@debug.Debug)

///|
/// Create an argument group.
pub fn ArgGroup::ArgGroup(
name : StringView,
required? : Bool = false,
multiple? : Bool = true,
args? : ArrayView[String] = [],
requires? : ArrayView[String] = [],
conflicts_with? : ArrayView[String] = [],
) -> ArgGroup {
{
name: name.to_owned(),
required,
multiple,
args: args.to_owned(),
requires: requires.to_owned(),
conflicts_with: conflicts_with.to_owned(),
}
}

///|
/// Create an argument group.
///
Expand Down
165 changes: 117 additions & 48 deletions argparse/arg_spec.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,44 @@ priv enum ArgInfo {
/// Declarative flag constructor wrapper.
pub struct FlagArg {
priv arg : Arg

/// Create a flag argument.
fn new(
name : StringView,
short? : Char,
long? : StringView,
about? : StringView,
action? : FlagAction,
env? : StringView,
requires? : ArrayView[String],
conflicts_with? : ArrayView[String],
required? : Bool,
global? : Bool,
negatable? : Bool,
hidden? : Bool,
) -> FlagArg
} derive(@debug.Debug)

///|
/// Create a flag argument.
pub fn FlagArg::FlagArg(
name : StringView,
short? : Char,
long? : StringView = name,
about? : StringView,
action? : FlagAction = SetTrue,
env? : StringView,
requires? : ArrayView[String] = [],
conflicts_with? : ArrayView[String] = [],
required? : Bool = false,
global? : Bool = false,
negatable? : Bool = false,
hidden? : Bool = false,
) -> FlagArg {
let name = name.to_owned()
let long = if long == "" { None } else { Some(long.to_owned()) }
let about = about.map(v => v.to_owned())
let env = env.map(v => v.to_owned())
{
arg: {
name,
about,
env,
global,
hidden,
requires: requires.to_owned(),
conflicts_with: conflicts_with.to_owned(),
required,
info: FlagInfo(short~, long~, action~, negatable~),
multiple: false,
},
}
}

///|
/// Create a flag argument.
///
Expand Down Expand Up @@ -148,26 +168,52 @@ pub fn FlagArg::new(
/// Named `OptionArg` to avoid shadowing the built-in `Option` type.
pub struct OptionArg {
priv arg : Arg

/// Create an option argument.
// FIXME(upstram) rename does not work here
fn new(
name : StringView,
short? : Char,
long? : StringView,
about? : StringView,
action? : OptionAction,
env? : StringView,
default_values? : ArrayView[String],
allow_hyphen_values? : Bool,
requires? : ArrayView[String],
conflicts_with? : ArrayView[String],
required? : Bool,
global? : Bool,
hidden? : Bool,
) -> OptionArg
} derive(@debug.Debug)

///|
/// Create an option argument.
// FIXME(upstram) rename does not work here
pub fn OptionArg::OptionArg(
name : StringView,
short? : Char,
long? : StringView = name,
about? : StringView,
action? : OptionAction = Set,
env? : StringView,
default_values? : ArrayView[String],
allow_hyphen_values? : Bool = false,
requires? : ArrayView[String] = [],
conflicts_with? : ArrayView[String] = [],
required? : Bool = false,
global? : Bool = false,
hidden? : Bool = false,
) -> OptionArg {
let name = name.to_owned()
let long = if long == "" { None } else { Some(long.to_owned()) }
let about = about.map(v => v.to_owned())
let env = env.map(v => v.to_owned())
{
arg: {
name,
about,
env,
requires: requires.to_owned(),
conflicts_with: conflicts_with.to_owned(),
required,
global,
hidden,
info: OptionInfo(
short~,
long~,
action~,
default_values=default_values.map(values => values.to_owned()),
allow_hyphen_values~,
),
multiple: action is Append,
},
}
}

///|
/// Create an option argument.
///
Expand Down Expand Up @@ -224,22 +270,45 @@ pub fn OptionArg::new(
/// Declarative positional constructor wrapper.
pub struct PositionArg {
priv arg : Arg

/// Create a positional argument.
fn new(
name : StringView,
about? : StringView,
env? : StringView,
default_values? : ArrayView[String],
num_args? : ValueRange,
allow_hyphen_values? : Bool,
requires? : ArrayView[String],
conflicts_with? : ArrayView[String],
global? : Bool,
hidden? : Bool,
) -> PositionArg
} derive(@debug.Debug)

///|
/// Create a positional argument.
pub fn PositionArg::PositionArg(
name : StringView,
about? : StringView,
env? : StringView,
default_values? : ArrayView[String],
num_args? : ValueRange,
allow_hyphen_values? : Bool = false,
requires? : ArrayView[String] = [],
conflicts_with? : ArrayView[String] = [],
global? : Bool = false,
hidden? : Bool = false,
) -> PositionArg {
let name = name.to_owned()
let about = about.map(v => v.to_owned())
let env = env.map(v => v.to_owned())
{
arg: {
name,
about,
env,
requires: requires.to_owned(),
conflicts_with: conflicts_with.to_owned(),
required: false,
global,
hidden,
info: PositionalInfo(
num_args~,
default_values=default_values.map(values => values.to_owned()),
allow_hyphen_values~,
),
multiple: range_allows_multiple(num_args),
},
}
}

///|
/// Create a positional argument.
///
Expand Down
61 changes: 43 additions & 18 deletions argparse/command.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,51 @@ pub struct Command {
priv subcommand_required : Bool
priv hidden : Bool
priv mut build_error : ArgBuildError?

/// Create a declarative command specification.
fn new(
name : StringView,
flags? : ArrayView[FlagArg],
options? : ArrayView[OptionArg],
positionals? : ArrayView[PositionArg],
subcommands? : ArrayView[Command],
about? : StringView,
version? : StringView,
disable_help_flag? : Bool,
disable_version_flag? : Bool,
disable_help_subcommand? : Bool,
arg_required_else_help? : Bool,
subcommand_required? : Bool,
hidden? : Bool,
groups? : ArrayView[ArgGroup],
) -> Command
} derive(@debug.Debug)

///|
/// Create a declarative command specification.
pub fn Command::Command(
name : StringView,
flags? : ArrayView[FlagArg] = [],
options? : ArrayView[OptionArg] = [],
positionals? : ArrayView[PositionArg] = [],
subcommands? : ArrayView[Command] = [],
about? : StringView,
version? : StringView,
disable_help_flag? : Bool = false,
disable_version_flag? : Bool = false,
disable_help_subcommand? : Bool = false,
arg_required_else_help? : Bool = false,
subcommand_required? : Bool = false,
hidden? : Bool = false,
groups? : ArrayView[ArgGroup] = [],
) -> Command {
let (parsed_args, arg_error) = collect_args(flags, options, positionals)
let groups = groups.to_owned()
let cmd = Command::{
name: name.to_owned(),
args: parsed_args,
groups,
subcommands: subcommands.to_owned(),
about: about.map(v => v.to_owned()),
version: version.map(v => v.to_owned()),
disable_help_flag,
disable_version_flag,
disable_help_subcommand,
arg_required_else_help,
subcommand_required,
hidden,
build_error: arg_error,
}
if cmd.build_error is None {
validate_command(cmd, parsed_args, groups, []) catch {
err => cmd.build_error = Some(err)
}
}
cmd
}

///|
/// Create a declarative command specification.
///
Expand Down
26 changes: 26 additions & 0 deletions argparse/error.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,32 @@ impl Show for ArgError with output(self : ArgError, logger) {
}
}

///|
impl @debug.Debug for ArgError with to_repr(self) {
match self {
Message(msg) => @debug.Repr::literal(msg)
}
}

///|
test "ArgError debug keeps display text" {
let err : Error = ArgError::Message(
(
$|error: unexpected argument '--bad' found
$|
$|Usage: demo [options]
),
)
inspect(
err.to_string(),
content=(
#|error: unexpected argument '--bad' found
#|
#|Usage: demo [options]
),
)
}

///|
/// Internal parse error variants used while parsing.
priv suberror ArgParseError {
Expand Down
18 changes: 6 additions & 12 deletions argparse/pkg.generated.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ import {
// Types and methods
pub struct ArgGroup {
// private fields

fn new(StringView, required? : Bool, multiple? : Bool, args? : ArrayView[String], requires? : ArrayView[String], conflicts_with? : ArrayView[String]) -> ArgGroup
} derive(@debug.Debug)
pub fn ArgGroup::ArgGroup(StringView, required? : Bool, multiple? : Bool, args? : ArrayView[String], requires? : ArrayView[String], conflicts_with? : ArrayView[String]) -> Self
pub fn ArgGroup::new(StringView, required? : Bool, multiple? : Bool, args? : ArrayView[String], requires? : ArrayView[String], conflicts_with? : ArrayView[String]) -> Self

pub struct Command {
// private fields

fn new(StringView, flags? : ArrayView[FlagArg], options? : ArrayView[OptionArg], positionals? : ArrayView[PositionArg], subcommands? : ArrayView[Command], about? : StringView, version? : StringView, disable_help_flag? : Bool, disable_version_flag? : Bool, disable_help_subcommand? : Bool, arg_required_else_help? : Bool, subcommand_required? : Bool, hidden? : Bool, groups? : ArrayView[ArgGroup]) -> Command
} derive(@debug.Debug)
pub fn Command::Command(StringView, flags? : ArrayView[FlagArg], options? : ArrayView[OptionArg], positionals? : ArrayView[PositionArg], subcommands? : ArrayView[Self], about? : StringView, version? : StringView, disable_help_flag? : Bool, disable_version_flag? : Bool, disable_help_subcommand? : Bool, arg_required_else_help? : Bool, subcommand_required? : Bool, hidden? : Bool, groups? : ArrayView[ArgGroup]) -> Self
pub fn Command::new(StringView, flags? : ArrayView[FlagArg], options? : ArrayView[OptionArg], positionals? : ArrayView[PositionArg], subcommands? : ArrayView[Self], about? : StringView, version? : StringView, disable_help_flag? : Bool, disable_version_flag? : Bool, disable_help_subcommand? : Bool, arg_required_else_help? : Bool, subcommand_required? : Bool, hidden? : Bool, groups? : ArrayView[ArgGroup]) -> Self
#as_free_fn
pub fn Command::parse(Self, argv? : ArrayView[String], env? : Map[String, String]) -> Matches raise
Expand All @@ -37,9 +35,8 @@ pub(all) enum FlagAction {

pub struct FlagArg {
// private fields

fn new(StringView, short? : Char, long? : StringView, about? : StringView, action? : FlagAction, env? : StringView, requires? : ArrayView[String], conflicts_with? : ArrayView[String], required? : Bool, global? : Bool, negatable? : Bool, hidden? : Bool) -> FlagArg
} derive(@debug.Debug)
pub fn FlagArg::FlagArg(StringView, short? : Char, long? : StringView, about? : StringView, action? : FlagAction, env? : StringView, requires? : ArrayView[String], conflicts_with? : ArrayView[String], required? : Bool, global? : Bool, negatable? : Bool, hidden? : Bool) -> Self
pub fn FlagArg::new(StringView, short? : Char, long? : StringView, about? : StringView, action? : FlagAction, env? : StringView, requires? : ArrayView[String], conflicts_with? : ArrayView[String], required? : Bool, global? : Bool, negatable? : Bool, hidden? : Bool) -> Self

pub struct Matches {
Expand All @@ -58,23 +55,20 @@ pub(all) enum OptionAction {

pub struct OptionArg {
// private fields

fn new(StringView, short? : Char, long? : StringView, about? : StringView, action? : OptionAction, env? : StringView, default_values? : ArrayView[String], allow_hyphen_values? : Bool, requires? : ArrayView[String], conflicts_with? : ArrayView[String], required? : Bool, global? : Bool, hidden? : Bool) -> OptionArg
} derive(@debug.Debug)
pub fn OptionArg::OptionArg(StringView, short? : Char, long? : StringView, about? : StringView, action? : OptionAction, env? : StringView, default_values? : ArrayView[String], allow_hyphen_values? : Bool, requires? : ArrayView[String], conflicts_with? : ArrayView[String], required? : Bool, global? : Bool, hidden? : Bool) -> Self
pub fn OptionArg::new(StringView, short? : Char, long? : StringView, about? : StringView, action? : OptionAction, env? : StringView, default_values? : ArrayView[String], allow_hyphen_values? : Bool, requires? : ArrayView[String], conflicts_with? : ArrayView[String], required? : Bool, global? : Bool, hidden? : Bool) -> Self

pub struct PositionArg {
// private fields

fn new(StringView, about? : StringView, env? : StringView, default_values? : ArrayView[String], num_args? : ValueRange, allow_hyphen_values? : Bool, requires? : ArrayView[String], conflicts_with? : ArrayView[String], global? : Bool, hidden? : Bool) -> PositionArg
} derive(@debug.Debug)
pub fn PositionArg::PositionArg(StringView, about? : StringView, env? : StringView, default_values? : ArrayView[String], num_args? : ValueRange, allow_hyphen_values? : Bool, requires? : ArrayView[String], conflicts_with? : ArrayView[String], global? : Bool, hidden? : Bool) -> Self
pub fn PositionArg::new(StringView, about? : StringView, env? : StringView, default_values? : ArrayView[String], num_args? : ValueRange, allow_hyphen_values? : Bool, requires? : ArrayView[String], conflicts_with? : ArrayView[String], global? : Bool, hidden? : Bool) -> Self

pub struct ValueRange {
// private fields

fn new(lower? : Int, upper? : Int) -> ValueRange
} derive(Eq, Show, @debug.Debug)
pub fn ValueRange::ValueRange(lower? : Int, upper? : Int) -> Self
pub fn ValueRange::new(lower? : Int, upper? : Int) -> Self
pub fn ValueRange::single() -> Self

Expand Down
Loading
Loading