ANN: Tackle.Opts - declarative command line arguments parser

I hope someone finds it useful:

Options:

with Ada.Text_IO;
with Tackle.Opts;

procedure Opts_Demo is
   use Ada;
   use Tackle;

   Options : constant Opts.Option_List := [Opts.Arg ("alpha", 'a', "Do alpha stuff"),
                                           Opts.Arg ("beta",  'b', "Do beta stuff"),
                                           Opts.Flag ("charlie", 'c', "Has charlie flag")];

   Arguments : constant Opts.Argument_List := Opts.Consume_Arguments;

   Result : constant Opts.Result := Opts.Parse (Arguments, Options);
begin
   --  Help is implicit unless provided
   if Result.Has_Flag ("help") then
      Opts.Print_Usage ("opts_demo", Options);

      return;
   end if;

   Text_IO.Put_Line ("Alpha: " & Result.Arg ("alpha"));
   Text_IO.Put_Line ("Beta: " & Result.Arg ("beta"));
   Text_IO.Put_Line ("Charlie?: " & Result.Has_Flag ("charlie")'Image);
end Opts_Demo;
$ ./opts_demo --help
Usage: opts_demo [options]

Options:
  --alpha, -a <alpha>   Do alpha stuff
  --beta, -b <beta>     Do beta stuff
  --charlie, -c         Has charlie flag
$ ./opts_demo --alpha Yes -b No --charlie
Alpha: Yes
Beta: No
Charlie?: TRUE

Commands:

procedure Opts_Demo is
   use Ada;
   use Tackle;

   Commands : constant Opts.Command_List := [Opts.Cmd ("alpha", "Do alpha stuff",
                                                       [Opts.Flag ("yes", 'y', "Yes?")]),
                                             Opts.Cmd ("beta", "Do beta stuff",
                                                       [Opts.Arg ("foo", 'f', "Foo!")], Passthrough => True)];

   Arguments : constant Opts.Argument_List := Opts.Consume_Arguments;

   Result : constant Opts.Result := Opts.Parse (Arguments, Commands);
begin
   --  Help is implicit unless provided
   if Result.Cmd = "" or else
      Result.Has_Flag ("help")
   then
      Opts.Print_Usage (Result.Cmd, "opts_demo", Commands);

      return;
   end if;

   if Result.Cmd = "beta" then
      Text_IO.Put_Line ("Passthrough args: " & Result.Passthrough_Args'Image);
   end if;
end Opts_Demo;
$ ./opts_demo --help
Usage: opts_demo <command> [options]

Commands:
  alpha   Do alpha stuff
  beta    Do beta stuff

Run 'opts_demo <command> --help' for command options
$ ./opts_demo beta --help
Usage: opts_demo beta [options] [-- <args>]

Options:
  --foo, -f <foo>   Foo!
  -- <args>         Passthrough arguments
$ ./opts_demo beta --foo Bar -- baz qux
Passthrough args:
["baz", "qux"]
6 Likes

This looks great! I’d prefer it to be in a separate crate, rather than a big crate of miscellaneous things.

2 Likes