]>
Dogcows Code - chaz/git-codeowners/blob - lib/App/Codeowners/Options.pm
1 package App
::Codeowners
::Options
;
2 # ABSTRACT: Getopt and shell completion for App::Codeowners
9 use Getopt
::Long
2.39 ();
12 our $VERSION = '0.49'; # VERSION
15 eval { require Pod
::Usage
};
17 my $ref = $VERSION eq '9999.999' ? 'master' : "v$VERSION";
18 my $exit = (@_ == 1 && $_[0] =~ /^\d+$/ && $_[0]) //
19 (@_ % 2 == 0 && {@_}->{'-exitval'}) // 2;
21 Online documentation is available at:
23 https://github.com/chazmcgarvey/git-codeowners/blob/$ref/README.md
25 Tip: To enable inline documentation, install the Pod::Usage module.
31 Pod
::Usage
::pod2usage
(@_);
37 'color|colour!' => (-t STDOUT
? 1 : 0), ## no critic (InputOutput::ProhibitInteractiveTest)
38 'format|f=s' => undef,
41 'shell-completion:s' => undef,
69 my @commands = sort keys %{$self->command_options};
76 if (my $command = $self->{command
}) {
77 @command_options = keys %{$self->command_options->{$command} || {}};
79 return (keys %{$self->early_options}, @command_options);
86 # assume UTF-8 args if non-ASCII
87 @args = map { decode
('UTF-8', $_) } @args if grep { /\P{ASCII}/ } @args;
89 my $self = bless {}, $class;
91 my @args_copy = @args;
93 my $opts = $self->get_options(
95 spec
=> $self->early_options,
96 config
=> 'pass_through',
99 if ($ENV{CODEOWNERS_COMPLETIONS
}) {
100 $self->{command
} = $args[0] || '';
101 my $cword = $ENV{CWORD
};
102 my $cur = $ENV{CUR
} || '';
103 # Adjust cword to remove progname
104 while (0 < --$cword) {
105 last if $cur eq ($args_copy[$cword] || '');
107 $self->completions($cword, @args_copy);
111 if ($opts->{version
}) {
112 my $progname = path
($0)->basename;
113 print "${progname} ${VERSION}\n";
117 pod2usage
(-exitval
=> 0, -verbose
=> 99, -sections
=> [qw(NAME SYNOPSIS OPTIONS COMMANDS)]);
119 if ($opts->{manual
}) {
120 pod2usage
(-exitval
=> 0, -verbose
=> 2);
122 if (defined $opts->{shell_completion
}) {
123 $self->shell_completion($opts->{shell_completion
});
127 # figure out the command (or default to "show")
128 my $command = shift @args;
129 my $command_options = $self->command_options->{$command || ''};
130 if (!$command_options) {
131 unshift @args, $command if defined $command;
133 $command_options = $self->command_options->{$command};
136 my $more_opts = $self->get_options(
138 spec
=> $command_options,
141 %$self = (%$opts, %$more_opts, command
=> $command, args
=> \
@args);
147 my $command = $self->{command
};
148 my @commands = sort keys %{$self->command_options};
149 return if not grep { $_ eq $command } @commands;
150 $command =~ s/[^a-z]/_/g;
156 return @{$self->{args
} || []};
162 my $args = {@_ == 1 && ref $_[0] eq 'HASH' ? %{$_[0]} : @_};
166 while (my ($opt, $default_value) = each %{$args->{spec
}}) {
167 my ($name) = $opt =~ /^([^=:!|]+)/;
169 $results{$name} = $default_value;
170 $options{$opt} = \
$results{$name};
173 if (my $fn = $args->{callback
}) {
174 $options{'<>'} = sub {
176 $fn->($arg, \
%results);
180 my $p = Getopt
::Long
::Parser-
>new;
181 $p->configure($args->{config
} || 'default');
182 return if !$p->getoptionsfromarray($args->{args
}, %options);
188 sub shell_completion
{
190 my $type = lc(shift || 'bash');
192 if ($type eq 'bash') {
194 # git-codeowners - Bash completion
195 # To use, eval this code:
196 # eval "$(git-codeowners --shell-completion)"
197 # This will work without the bash-completion package, but handling of colons
198 # in the completion word will work better with bash-completion installed and
201 local cur words cword
202 if declare -f _get_comp_words_by_ref >/dev/null
204 _get_comp_words_by_ref -n : cur cword words
206 words=("${COMP_WORDS[@]}")
211 COMPREPLY=($(CODEOWNERS_COMPLETIONS=1 CWORD="$cword" CUR="$cur" ${words[@]}))
212 # COMPREPLY=($(${words[0]} --completions "$cword" "${words[@]}"))
215 COMPREPLY=($(compgen -A "${COMPREPLY[0]}" -- "$cur"))
217 declare -f __ltrim_colon_completions >/dev/null && \
218 __ltrim_colon_completions "$cur"
221 complete -F _git_codeowners git-codeowners
225 # TODO - Would be nice to support Zsh
226 warn "No such shell completion: $type\n";
236 my $current = $words[$cword] || '';
237 my $prev = $words[$cword - 1] || '';
241 if ($prev eq '--format' || $prev eq '-f') {
242 $reply = $self->_completion_formats;
244 elsif ($current =~ /^-/) {
245 $reply = $self->_completion_options;
248 if (!$self->command) {
249 $reply = [$self->commands, @{$self->_completion_options([keys %{$self->early_options}])}];
258 print grep { /^\Q$current\E/ } @$reply;
262 sub _completion_options
{
264 my $opts = shift || [$self->options];
268 for my $option (@$opts) {
269 my ($names, $op, $vtype) = $option =~ /^([^=:!]+)([=:!]?)(.*)$/;
270 my @names = split(/\|/, $names);
272 for my $name (@names) {
274 push @options, "--$name", "--no-$name";
277 if (length($name) > 1) {
278 push @options, "--$name";
281 push @options, "-$name";
287 return [sort @options];
290 sub _completion_formats
{ [qw(csv json json:pretty tsv yaml)] }
302 App::Codeowners::Options - Getopt and shell completion for App::Codeowners
312 $options = $options->get_options(
314 spec => \@expected_options,
315 callback => sub { my ($arg, $results) = @_; ... },
318 Convert command-line arguments to options, based on specified rules.
320 Returns a hashref of options or C<undef> if an error occurred.
326 C<args> - Arguments from the caller (e.g. C<@ARGV>).
330 C<spec> - List of L<Getopt::Long> compatible option strings.
334 C<callback> - Optional coderef to call for non-option arguments.
338 C<config> - Optional L<Getopt::Long> configuration string.
342 =head2 shell_completion
344 $options->shell_completion($shell_type);
346 Print shell code to C<STDOUT> for the given type of shell. When eval'd, the shell code enables
347 completion for the F<git-codeowners> command.
351 $options->completions($current_arg_index, @args);
353 Print completions to C<STDOUT> for the given argument list and cursor position, and exit.
355 May also exit with status 9 and a compgen action printed to C<STDOUT> to indicate that the shell
356 should generate its own completions.
362 Please report any bugs or feature requests on the bugtracker website
363 L<https://github.com/chazmcgarvey/git-codeowners/issues>
365 When submitting a bug or request, please include a test-file or a
366 patch to an existing test-file that illustrates the bug or desired
371 Charles McGarvey <chazmcgarvey@brokenzipper.com>
373 =head1 COPYRIGHT AND LICENSE
375 This software is copyright (c) 2019 by Charles McGarvey.
377 This is free software; you can redistribute it and/or modify it under
378 the same terms as the Perl 5 programming language system itself.
This page took 0.054444 seconds and 5 git commands to generate.