diff options
Diffstat (limited to 'lib/Devscripts/Salsa/Hooks.pm')
-rw-r--r-- | lib/Devscripts/Salsa/Hooks.pm | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/lib/Devscripts/Salsa/Hooks.pm b/lib/Devscripts/Salsa/Hooks.pm new file mode 100644 index 0000000..8def3b2 --- /dev/null +++ b/lib/Devscripts/Salsa/Hooks.pm @@ -0,0 +1,215 @@ +# Common hooks library +package Devscripts::Salsa::Hooks; + +use strict; +use Devscripts::Output; +use Moo::Role; + +sub add_hooks { + my ($self, $repo_id, $repo) = @_; + if ( $self->config->kgb + or $self->config->disable_kgb + or $self->config->tagpending + or $self->config->disable_tagpending + or $self->config->irker + or $self->config->disable_irker + or $self->config->email + or $self->config->disable_email) { + my $hooks = $self->enabled_hooks($repo_id); + return 1 unless (defined $hooks); + # KGB hook (IRC) + if ($self->config->kgb or $self->config->disable_kgb) { + unless ($self->config->irc_channel->[0] + or $self->config->disable_kgb) { + ds_warn "--kgb needs --irc-channel"; + return 1; + } + if ($self->config->irc_channel->[1]) { + ds_warn "KGB accepts only one --irc-channel value,"; + } + if ($hooks->{kgb}) { + ds_warn "Deleting old kgb (was $hooks->{kgb}->{url})"; + $self->api->delete_project_hook($repo_id, $hooks->{kgb}->{id}); + } + if ($self->config->irc_channel->[0] + and not $self->config->disable_kgb) { + # TODO: if useful, add parameters for this options + eval { + $self->api->create_project_hook( + $repo_id, + { + url => $self->config->kgb_server_url + . $self->config->irc_channel->[0], + map { ($_ => 1) } @{ $self->config->kgb_options }, + }); + ds_verbose "KGB hook added to project $repo_id (channel: " + . $self->config->irc_channel->[0] . ')'; + }; + if ($@) { + ds_warn "Fail to add KGB hook: $@"; + if (!$self->config->no_fail) { + return 1; + } + } + } + } + # Irker hook (IRC) + if ($self->config->irker or $self->config->disable_irker) { + unless ($self->config->irc_channel->[0] + or $self->config->disable_irker) { + ds_warn "--irker needs --irc-channel"; + return 1; + } + if ($hooks->{irker}) { + no warnings; + ds_warn +"Deleting old irker (redirected to $hooks->{irker}->{recipients})"; + $self->api->delete_project_service($repo_id, 'irker'); + } + if ($self->config->irc_channel->[0] + and not $self->config->disable_irker) { + # TODO: if useful, add parameters for this options + my $ch = join(' ', + map { '#' . $_ } @{ $self->config->irc_channel }); + $self->api->edit_project_service( + $repo_id, 'irker', + { + active => 1, + server_host => $self->config->irker_host, + ( + $self->config->irker_port + ? (server_port => $self->config->irker_port) + : () + ), + default_irc_uri => $self->config->irker_server_url, + recipients => $ch, + colorize_messages => 1, + }); + ds_verbose + "Irker hook added to project $repo_id (channel: $ch)"; + } + } + # email on push + if ($self->config->email or $self->config->disable_email) { + if ($hooks->{email}) { + no warnings; + ds_warn +"Deleting old email-on-push (redirected to $hooks->{email}->{recipients})"; + $self->api->delete_project_service($repo_id, 'emails-on-push'); + } + if (@{ $self->config->email_recipient } + and not $self->config->disable_email) { + # TODO: if useful, add parameters for this options + $self->api->edit_project_service( + $repo_id, + 'emails-on-push', + { + recipients => join(' ', + map { my $a = $_; $a =~ s/%p/$repo/; $a } + @{ $self->config->email_recipient }), + }); + no warnings; + ds_verbose + "Email-on-push hook added to project $repo_id (recipients: " + . join(' ', @{ $self->config->email_recipient }) . ')'; + } + } + # Tagpending hook + if ($self->config->tagpending or $self->config->disable_tagpending) { + if ($hooks->{tagpending}) { + ds_warn + "Deleting old tagpending (was $hooks->{tagpending}->{url})"; + $self->api->delete_project_hook($repo_id, + $hooks->{tagpending}->{id}); + } + my $repo_name = $self->api->project($repo_id)->{name}; + unless ($self->config->disable_tagpending) { + eval { + $self->api->create_project_hook( + $repo_id, + { + url => $self->config->tagpending_server_url + . $repo_name, + push_events => 1, + }); + ds_verbose "Tagpending hook added to project $repo_id"; + }; + if ($@) { + ds_warn "Fail to add Tagpending hook: $@"; + if (!$self->config->no_fail) { + return 1; + } + } + } + } + } + return 0; +} + +sub enabled_hooks { + my ($self, $repo_id) = @_; + my $hooks; + my $res = {}; + if ( $self->config->kgb + or $self->config->disable_kgb + or $self->config->tagpending + or $self->config->disable_tagpending) { + $hooks = eval { $self->api->project_hooks($repo_id) }; + if ($@) { + ds_warn "Unable to check hooks for project $repo_id"; + return undef; + } + foreach my $h (@{$hooks}) { + $res->{kgb} = { + id => $h->{id}, + url => $h->{url}, + options => [grep { $h->{$_} and $h->{$_} eq 1 } keys %$h], + } + if $h->{url} =~ /\Q$self->{config}->{kgb_server_url}\E/; + $res->{tagpending} = { + id => $h->{id}, + url => $h->{url}, + } + if $h->{url} =~ /\Q$self->{config}->{tagpending_server_url}\E/; + } + } + if ( ($self->config->email or $self->config->disable_email) + and $_ = $self->api->project_service($repo_id, 'emails-on-push') + and $_->{active}) { + $res->{email} = $_->{properties}; + } + if ( ($self->config->irker or $self->config->disable_irker) + and $_ = $self->api->project_service($repo_id, 'irker') + and $_->{active}) { + $res->{irker} = $_->{properties}; + } + return $res; +} + +sub desc { + my ($self, $repo) = @_; + my @res = (); + if ($self->config->desc) { + my $str = $self->config->desc_pattern; + $str =~ s/%P/$repo/g; + $repo =~ s#.*/##; + $str =~ s/%p/$repo/g; + push @res, description => $str; + } + if ($self->config->disable_issues) { + push @res, issues_enabled => 0; + } elsif ($self->config->enable_issues) { + push @res, issues_enabled => 1; + } + if ($self->config->disable_mr) { + push @res, merge_requests_enabled => 0; + } elsif ($self->config->enable_mr) { + push @res, merge_requests_enabled => 1; + } + if ($self->config->ci_config_path) { + push @res, ci_config_path => $self->config->ci_config_path; + } + return @res; +} + +1; |