X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/04a9dbfe7daa9c352ae4e9af17df8134248f3806..b277e00d4ec2dc3b50a111957b7fbd0c5ac7bbd9:/IkiWiki/Rcs/svn.pm?ds=sidebyside diff --git a/IkiWiki/Rcs/svn.pm b/IkiWiki/Rcs/svn.pm index 597295d44..9081c3902 100644 --- a/IkiWiki/Rcs/svn.pm +++ b/IkiWiki/Rcs/svn.pm @@ -1,12 +1,24 @@ #!/usr/bin/perl +package IkiWiki::Rcs::svn; + use warnings; use strict; use IkiWiki; use POSIX qw(setlocale LC_CTYPE); +sub import { #{{{ + if (exists $IkiWiki::config{svnpath}) { + # code depends on the path not having extraneous slashes + $IkiWiki::config{svnpath}=~tr#/#/#s; + $IkiWiki::config{svnpath}=~s/\/$//; + $IkiWiki::config{svnpath}=~s/^\///; + } +} #}}} + + package IkiWiki; - + # svn needs LC_CTYPE set to a UTF-8 locale, so try to find one. Any will do. sub find_lc_ctype() { my $current = setlocale(LC_CTYPE()); @@ -85,9 +97,8 @@ sub rcs_commit ($$$;$$) { #{{{ if (defined $rev && defined $oldrev && $rev != $oldrev) { # Merge their changes into the file that we've # changed. - chdir($config{srcdir}); # svn merge wants to be here if (system("svn", "merge", "--quiet", "-r$oldrev:$rev", - "$config{srcdir}/$file") != 0) { + "$config{srcdir}/$file", "$config{srcdir}/$file") != 0) { warn("svn merge -r$oldrev:$rev failed\n"); } } @@ -95,7 +106,7 @@ sub rcs_commit ($$$;$$) { #{{{ if (system("svn", "commit", "--quiet", "--encoding", "UTF-8", "-m", possibly_foolish_untaint($message), - "$config{srcdir}") != 0) { + $config{srcdir}) != 0) { my $conflict=readfile("$config{srcdir}/$file"); if (system("svn", "revert", "--quiet", "$config{srcdir}/$file") != 0) { warn("svn revert failed\n"); @@ -106,6 +117,28 @@ sub rcs_commit ($$$;$$) { #{{{ return undef # success } #}}} +sub rcs_commit_staged ($$$) { + # Commits all staged changes. Changes can be staged using rcs_add, + # rcs_remove, and rcs_rename. + my ($message, $user, $ipaddr)=@_; + + if (defined $user) { + $message="web commit by $user".(length $message ? ": $message" : ""); + } + elsif (defined $ipaddr) { + $message="web commit from $ipaddr".(length $message ? ": $message" : ""); + } + + if (system("svn", "commit", "--quiet", + "--encoding", "UTF-8", "-m", + possibly_foolish_untaint($message), + $config{srcdir}) != 0) { + warn("svn commit failed\n"); + return 1; # failure + } + return undef # success +} + sub rcs_add ($) { #{{{ # filename is relative to the root of the srcdir my $file=shift; @@ -123,6 +156,40 @@ sub rcs_add ($) { #{{{ } } #}}} +sub rcs_remove ($) { #{{{ + # filename is relative to the root of the srcdir + my $file=shift; + + if (-d "$config{srcdir}/.svn") { + if (system("svn", "rm", "--force", "--quiet", "$config{srcdir}/$file") != 0) { + warn("svn rm failed\n"); + } + } +} #}}} + +sub rcs_rename ($$) { #{{{ + # filenames relative to the root of the srcdir + my ($src, $dest)=@_; + + if (-d "$config{srcdir}/.svn") { + # Add parent directory for $dest + my $parent=dirname($dest); + if (! -d "$config{srcdir}/$parent/.svn") { + while (! -d "$config{srcdir}/$parent/.svn") { + $parent=dirname($dest); + } + if (system("svn", "add", "--quiet", "$config{srcdir}/$parent") != 0) { + warn("svn add $parent failed\n"); + } + } + + if (system("svn", "mv", "--force", "--quiet", + "$config{srcdir}/$src", "$config{srcdir}/$dest") != 0) { + warn("svn rename failed\n"); + } + } +} #}}} + sub rcs_recentchanges ($) { #{{{ my $num=shift; my @ret; @@ -131,7 +198,6 @@ sub rcs_recentchanges ($) { #{{{ eval q{ use Date::Parse; - use Time::Duration; use XML::SAX; use XML::Simple; }; @@ -161,7 +227,7 @@ sub rcs_recentchanges ($) { #{{{ my $rev = $logentry->{revision}; my $user = $logentry->{author}; - my $when=time - str2time($logentry->{date}, 'UTC'); + my $when=str2time($logentry->{date}, 'UTC'); foreach my $msgline (split(/\n/, $logentry->{msg})) { push @message, { line => $msgline }; @@ -177,19 +243,24 @@ sub rcs_recentchanges ($) { #{{{ $committype="svn"; } - foreach (keys %{$logentry->{paths}}) { - next unless /^\/\Q$config{svnpath}\E\/([^ ]+)(?:$|\s)/; - my $file=$1; + foreach my $file (keys %{$logentry->{paths}}) { + if (length $config{svnpath}) { + next unless $file=~/^\/\Q$config{svnpath}\E\/([^ ]+)(?:$|\s)/; + $file=$1; + } + my $diffurl=$config{diffurl}; $diffurl=~s/\[\[file\]\]/$file/g; $diffurl=~s/\[\[r1\]\]/$rev - 1/eg; $diffurl=~s/\[\[r2\]\]/$rev/g; + push @pages, { page => pagename($file), diffurl => $diffurl, } if length $file; } - push @ret, { rev => $rev, + push @ret, { + rev => $rev, user => $user, committype => $committype, when => $when, @@ -202,37 +273,9 @@ sub rcs_recentchanges ($) { #{{{ return @ret; } #}}} -sub rcs_notify () { #{{{ - if (! exists $ENV{REV}) { - error("REV is not set, not running from svn post-commit hook, cannot send notifications"); - } - my $rev=int(possibly_foolish_untaint($ENV{REV})); - - my $user=`svnlook author $config{svnrepo} -r $rev`; - chomp $user; - - my $message=`svnlook log $config{svnrepo} -r $rev`; - if ($message=~/$config{web_commit_regexp}/) { - $user=defined $2 ? "$2" : "$3"; - $message=$4; - } - - my @changed_pages; - foreach my $change (`svnlook changed $config{svnrepo} -r $rev`) { - chomp $change; - if ($change =~ /^[A-Z]+\s+\Q$config{svnpath}\E\/(.*)/) { - push @changed_pages, $1; - } - } - - require IkiWiki::UserInfo; - send_commit_mails( - sub { - return $message; - }, - sub { - `svnlook diff $config{svnrepo} -r $rev --no-diff-deleted`; - }, $user, @changed_pages); +sub rcs_diff ($) { #{{{ + my $rev=possibly_foolish_untaint(int(shift)); + return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`; } #}}} sub rcs_getctime ($) { #{{{