App-Sqitch

 view release on metacpan or  search on metacpan

lib/App/Sqitch.pm  view on Meta::CPAN

    );
}

sub _parse_core_opts {
    my ( $self, $args ) = @_;
    my %opts;
    Getopt::Long::Configure(qw(bundling pass_through));
    Getopt::Long::GetOptionsFromArray(
        $args,
        map {
            ( my $k = $_ ) =~ s/[|=+:!].*//;
            $k =~ s/-/_/g;
            $_ => \$opts{$k};
        } $self->_core_opts
    ) or $self->_pod2usage('sqitchusage', '-verbose' => 99 );

    # Handle documentation requests.
    if ($opts{help} || $opts{man}) {
        $self->_pod2usage(
            $opts{help} ? 'sqitchcommands' : 'sqitch',
            '-exitval' => 0,
            '-verbose' => 2,
        );
    }

    # Handle version request.
    if ( delete $opts{version} ) {
        $self->emit( _bn($0), ' (', __PACKAGE__, ') ', __PACKAGE__->VERSION );
        exit;
    }

    # Handle --etc-path.
    if ( $opts{etc_path} ) {
        $self->emit( App::Sqitch::Config->class->system_dir );
        exit;
    }

    # Handle --chdir
    if ( my $dir = delete $opts{chdir} ) {
        chdir $dir or hurl fs => __x(
            'Cannot change to directory {directory}: {error}',
            directory => $dir,
            error   => $!,
        );
    }

    # Normalize the options (remove undefs) and return.
    $opts{verbosity} = delete $opts{verbose};
    $opts{verbosity} = 0 if delete $opts{quiet};
    delete $opts{$_} for grep { !defined $opts{$_} } keys %opts;
    return \%opts;
}

sub _find_cmd {
    my ( $class, $args ) = @_;
    my (@tried, $prev);
    for (my $i = 0; $i <= $#$args; $i++) {
        my $arg = $args->[$i] or next;
        if ($arg =~ /^-/) {
            last if $arg eq '--';
            # Skip the next argument if this looks like a pre-0.9999 option.
            # There shouldn't be many since we now recommend putting options
            # after the command. XXX Remove at some future date.
            $i++ if $arg =~ /^(?:-[duhp])|(?:--(?:db-\w+|client|engine|extension|plan-file|registry|top-dir))$/;
            next;
        }
        push @tried => $arg;
        my $cmd = try { App::Sqitch::Command->class_for($class, $arg) } or next;
        splice @{ $args }, $i, 1;
        return $cmd;
    }

    # No valid command found. Report those we tried.
    $class->vent(__x(
        '"{command}" is not a valid command',
        command => $_,
    )) for @tried;
    $class->_pod2usage('sqitchcommands');
}

sub _pod2usage {
    my ( $self, $doc ) = ( shift, shift );
    require App::Sqitch::Command::help;
    # Help does not need the Sqitch command; since it's required, fake it.
    my $help = App::Sqitch::Command::help->new( sqitch => bless {}, $self );
    $help->find_and_show( $doc || 'sqitch', '-exitval' => 2, @_ );
}

sub run {
    my $self = shift;
    local $SIG{__DIE__} = sub {
        ( my $msg = shift ) =~ s/\s+at\s+.+/\n/ms;
        hurl ipc => $msg;
    };
    if (ISWIN && IPC::System::Simple->VERSION < 1.28) {
        runx ( shift, $self->quote_shell(@_) );
        return $self;
    }
    runx @_;
    return $self;
}

sub shell {
    my ($self, $cmd) = @_;
    local $SIG{__DIE__} = sub {
        ( my $msg = shift ) =~ s/\s+at\s+.+/\n/ms;
        hurl ipc => $msg;
    };
    IPC::System::Simple::run $cmd;
    return $self;
}

sub quote_shell {
    my $self = shift;
    if (ISWIN) {
        require Win32::ShellQuote;
        return Win32::ShellQuote::quote_native(@_);
    }
    require String::ShellQuote;
    return String::ShellQuote::shell_quote(@_);
}

lib/App/Sqitch.pm  view on Meta::CPAN


=item C<user_email>

=item C<editor>

=item C<verbosity>

=back

=head2 Accessors

=head3 C<user_name>

=head3 C<user_email>

=head3 C<editor>

=head3 C<options>

  my $options = $sqitch->options;

Returns a hashref of the core command-line options.

=head3 C<config>

  my $config = $sqitch->config;

Returns the full configuration, combined from the project, user, and system
configuration files.

=head3 C<verbosity>

=head2 Instance Methods

=head3 C<run>

  $sqitch->run('echo', '-n', 'hello');

Runs a system command and waits for it to finish. Throws an exception on
error. Does not use the shell, so arguments must be passed as a list. Use
C<shell> to run a command and its arguments as a single string.

=over

=item C<target>

The name of the target, as passed.

=item C<uri>

A L<database URI|URI::db> object, to be used to connect to the target
database.


=item C<registry>

The name of the Sqitch registry in the target database.

=back

If the C<$target> argument looks like a database URI, it will simply returned
in the hash reference. If the C<$target> argument corresponds to a target
configuration key, the target configuration will be returned, with the C<uri>
value a upgraded to a L<URI> object. Otherwise returns C<undef>.

=head3 C<shell>

  $sqitch->shell('echo -n hello');

Shells out a system command and waits for it to finish. Throws an exception on
error. Always uses the shell, so a single string must be passed encapsulating
the entire command and its arguments. Use C<quote_shell> to assemble strings
into a single shell command. Use C<run> to execute a list without a shell.

=head3 C<quote_shell>

  my $cmd = $sqitch->quote_shell('echo', '-n', 'hello');

Assemble a list into a single string quoted for execution by C<shell>. Useful
for combining a specified command, such as C<editor()>, which might include
the options in the string, for example:

  $sqitch->shell( $sqitch->editor, $sqitch->quote_shell($file) );

=head3 C<capture>

  my @files = $sqitch->capture(qw(ls -lah));

Runs a system command and captures its output to C<STDOUT>. Returns the output
lines in list context and the concatenation of the lines in scalar context.
Throws an exception on error.

=head3 C<probe>

  my $git_version = $sqitch->capture(qw(git --version));

Like C<capture>, but returns just the C<chomp>ed first line of output.

=head3 C<spool>

  $sqitch->spool($sql_file_handle, 'sqlite3', 'my.db');
  $sqitch->spool(\@file_handles, 'sqlite3', 'my.db');

Like run, but spools the contents of one or ore file handle to the standard
input the system command. Returns true on success and throws an exception on
failure.

=head3 C<trace>

=head3 C<trace_literal>

  $sqitch->trace_literal('About to fuzzle the wuzzle.');
  $sqitch->trace('Done.');

Send trace information to C<STDOUT> if the verbosity level is 3 or higher.
Trace messages will have C<trace: > prefixed to every line. If it's lower than
3, nothing will be output. C<trace> appends a newline to the end of the
message while C<trace_literal> does not.

=head3 C<debug>



( run in 3.408 seconds using v1.01-cache-2.11-cpan-f56aa216473 )