Gerrit-Client
view release on metacpan or search on metacpan
lib/Gerrit/Client.pm view on Meta::CPAN
return;
}
if ($hdr->{Status} eq '401' && !$tried_auth && $handle_auth) {
$handle_auth->($body, $hdr);
return;
}
# failed!
$handle_err->($body, $hdr);
};
$do_http_call = sub { http_post($url, $jsondata, %post_args, $handle_response) };
$do_http_call->();
return;
}
sub _review_by_ssh {
my ($commit_or_change, $options) = @_;
my $parsed_url = $options->{parsed_url};
my @cmd = ( @{ $parsed_url->{cmd} }, 'review', $commit_or_change, );
while ( my ( $key, $spec ) = each %GERRIT_REVIEW_OPTIONS ) {
my $value = $options->{$key};
# code_review -> --code-review
my $cmd_key = $key;
$cmd_key =~ s{_}{-}g;
$cmd_key = "--$cmd_key";
if ( $spec->{type} && $spec->{type} eq BOOLEAN ) {
if ($value) {
push @cmd, $cmd_key;
}
}
elsif ( defined($value) ) {
push @cmd, $cmd_key, quote($value);
}
}
my $cv = AnyEvent::Util::run_cmd( \@cmd );
my $cmdstr;
{
local $LIST_SEPARATOR = '] [';
$cmdstr = "[@cmd]";
}
$cv->cb(
sub {
my $status = shift->recv();
if ( $status && $options->{on_error} ) {
$options->{on_error}->("$cmdstr exited with status $status");
}
if ( !$status && $options->{on_success} ) {
$options->{on_success}->();
}
# make sure we stay alive until this callback is executed
undef $cv;
}
);
return;
}
# options to Gerrit::Client::query which map directly to options to
# "ssh <somegerrit> gerrit query ..."
my %GERRIT_QUERY_OPTIONS = (
( map { $_ => { type => BOOLEAN, default => 0 } }
qw(
all_approvals
comments
commit_message
current_patch_set
dependencies
files
patch_sets
submit_records
)
)
);
=item B<< query $query, ssh_url => $gerrit_url, ... >>
Wrapper for the `gerrit query' command; send a query to gerrit
and invoke a callback with the results.
$query is the Gerrit query string, whose format is described in L<the
Gerrit
documentation|https://gerrit.googlecode.com/svn/documentation/2.2.1/user-search.html>.
"status:open age:1w" is an example of a simple Gerrit query.
$gerrit_url is the URL with ssh schema of the Gerrit site to be queried
(e.g. "ssh://user@gerrit.example.com:29418/").
If the URL contains a path (project) component, it is ignored.
All other arguments are optional, and include:
=over
=item B<< on_success => $cb->( @results ) >>
Callback invoked when the query completes.
Each element of @results is a hashref representing a Gerrit change,
parsed from the JSON output of `gerrit query'. The format of Gerrit
change objects is described in L<the Gerrit documentation|
https://gerrit.googlecode.com/svn/documentation/2.2.1/json.html>.
=item B<< on_error => $cb->( $error ) >>
Callback invoked when the query command fails.
$error is a human-readable string describing the error.
=item B<< all_approvals => 0|1 >>
=item B<< comments => 0|1 >>
lib/Gerrit/Client.pm view on Meta::CPAN
=item B<< submit_records => 0|1 >>
These options are passed to the `gerrit query' command and may be used
to increase the level of information returned by the query.
For information on their usage, please see the output of `gerrit query
--help' on your gerrit installation, or see L<the Gerrit
documentation|http://gerrit.googlecode.com/svn/documentation/2.2.1/cmd-query.html>.
=back
=cut
sub query {
my $query = shift;
my (%options) = validate(
@_,
{ url => 0,
ssh_url => 0,
on_success => { type => CODEREF, default => undef },
on_error => {
type => CODEREF,
default => sub {
warn __PACKAGE__ . "::query: error: ", @_;
}
},
%GERRIT_QUERY_OPTIONS,
}
);
$options{ssh_url} ||= $options{url};
my $parsed_url = _gerrit_parse_url( $options{ssh_url} );
my @cmd = ( @{ $parsed_url->{cmd} }, 'query', '--format', 'json' );
while ( my ( $key, $spec ) = each %GERRIT_QUERY_OPTIONS ) {
my $value = $options{$key};
next unless $value;
# some_option -> --some-option
my $cmd_key = $key;
$cmd_key =~ s{_}{-}g;
$cmd_key = "--$cmd_key";
push @cmd, $cmd_key;
}
push @cmd, quote($query);
my $output;
my $cv = AnyEvent::Util::run_cmd( \@cmd, '>' => \$output );
my $cmdstr;
{
local $LIST_SEPARATOR = '] [';
$cmdstr = "[@cmd]";
}
$cv->cb(
sub {
# make sure we stay alive until this callback is executed
undef $cv;
my $status = shift->recv();
if ( $status && $options{on_error} ) {
$options{on_error}->("$cmdstr exited with status $status");
return;
}
return unless $options{on_success};
my @results;
foreach my $line ( split /\n/, $output ) {
my $data = eval { decode_json($line) };
if ($EVAL_ERROR) {
$options{on_error}->("error parsing result `$line': $EVAL_ERROR");
return;
}
next if ( $data->{type} && $data->{type} eq 'stats' );
push @results, $data;
}
$options{on_success}->(@results);
return;
}
);
return;
}
=item B<< quote $string >>
Returns a copy of the input string with special characters escaped, suitable
for usage with Gerrit CLI commands.
Gerrit commands run via ssh typically need extra quoting because the ssh layer
already evaluates the command string prior to passing it to Gerrit.
This function understands how to quote arguments for this case.
B<Note:> do not use this function for passing arguments to other Gerrit::Client
functions; those perform appropriate quoting internally.
=cut
sub quote {
my ($string) = @_;
# character set comes from gerrit source:
# gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandFactoryProvider.java
# 'split' function
$string =~ s{([\t "'\\])}{\\$1}g;
return $string;
}
=item B<< http_digest_auth($username, $password) >>
Returns a callback to be used with REST-related Gerrit::Client functions.
The callback enables Digest-based HTTP authentication with the given
credentials.
Note that only the Digest scheme used by Gerrit (as of 2.8) is supported:
( run in 0.540 second using v1.01-cache-2.11-cpan-39bf76dae61 )