This file is indexed.

/usr/share/perl5/App/Cleo.pm is in cleo 0.004-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
package App::Cleo;

use strict;
use warnings;

use Term::ReadKey;
use Term::ANSIColor qw(colored);
use File::Slurp qw(read_file);
use Time::HiRes qw(usleep);

our $VERSION = 0.004;

#-----------------------------------------------------------------------------

sub new {
    my $class = shift;

    my $self = {
        shell  => $ENV{SHELL} || '/bin/bash',
        prompt => colored( ['green'], '(%d)$ '),
        delay  => 25_000,
        @_,
    };

    return bless $self, $class;
}

#-----------------------------------------------------------------------------

sub run {
    my ($self, $commands) = @_;

    my $type = ref $commands;
    my @commands = !$type ? read_file($commands)
        : $type eq 'SCALAR' ? split "\n", ${$commands}
            : $type eq 'ARRAY' ? @{$commands}
                : die "Unsupported type: $type";

    open my $fh, '|-', $self->{shell} or die $!;
    $self->{fh} = $fh;
    ReadMode('raw');
    local $| = 1;

    chomp @commands;
    @commands = grep { /^\s*[^\#;]\S+/ } @commands;

    CMD:
    for (my $i = 0; $i < @commands; $i++) {

        my $cmd = $commands[$i];
        chomp $cmd;

        $self->do_cmd($cmd) and next CMD
            if $cmd =~ s/^!!!//;

        print sprintf $self->{prompt}, $i;

        my @steps = split /%%%/, $cmd;
        while (my $step = shift @steps) {

            my $key = ReadKey(0);
            print "\n" if $key =~ m/[srp]/;

            last CMD       if $key eq 'q';
            next CMD       if $key eq 's';
            redo CMD       if $key eq 'r';
            $i--, redo CMD if $key eq 'p';

            $step .= ' ' if not @steps;
            my @chars = split '', $step;
            print and usleep $self->{delay} for @chars;
        }

        my $key = ReadKey(0);
        print "\n";

        last CMD       if $key eq 'q';
        next CMD       if $key eq 's';
        redo CMD       if $key eq 'r';
        $i--, redo CMD if $key eq 'p';

        $self->do_cmd($cmd);
    }

    ReadMode('restore');
    print "\n";

    return $self;
}

#-----------------------------------------------------------------------------

sub do_cmd {
    my ($self, $cmd) = @_;

    my $cmd_is_finished;
    local $SIG{ALRM} = sub {$cmd_is_finished = 1};

    $cmd =~ s/%%%//g;
    my $fh = $self->{fh};

    print $fh "$cmd\n";
    print $fh "kill -14 $$\n";
    $fh->flush;

    # Wait for signal that command has ended
    until ($cmd_is_finished) {}
    $cmd_is_finished = 0;

    return 1;
}

#-----------------------------------------------------------------------------
1;

=pod

=head1 NAME

App::Cleo - Play back shell commands for live demonstrations

=head1 SYNOPSIS

  use App::Cleo
  my $cleo = App::Cleo->new(%options);
  $cleo->run($commands);

=head1 DESCRIPTION

App::Cleo is the back-end for the L<cleo> utility.  Please see the L<cleo>
documentation for details on how to use this.

=head1 CONSTRUCTOR

The constructor accepts arguments as key-value pairs.  The following keys are
supported:

=over 4

=item delay

Number of milliseconds to wait before displaying each character of the command.
The default is C<25_000>.

=item prompt

String to use for the artificial prompt.  The token C<%d> will be substituted
with the number of the current command.  The default is C<(%d)$>.

=item shell

Path to the shell command that will be used to run the commands.  Defaults to
either the C<SHELL> environment variable or C</bin/bash>.

=back

=head1 METHODS

=over 4

=item run( $commands )

Starts playback of commands.  If the argument is a string, it will be treated
as a file name and commands will be read from the file. If the argument is a
scalar reference, it will be treated as a string of commands separated by
newlines.  If the argument is an array reference, then each element of the
array will be treated as a command.

=back

=head1 AUTHOR

Jeffrey Ryan Thalhammer <thaljef@cpan.org>

=head1 COPYRIGHT

Copyright (c) 2014, Imaginative Software Systems

=cut