]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - doc/plugins/contrib/irker.mdwn
fix system calls
[git.ikiwiki.info.git] / doc / plugins / contrib / irker.mdwn
1 [[!template id=plugin name=irker author="[[anarcat]]"]]
2 [[!tag type/special-purpose]]
4 This plugin will configure your wiki to send IRC notifications using the [irker](http://www.catb.org/esr/irker/) notification bot.
6 It is fairly simple and requires no configuration but installation of the irker package. For template configuration, patches from [Debian bug #824512](https://bugs.debian.org/824512) are necessary.
8 [[!format perl """
9 package IkiWiki::Plugin::irker;
11 use warnings;
12 use strict;
13 use IkiWiki 3.00;
15 sub import {
16     hook(type => "getsetup", id => "irker", call => \&getsetup);
17     hook(type => "checkconfig", id => "branchable", call => \&checkconfig,
18          first => 1);
19     hook(type => "genwrapper", id => "irker", call => \&genwrapper,
20          last => 1);
21 }
23 sub getsetup() {
24         return
25                 plugin => {
26                         safe => 0,
27                         rebuild => undef,
28                         section => "core",
29                 },
30                 irker_channels => {
31                         type => "string",
32                         example => ['ircs://irc.example.com/example'],
33                         description => "IRC channels to send notifications to",
34                         safe => 1,
35                         rebuild => 0,
36                 },
37                 irker_template => {
38                         type => "string",
39                         example => "'%(bold)s%(project)s:%(reset)s %(green)s%(author)s%(reset)s %(repo)s:%(yellow)s%(branch)s%(reset)s * %(bold)s%(rev)s%(reset)s / %(bold)s%(files)s%(reset)s: %(logmsg)s %(brown)s%(url)s%(reset)s",
40                         description => "Template to use for messages. Only supported with patch from https://bugs.debian.org/824512",
41                         safe => 1,
42                         rebuild => 0,
43                 },
44                 irker_hook => {
45                         type => "string",
46                         example => "irkerhook-git",
47                         description => 'Hook to setup for notifications, will look in $PATH if File::Which is available, otherwise use absolute path.',
48                         safe => 1,
49                         rebuild => 0,
50                 },
51 }
53 sub checkconfig {
54     use URI; # ikiwiki Depends on it
55     foreach my $channel (@{$config{'irker_channels'}}) {
56         my $uri = URI->new( $channel );
57         # inspired by http://stackoverflow.com/a/2599378/1174784
58         # and http://stackoverflow.com/a/4953329/1174784
59         if (!$uri->scheme || $uri->path =~ m/^([#&]?[^\x07\x2C\s]{,200})/) {
60             error("$channel is not a valid IRC channel URI");
61         }
62     }
63     # check if hook exists
64     if (-x $config{irker_hook}) {
65         # shortcut: already configured
66         return;
67     }
68     eval q{use File::Which};
69     # check with which, i available
70     if (!$@) {
71         my $hook;
72         if (!defined $config{'irker_hook'}) {
73             $config{'irker_hook'} = 'irkerhook-git';
74         }
75         $hook = which($config{'irker_hook'});
76         if (defined $hook) {
77             $config{'irker_hook'} = $hook;
78         }
79         else {
80             error("irker hook '$config{irker_hook}' not found in PATH");
81         }
82     }
83     if (!-x $config{irker_hook}) {
84         error("irker hook '$config{irker_hook}' not executable");
85     }
86 }
88 # Parses git_wrapper to find out where the git repository is.
89 # cargo-culted from branchable.pm
90 sub find_git_repository {
91         if ($config{rcs} eq 'git' &&
92             $config{git_wrapper}=~m!^(.*)/hooks/post-update$!) {
93                 return $1;
94         }
95         else {
96                 return undef;
97         }
98 }
100 # setup the hook symlink and git configuration
101 sub genwrapper() {
102     my $repo=find_git_repository();
103     if (defined $repo && defined $config{'irker_channels'}) {
104         if (!-l $repo . '/hooks/post-receive') {
105             if (-e $repo . '/hooks/post-receive') {
106                 error('post-receive hook exists and is not a symlink, failed to setup hook');
107             }
108             symlink($config{'irker_hook'}, $repo . '/hooks/post-receive') || error('failed to symlink: $!');
109         }
110         my $channels = join(",", @{$config{'irker_channels'}});
111         system { 'git' } ('config', '-C', $repo, 'config', 'irker.channels', $channels);
112         system { 'git' } ('config', '-C', $repo, 'config', 'irker.channels', $config{'wikiname'});
113         if ($config{'irker_template'}) {
114             exec { 'git' } ('config', '-C', $repo, 'config', 'irker.channels', $config{'irker_template'});
115         }
116     }
117     else {
118         system { 'git' } ('config', '-C', $repo, 'config', '--remove-section', 'irker');
119         if (-l $repo . '/hooks/post-receive' && 
120             readlink($repo . '/hooks/post-receive') =~ m/irkerhook/) {
121             unlink($repo . '/hooks/post-receive');
122         }
123     }
124     return "";
128 """]]