Gerrit-Client
view release on metacpan or search on metacpan
lib/Gerrit/Client.pm view on Meta::CPAN
$args{ssh_url} || croak 'missing ssh_url argument';
$args{on_patchset}
|| $args{on_patchset_cmd}
|| $args{on_patchset_fork}
|| croak 'missing on_patchset{_cmd,_fork} argument';
$args{workdir} || croak 'missing workdir argument';
$args{on_error} ||= sub { warn __PACKAGE__, ': ', @_ };
if ( !exists( $args{git_work_tree} ) ) {
$args{git_work_tree} = 1;
}
if ( !exists( $args{query} ) ) {
$args{query} = 'status:open';
}
if ( !-d $args{workdir} ) {
mkpath( $args{workdir} );
}
# drop the path section of the URL to get base gerrit URL
my $url = URI->new($args{ssh_url});
$url->path( undef );
$args{ssh_url} = $url->as_string();
require "Gerrit/Client/ForEach.pm";
my $self = bless {}, 'Gerrit::Client::ForEach';
$self->{args} = \%args;
my $weakself = $self;
weaken($weakself);
# stream_events takes care of incoming changes, perform a query to find
# existing changes
my $do_query = sub {
return unless $args{query};
query(
$args{query},
ssh_url => $args{ssh_url},
current_patch_set => 1,
on_error => sub { $args{on_error}->(@_) },
on_success => sub {
return unless $weakself;
my (@results) = @_;
foreach my $change (@results) {
# simulate patch set creation
my ($event) = {
type => 'patchset-created',
change => $change,
patchSet => delete $change->{currentPatchSet},
};
$weakself->_handle_for_each_event($event);
}
},
);
};
# Unfortunately, we have no idea how long it takes between starting the
# stream-events command and when the streaming of events begins, so if
# we query straight away, we could miss some changes which arrive while
# stream-events is e.g. still in ssh negotiation.
# Therefore, introduce this arbitrary delay between when we start
# stream-events and when we'll perform a query.
my $query_timer;
my $do_query_soon = sub {
$query_timer = AE::timer( 4, 0, $do_query );
};
$self->{stream} = Gerrit::Client::stream_events(
ssh_url => $args{ssh_url},
on_event => sub {
$weakself->_handle_for_each_event(@_);
},
on_error => sub {
my ($error) = @_;
$args{on_error}->("connection lost: $error, attempting to recover\n");
# after a few seconds to allow reconnect, perform the base query again
$do_query_soon->();
return 1;
},
);
$do_query_soon->();
return $self;
}
=item B<random_change_id>
Returns a random Change-Id (the character 'I' followed by 40
hexadecimal digits), suitable for usage as the Change-Id field in a
commit to be pushed to gerrit.
=cut
sub random_change_id {
return 'I' . sprintf(
# 40 hex digits, one 32 bit integer gives 8 hex digits,
# therefore 5 random integers
"%08x" x 5,
map { rand() * ( 2**32 ) } ( 1 .. 5 )
);
}
=item B<next_change_id>
Returns the 'next' Change-Id which should be used for a commit created
by the current git author/committer (which should be set by
L<git_environment|/git_environment-name-name-email-email-author_only-0-1->
prior to calling this method). The current working directory must be
within a git repository.
This method is suitable for usage within a script which periodically
creates commits for review, but should have only one outstanding
review (per branch) at any given time. The returned Change-Id is
( run in 1.061 second using v1.01-cache-2.11-cpan-140bd7fdf52 )