wiki.pl: Port some fixes from upstream
[Orgmuse.git] / svn-post-commit-copy-to-wiki.pl
blob9d19f94a819e68477218962539d0c1f5248a7317
1 #!/usr/bin/perl -w
3 # Copyright 2005 Alex Schroeder <alex@emacswiki.org>
5 # Based on commit-email.pl, which is part of Subversion.
6 # ====================================================================
7 # Copyright (c) 2000-2004 CollabNet. All rights reserved.
9 # This software is licensed as described in the file COPYING, which
10 # you should have received as part of this distribution. The terms
11 # are also available at http://subversion.tigris.org/license-1.html.
12 # If newer versions of this license are posted there, you may use a
13 # newer version instead, at your option.
15 # This software consists of voluntary contributions made by many
16 # individuals. For exact contribution history, see the revision
17 # history and logs, available at http://subversion.tigris.org/.
18 # ====================================================================
20 # Turn on warnings the best way depending on the Perl version.
21 BEGIN {
22 if ( $] >= 5.006_000)
23 { require warnings; import warnings; }
24 else
25 { $^W = 1; }
28 use strict;
29 use Carp;
30 use File::Basename;
31 use LWP::UserAgent;
33 ######################################################################
34 # Configuration section.
36 # Svnlook path.
37 my $svnlook = "/usr/bin/svnlook";
39 # End of Configuration section.
40 ######################################################################
42 # Since the path to svnlook depends upon the local installation
43 # preferences, check that the required programs exist to insure that
44 # the administrator has set up the script properly.
46 my $ok = 1;
47 foreach my $program ($svnlook)
49 if (-e $program)
51 unless (-x $program)
53 warn "$0: required program `$program' is not executable, ",
54 "edit $0.\n";
55 $ok = 0;
58 else
60 warn "$0: required program `$program' does not exist, edit $0.\n";
61 $ok = 0;
64 exit 1 unless $ok;
68 ######################################################################
69 # Initial setup/command-line handling.
71 # repository path, revision number, and url to post to
72 my ($repos, $rev, $url) = @ARGV;
74 # If the last argument is undefined, then there were not enough
75 # command line arguments.
76 &usage("$0: too few arguments.") unless defined $url;
78 # Check the validity of the command line arguments. Check that the
79 # revision is an integer greater than 0 and that the repository
80 # directory exists.
81 unless ($rev =~ /^\d+/ and $rev > 0)
83 &usage("$0: revision number `$rev' must be an integer > 0.");
85 unless (-e $repos)
87 &usage("$0: repos directory `$repos' does not exist.");
89 unless (-d _)
91 &usage("$0: repos directory `$repos' is not a directory.");
93 unless ($url =~ m!http://!)
95 &usage("$0: wiki url `$url' is not an URL.");
98 ######################################################################
99 # Harvest data using svnlook.
101 # Get the author, date, and log from svnlook.
102 my @svnlooklines = &read_from_process($svnlook, 'info', $repos, '-r', $rev);
103 my $author = shift @svnlooklines;
104 my $date = shift @svnlooklines;
105 shift @svnlooklines;
106 my @log = @svnlooklines;
108 # Figure out what files have changed using svnlook.
109 @svnlooklines = &read_from_process($svnlook, 'changed', $repos, '-r', $rev);
111 # Parse the changed nodes.
112 my @paths = ();
113 foreach my $line (@svnlooklines)
115 # Split the line up into the modification code and path, ignoring
116 # property modifications.
117 if ($line =~ /^(.). (.*)$/)
119 push(@paths, $2);
123 ######################################################################
124 # Post to the wiki
126 foreach my $path (@paths) {
127 my $id = basename($path);
128 my $log = join("\n", @log);
129 my @data = &read_from_process($svnlook, 'cat', $repos, $path, '-r', $rev);
130 my $data = join("\n", @data);
131 my $ua = LWP::UserAgent->new;
132 $ua->post($url, { title=>$id,
133 username=>$author,
134 summary=>$log,
135 text=>$data});
138 exit 0;
140 sub usage
142 warn "@_\n" if @_;
143 die "usage: $0 REPOS REVNUM URL\n";
146 # Start a child process safely without using /bin/sh.
147 sub safe_read_from_pipe
149 unless (@_)
151 croak "$0: safe_read_from_pipe passed no arguments.\n";
154 my $pid = open(SAFE_READ, '-|');
155 unless (defined $pid)
157 die "$0: cannot fork: $!\n";
159 unless ($pid)
161 open(STDERR, ">&STDOUT")
162 or die "$0: cannot dup STDOUT: $!\n";
163 exec(@_)
164 or die "$0: cannot exec `@_': $!\n";
166 my @output;
167 while (<SAFE_READ>)
169 s/[\r\n]+$//;
170 push(@output, $_);
172 close(SAFE_READ);
173 my $result = $?;
174 my $exit = $result >> 8;
175 my $signal = $result & 127;
176 my $cd = $result & 128 ? "with core dump" : "";
177 if ($signal or $cd)
179 warn "$0: pipe from `@_' failed $cd: exit=$exit signal=$signal\n";
181 if (wantarray)
183 return ($result, @output);
185 else
187 return $result;
191 # Use safe_read_from_pipe to start a child process safely and return
192 # the output if it succeeded or an error message followed by the output
193 # if it failed.
194 sub read_from_process
196 unless (@_)
198 croak "$0: read_from_process passed no arguments.\n";
200 my ($status, @output) = &safe_read_from_pipe(@_);
201 if ($status)
203 return ("$0: `@_' failed with this output:", @output);
205 else
207 return @output;