#! /usr/bin/perl # mail-watchers # -- looks up the repo in the database ; # -- determines the repo's watchers : # $watchlist -> { $watcher } { $path } == is_watcher # # -- for each watcher, uses 'SVN::Notify' to notify the watcher, # picking the relevant parts (by $path) from the svn-diff ; # The longest matching path determines the relevancy. # # -- called from every REPO/hooks/post-commit as # $prog repo-name revision repo_id use lib 'lib' ; use strict ; use warnings ; use Repocafe ; use SVN::Notify ; use PickDiff ; use lib::DiffPicker ; my $prog = substr($0,rindex($0,'/')+1) ; my $Usage = </dev/null" ; close STDERR ; open STDERR, ">/dev/null" ; } my $REPO = shift ; my $REV = shift ; my $RID = shift ; my $Cafe = make_cafe ( c => $opt{c} ) ; my $conf = $Cafe -> conf ; my $serv = $conf -> www_server ; my $from = $conf -> mail_from_noreply ; my $REPO_DIR = $conf -> dir_repos ; my @PROG = split ' ', $conf -> cmd_commit_email ; my @OPTS = ( '--from', $from ) ; # $Cafe -> repos -> dmp ( -incl => [ 'TAB' ] ) if $opt{v} ; my $repo = $Cafe -> repos -> get ( $RID ) ; my $name = $repo -> repo_name ; my $path = $repo -> path ; my @wats = $repo -> watchers ; my $list = $repo -> watch_list ; Error "REPO != path ; $REPO != $path" if $opt{v} and $REPO ne $path ; my %notify_opts = ( repos_path => $REPO , revision => $REV , sendmail => '/usr/sbin/sendmail' , from => $from , with_diff => 1 , diff_switches => '--no-diff-added --no-diff-deleted' , max_sub_length => 100 , max_diff_length => 1024 * 1024 , filters => [ 'lib::DiffPicker' ] , subject_prefix => $name ) ; sub mk_sub_like { my $hash = shift ; sub { my $file = shift ; my $res = 0 ; for my $path ( sort keys %$hash ) { $res = $hash -> { $path } if $path eq '' or $file =~ m!^$path/! ; } $res ; } } for my $mail ( sort keys %$list ) { my $paths = $list -> { $mail } ; my $N = lib::DiffPicker -> new ( %notify_opts , to => $mail ) ; my $like = PickDiff -> set_like ( mk_sub_like ( $paths ) ) ; my @likes = () ; my $prep = $N -> prepare ; if ( $opt{v} ) { printf "%s :\n%s", $mail, join '', map { sprintf " watching (%s,%s)\n", $_, $paths -> { $_ } || 0 ; } sort keys %$paths ; printf "repo -> path (%s)\n", $path ; printf "user -> mail (%s)\n", $mail ; printf "prepare %s\n", $prep ; } my $files = $N -> files ; for my $key ( sort keys %$files ) { my @names = @{ $files -> { $key } } ; my @like = grep &$like ( $_ ), @names ; $files -> { $key } = [ @like ] ; push @likes, @like ; if ( $opt{v} ) { printf " like %s %s\n", $_, &$like ( $_ ) for @names ; } } if ( @likes ) { unless ( $opt{d} ) { no warnings ; my $exec = $N -> execute ; printf "execute %s\n", $exec if $opt{v} ; } } if ( $opt{v} ) { printf "from %s\n", $from ; printf "to %s\n", @{ $N -> { to } } ; printf "like %d\n[ %s\n]\n", scalar @likes, join "\n, ", @likes ; } }