summaryrefslogtreecommitdiffstats
path: root/lib/Devscripts/Salsa/Hooks.pm
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/Devscripts/Salsa/Hooks.pm215
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;