File Coverage

blib/lib/SVN/Hooks.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package SVN::Hooks;
2             {
3             $SVN::Hooks::VERSION = '1.27';
4             }
5             # ABSTRACT: Framework for implementing Subversion hooks
6              
7 1     1   6 use strict;
  1         2  
  1         38  
8 1     1   7 use warnings;
  1         1  
  1         36  
9              
10 1     1   5 use File::Basename;
  1         1  
  1         149  
11 1     1   1422 use File::Spec::Functions;
  1         986  
  1         96  
12 1     1   6 use Data::Util qw(:check);
  1         3  
  1         197  
13 1     1   2479 use SVN::Look;
  0            
  0            
14              
15             use Exporter qw/import/;
16              
17             our @EXPORT = qw/run_hook POST_COMMIT POST_LOCK POST_REVPROP_CHANGE
18             POST_UNLOCK PRE_COMMIT PRE_LOCK PRE_REVPROP_CHANGE
19             PRE_UNLOCK START_COMMIT/;
20              
21             our @Conf_Files = (catfile('conf', 'svn-hooks.conf'));
22             our $Repo = undef;
23             our %Hooks = ();
24              
25             sub run_hook {
26             my ($hook_name, $repo_path, @args) = @_;
27              
28             $hook_name = basename $hook_name;
29              
30             -d $repo_path or die "not a directory ($repo_path): $_\n";
31              
32             $Repo = $repo_path;
33              
34             # Reload all configuration files
35             foreach my $conf (@Conf_Files) {
36             my $conffile = file_name_is_absolute($conf) ? $conf : catfile($Repo, $conf);
37             next unless -e $conffile; # Configuration files are optional
38              
39             # The configuration file must be evaluated in the main:: namespace
40             package main;
41             {
42             $main::VERSION = '1.27';
43             }
44             unless (my $return = do $conffile) {
45             die "couldn't parse '$conffile': $@\n" if $@;
46             die "couldn't do '$conffile': $!\n" unless defined $return;
47             die "couldn't run '$conffile'\n" unless $return;
48             }
49             }
50              
51             # Substitute a SVN::Look object for the first argument
52             # in the hooks where this makes sense.
53             if ($hook_name eq 'pre-commit') {
54             # The next arg is a transaction number
55             $repo_path = SVN::Look->new($repo_path, '-t' => $args[0]);
56             } elsif ($hook_name =~ /^(?:post-commit|(?:pre|post)-revprop-change)$/) {
57             # The next arg is a revision number
58             $repo_path = SVN::Look->new($repo_path, '-r' => $args[0]);
59             }
60              
61             foreach my $hook (@{$Hooks{$hook_name}}) {
62             if (is_code_ref($hook)) {
63             $hook->($repo_path, @args);
64             } elsif (is_array_ref($hook)) {
65             foreach my $h (@$hook) {
66             $h->($repo_path, @args);
67             }
68             } else {
69             die "SVN::Hooks: internal error!\n";
70             }
71             }
72              
73             return;
74             }
75              
76             ## no critic (Subroutines::ProhibitSubroutinePrototypes)
77              
78             # post-commit(SVN::Look)
79              
80             sub POST_COMMIT (&) {
81             my ($hook) = @_;
82             push @{$Hooks{'post-commit'}}, sub { $hook->(@_); };
83             return;
84             }
85              
86             # post-lock(repos-path, username)
87              
88             sub POST_LOCK (&) {
89             my ($hook) = @_;
90             push @{$Hooks{'post-lock'}}, sub { $hook->(@_); };
91             return;
92             }
93              
94             # post-revprop-change(SVN::Look, username, property-name, action)
95              
96             sub POST_REVPROP_CHANGE (&) {
97             my ($hook) = @_;
98             push @{$Hooks{'post-revprop-change'}}, sub { $hook->(@_); };
99             return;
100             }
101              
102             # post-unlock(repos-path, username)
103              
104             sub POST_UNLOCK (&) {
105             my ($hook) = @_;
106             push @{$Hooks{'post-unlock'}}, sub { $hook->(@_); };
107             return;
108             }
109              
110             # pre-commit(SVN::Look)
111              
112             sub PRE_COMMIT (&) {
113             my ($hook) = @_;
114             push @{$Hooks{'pre-commit'}}, sub { $hook->(@_); };
115             return;
116             }
117              
118             # pre-lock(repos-path, path, username, comment, steal-lock-flag)
119              
120             sub PRE_LOCK (&) {
121             my ($hook) = @_;
122             push @{$Hooks{'pre-lock'}}, sub { $hook->(@_); };
123             return;
124             }
125              
126             # pre-revprop-change(SVN::Look, username, property-name, action)
127              
128             sub PRE_REVPROP_CHANGE (&) {
129             my ($hook) = @_;
130             push @{$Hooks{'pre-revprop-change'}}, sub { $hook->(@_); };
131             return;
132             }
133              
134             # pre-unlock(repos-path, path, username, lock-token, break-unlock-flag)
135              
136             sub PRE_UNLOCK (&) {
137             my ($hook) = @_;
138             push @{$Hooks{'pre-unlock'}}, sub { $hook->(@_); };
139             return;
140             }
141              
142             # start-commit(repos-path, username, capabilities)
143              
144             sub START_COMMIT (&) {
145             my ($hook) = @_;
146             push @{$Hooks{'start-commit'}}, sub { $hook->(@_); };
147             return;
148             }
149              
150             ## use critic
151              
152             1; # End of SVN::Hooks
153              
154             __END__