This file is indexed.

/usr/share/perl5/Prophet/CLI.pm is in libprophet-perl 0.750-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package Prophet::CLI;
use Any::Moose;

use Prophet;
use Prophet::Replica;
use Prophet::CLI::Command;
use Prophet::CLI::Dispatcher;
use Prophet::CLIContext;
use Prophet::Record;

use List::Util 'first';
use Text::ParseWords qw(shellwords);

has app_class => (
    is      => 'rw',
    isa     => 'ClassName',
    default => 'Prophet::App',
);

has dispatcher_class => (
    is      => 'rw',
    isa     => 'ClassName',
    lazy    => 1,
    default => sub {
        my $self = shift;

        my $app_class = $self->app_class;
        my $class = $app_class .'::CLI::Dispatcher';
        return $class if $app_class->try_to_require( $class );
        return 'Prophet::CLI::Dispatcher';
    },
);

has record_class => (
    is      => 'rw',
    isa     => 'ClassName',
    lazy    => 1,
    default => 'Prophet::Record',
);

has app_handle => (
    is      => 'rw',
    isa     => 'Prophet::App',
    lazy    => 1,
    handles => [qw/handle config/],
    default => sub {
        return $_[0]->app_class->new;
    },
);


has context => (
    is => 'rw',
    isa => 'Prophet::CLIContext',
    lazy => 1,
    default => sub {
        return Prophet::CLIContext->new( app_handle => shift->app_handle);
    }

);

has interactive_shell => ( 
    is => 'rw',
    isa => 'Bool',
    default => 0,
);

# default line length for CLI-related things that ought to wrap
use constant LINE_LENGTH => 80;

=head2 _record_cmd

handles the subcommand for a particular type

=cut

=head2 dispatcher_class -> Class

Returns class name of the dispatcher used to dispatch command lines.
By default app_class::CLI::Dispatcher is used if it can be loaded
otherwise L<Prophet::CLI::Dispatcher>. Override using:

    has '+dispatcher_class' => ( default => 'MyApp::Dispatcher' );

=head2 run_one_command

Runs a command specified by commandline arguments given in an
ARGV-like array of argumnents and key value pairs . To use in a
commandline front-end, create a L<Prophet::CLI> object and pass in
your main app class as app_class, then run this routine.

Example:

 my $cli = Prophet::CLI->new({ app_class => 'App::SD' });
 $cli->run_one_command(@ARGV);

=cut

sub run_one_command {
    my $self = shift;
    my @args = (@_);

    # find the first alias that matches, rerun the aliased cmd
    # note: keys of aliases are treated as regex, 
    # we need to substitute $1, $2 ... in the value if there's any
    my $ori_cmd = join ' ', @args;

    if ($self->app_handle->local_replica_url) {
        my $aliases = $self->app_handle->config->aliases;
        while (my ($alias, $replacement) = each %$aliases ) {
            my $command = $self->_command_matches_alias(
                \@args, $alias, $replacement,
               ) || next;

            # we don't want to recursively call if people stupidly write
            # alias pull --local = pull --local
            next if ( join(' ', @$command) eq $ori_cmd );
            return $self->run_one_command(@$command);
        }
    }
    #  really, we shouldn't be doing this stuff from the command dispatcher
    $self->context( Prophet::CLIContext->new( app_handle => $self->app_handle ) );
    $self->context->setup_from_args(@args);
    my $dispatcher = $self->dispatcher_class->new;

    # Path::Dispatcher is string-based, so we need to join the args
    # hash with spaces before passing off (args with whitespace in
    # them are quoted, double quotes are escaped)
    my $dispatch_command_string = join(' ', map {
            s/"/\\"/g;  # escape double quotes
            /\s/ ? qq{"$_"} : $_;
        } @{ $self->context->primary_commands });

    local $Prophet::CLI::Dispatcher::cli = $self;
    my $dispatch = $dispatcher->dispatch( $dispatch_command_string );
    $self->start_pager();
    $dispatch->run($dispatcher);
    $self->end_pager();
}

sub _command_matches_alias {
    my $self  = shift;
    my @words = @{+shift};
    my @alias = shellwords(shift);
    my @expansion = shellwords(shift);

    # Compare @words against @alias
    return if(scalar(@words) < scalar(@alias));

    while(@alias) {
        if(shift @words ne shift @alias) {
            return;
        }
    }

    # @words now contains the remaining words given on the
    # command-line, and @expansion contains the words in the
    # expansion.

    if (first sub {m{\$\d+\b}}, @expansion) {
        # Expand $n placeholders
        for (@expansion) {
            s/\$(\d+)\b/$words[$1 - 1]||""/ge;
        }
        return [@expansion];
    } else {
        return [@expansion, @words];
    }
}

sub is_interactive {
  return -t STDIN && -t STDOUT;
}

sub get_pager {
    my $self = shift;
    return $ENV{'PAGER'} || `which less` || `which more`;
}

our $ORIGINAL_STDOUT;

sub start_pager {
    my $self = shift;
    my $content = shift;
    if (is_interactive() && !$ORIGINAL_STDOUT) {
        local $ENV{'LESS'} ||= '-FXe';
        local $ENV{'MORE'};
        $ENV{'MORE'} ||= '-FXe' unless $^O =~ /^MSWin/;

        my $pager = $self->get_pager();
        return unless $pager;
        open (my $cmd, "|-", $pager) || return;
        $|++;
        $ORIGINAL_STDOUT = *STDOUT;

        # $pager will be closed once we restore STDOUT to $ORIGINAL_STDOUT
        *STDOUT = $cmd;
    }
}

sub in_pager {
    return $ORIGINAL_STDOUT ? 1 :0;
}

sub end_pager {
    my $self = shift;
    return unless ($self->in_pager);
    *STDOUT = $ORIGINAL_STDOUT ;

    # closes the pager
    $ORIGINAL_STDOUT = undef;
}

=head2 get_script_name

Return the name of the script that was run. This is the empty string
if we're in a shell, otherwise the script name concatenated with
a space character. This is so you can just use this for e.g.
printing usage messages or help docs that might be run from either
a shell or the command line.

=cut

sub get_script_name {
    my $self = shift;
    return '' if $self->interactive_shell;
    require File::Spec;
    my ($cmd) = ( File::Spec->splitpath($0) )[2];
    return $cmd . ' ';
}

END {
   *STDOUT = $ORIGINAL_STDOUT if $ORIGINAL_STDOUT;
}

__PACKAGE__->meta->make_immutable;
no Any::Moose;

1;