summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes2
-rw-r--r--dist.ini1
-rw-r--r--lib/Getopt/Dakkar.pm8
-rw-r--r--notes.pl88
4 files changed, 99 insertions, 0 deletions
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..02be04b
--- /dev/null
+++ b/Changes
@@ -0,0 +1,2 @@
+{{$NEXT}}
+ - first
diff --git a/dist.ini b/dist.ini
index 5afd394..e656f9f 100644
--- a/dist.ini
+++ b/dist.ini
@@ -1,3 +1,4 @@
+name = Getopt-Dakkar
author = Gianni Ceccarelli <dakkar@thenautilus.net>
license = Perl_5
copyright_holder = Gianni Ceccarelli <dakkar@thenautilus.net>
diff --git a/lib/Getopt/Dakkar.pm b/lib/Getopt/Dakkar.pm
index 3875754..c3b9444 100644
--- a/lib/Getopt/Dakkar.pm
+++ b/lib/Getopt/Dakkar.pm
@@ -1 +1,9 @@
package Getopt::Dakkar;
+use strict;
+use warnings;
+use 5.026;
+use experimental qw(signatures postderef);
+# VERSION
+# ABSTRACT: the best command line parser ever
+
+1;
diff --git a/notes.pl b/notes.pl
new file mode 100644
index 0000000..d6bff3f
--- /dev/null
+++ b/notes.pl
@@ -0,0 +1,88 @@
+#!perl
+
+Getopt::Dakkar->new({
+ name => basename($0),
+ title => from_pod('NAME'),
+ synopsis => from_pod('SYNOPSIS'),
+
+ class => $a_class_name, #
+ object => $an_object, # at most one of these two is allowed
+ # maybe object should be passed to the ->run method, not here?
+ # but I like the idea of different options / parameters /
+ # subcommands having their own objects
+ op => $method, # optional
+
+ options => [
+ {
+ name => 'some-opt',
+ alias => [qw(s O)], # equivalent to switches => [qw(some-opt s O)],
+ type => Type::Tiny::something, # special cases for path, enum, bool
+ # 'counter' would be useful
+ # also, special cases for arrays and hashes
+ required => 1,
+ validate => \&foo, # defaults to the type::tiny assertion
+ complete_shell => \&cs, # auto-generated for path, enum, more?
+ complete => \&bar, # only if there's no complete_shell
+ op => $method, # optional
+ },
+ ...
+ ],
+
+ parameters => [
+ {
+ # like options, but no aliases / switches
+ },
+ ...
+ ],
+ # you can't have both parameters and subcommands
+ subcommands => [
+ {
+ # like top-level
+ },
+ ...
+ ],
+});
+
+=head1 LOGIC
+
+- options and parameters can optionally be mixed (like other getopts)
+- short options can optionally be bundled
+
+normal parsing: at each level:
+
+- shift @ARGV, match against "-$short_option" or "--$long_option", eat
+ argument if needed
+- if no match, and subcommands
+ - match against subcommands
+ - if no match, and we have a default/implied subcommands, assume that and recurse
+ - error out
+- if no match, and parameters
+ - match parameters positionally
+
+just before recursing (or at the end):
+
+- if we don't have a $state, init it with $object, or $class->new($argpack) ($class defaults to a hash-like thing that has a 'merge_with' method)
+- call $state->$op($argpack) ($op defaults to 'merge_with')
+- $argpack has a weakref to the Getopt::Dakkar object
+
+which means:
+
+- if no class/object/op is passed, at the end we have hash-like state
+ with all the arguments/optios merged in
+
+- if we only have an op at the last step, it will be invoked with all
+ the accumulated info
+
+- ops at different levels can do whatever they want
+
+shell completion:
+
+- the various complete_shell are put together into a big function
+- if there's a 'complete' (non-shell), the function will
+ GETOPT_DAKKAR_COMPLETE=1 $name "$@"
+ (the last word may be empty if we're TAB-ing after a IFS)
+- the program will parse normally
+ - on validation error, warn, ignore the failed argument, and carry on
+- then invoke the completion function $state->$complete($argpack)
+- and return to the shell everything that was returned
+ - check App::Spec trick to print more than what's completed