-sub rcs_notify () { #{{{
- # Send notification mail to subscribed users.
- #
- # In usual Git usage, hooks/update script is presumed to send
- # notification mails (see git-receive-pack(1)). But we prefer
- # hooks/post-update to support IkiWiki commits coming from a
- # cloned repository (through command line) because post-update
- # is called _after_ each ref in repository is updated (update
- # hook is called _before_ the repository is updated). Since
- # post-update hook does not accept command line arguments, we
- # don't have an $ENV variable in this function.
- #
- # Here, we rely on a simple fact: we can extract all parts of the
- # notification content by parsing the "HEAD" commit (which also
- # triggers a refresh of IkiWiki pages) and we can obtain the diff
- # by comparing HEAD and HEAD^ (the previous commit).
-
- my $sha1 = 'HEAD'; # the commit which triggers this action
-
- my $ci = git_commit_info($sha1);
- return if !defined $ci;
-
- my @changed_pages = map { $_->{'file'} } @{ $ci->{'details'} };
-
- my ($user, $message);
- if (@{ $ci->{'comment'} }[0] =~ m/$config{web_commit_regexp}/) {
- $user = defined $2 ? "$2" : "$3";
- $message = $4;
- } else {
- $user = $ci->{'author_username'};
- $message = join "\n", @{ $ci->{'comment'} };
- }
-
- require IkiWiki::UserInfo;
- my @email_recipients = commit_notify_list($user, @changed_pages);
- return if !@email_recipients;
-
- # TODO: if a commit spans multiple pages, this will send
- # subscribers a diff that might contain pages they did not
- # sign up for. Should separate the diff per page and
- # reassemble into one mail with just the pages subscribed to.
- my $diff = join "\n", run_or_die('git-diff', "${sha1}^", $sha1);
-
- my $subject = "$config{wikiname} update of ";
- if (@changed_pages > 2) {
- $subject .= "$changed_pages[0] $changed_pages[1] etc";
- } else {
- $subject .= join " ", @changed_pages;
- }
- $subject .= " by $user";
-
- my $template = template("notifymail.tmpl");
- $template->param(
- wikiname => $config{wikiname},
- diff => $diff,
- user => $user,
- message => $message,
- );
-
- eval q{use Mail::Sendmail};
- error($@) if $@;
- foreach my $email (@email_recipients) {
- sendmail(
- To => $email,
- From => "$config{wikiname} <$config{adminemail}>",
- Subject => $subject,
- Message => $template->output,
- ) or error("Failed to send update notification mail: $!");
- }
-} #}}}
-