package Git::Class::Role::Execute;
use Moo::Role; with qw/
Git::Class::Role::Error
Git::Class::Role::Cwd
/;
use Capture::Tiny qw(capture tee);
use Scope::Guard ();
use Path::Tiny ();
sub _execute {
my ($self, @args) = @_;
@args = map { _quote($_) } @args;
if ($ENV{GIT_CLASS_TRACE}) {
print STDERR join ' ', @args, "\n";
}
my ($out, $err) = do {
# Capture::Tiny may confuse your web apps, so use it sparingly.
if (!defined wantarray or $self->no_capture) {
my $cwd = Path::Tiny->cwd;
my $guard = Scope::Guard::guard { chdir $cwd };
chdir $self->_cwd if $self->_cwd;
system(@args);
return ('', $?);
}
else {
local *capture = *tee if $self->is_verbose;
capture {
my $cwd = Path::Tiny->cwd();
my $guard = Scope::Guard::guard { chdir $cwd };
chdir $self->_cwd if $self->_cwd;
system(@args);
};
}
};
$self->_error($err) if $err;
wantarray ? split /\n/, $out : $out;
}
sub _get_options {
my ($self, @args) = @_;
my (%options, @left);
foreach my $arg (@args) {
if (ref $arg eq 'HASH') {
%options = (%options, %{ $arg });
}
else {
push @left, $arg;
}
}
return (\%options, @left);
}
sub _prepare_options {
my ($self, $options) = @_;
my @list;
foreach my $key (sort keys %{ $options }) {
my $value = $options->{$key};
$value = '' unless defined $value;
$key =~ s/_/\-/g;
if (length $key == 1) {
unshift @list, "-$key", ($value ne '' ? $value : ());
}
else {
unshift @list, "--$key".(($value ne '') ? "=$value" : '');
}
}
return @list;
}
sub _quote {
my $value = shift;
return '' unless defined $value;
return $$value if ref $value eq 'SCALAR';
my $option_name;
if ($value =~ s/^(\-\-[\w\-]+=)//) {
$option_name = $1;
}
my $org_value = $value;
if ($^O eq 'MSWin32') {
if ($org_value =~ /[\s^"<>&|!\(\)=;,]/) {
$value =~ s/\%/^\%/g;
$value =~ s/"/"""/g;
$value = qq{"$value"};
}
}
else {
require String::ShellQuote;
$value = String::ShellQuote::shell_quote_best_effort($value);
}
$value = $option_name . $value if $option_name;
return $value;
}
1;
__END__
=head1 NAME
Git::Class::Role::Execute
=head1 SYNOPSIS
=head1 DESCRIPTION
=head1 METHODS
=head1 AUTHOR
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2009 by Kenichi Ishigaki.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut