From 86e1dc492ffa26f6546c9c6d3234b762a86ccb61 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 19 Jul 2011 11:26:14 -0400 Subject: apply the big mercurial patch * mercurial: openid nicknames are now used when committing. (Daniel Andersson) * mercurial: implement rcs_commit_staged so comments, attachments, etc can be used. (Daniel Andersson) * mercurial: fix viewing of a diff containing non-utf8 changes. (Daniel Andersson) --- IkiWiki/Plugin/mercurial.pm | 117 +++++++++++++++++---- debian/changelog | 10 ++ doc/rcs.mdwn | 4 +- ...ttempt_to_extend_Mercurial_backend_support.mdwn | 2 + 4 files changed, 111 insertions(+), 22 deletions(-) diff --git a/IkiWiki/Plugin/mercurial.pm b/IkiWiki/Plugin/mercurial.pm index d7399eaf0..79f021516 100644 --- a/IkiWiki/Plugin/mercurial.pm +++ b/IkiWiki/Plugin/mercurial.pm @@ -69,6 +69,50 @@ sub getsetup () { }, } +sub safe_hg (&@) { + # Start a child process safely without resorting to /bin/sh. + # Returns command output (in list content) or success state + # (in scalar context), or runs the specified data handler. + + my ($error_handler, $data_handler, @cmdline) = @_; + + my $pid = open my $OUT, "-|"; + + error("Cannot fork: $!") if !defined $pid; + + if (!$pid) { + # In child. + # hg commands want to be in wc. + chdir $config{srcdir} + or error("cannot chdir to $config{srcdir}: $!"); + + exec @cmdline or error("Cannot exec '@cmdline': $!"); + } + # In parent. + + my @lines; + while (<$OUT>) { + chomp; + + if (! defined $data_handler) { + push @lines, $_; + } + else { + last unless $data_handler->($_); + } + } + + close $OUT; + + $error_handler->("'@cmdline' failed: $!") if $? && $error_handler; + + return wantarray ? @lines : ($? == 0); +} +# Convenient wrappers. +sub run_or_die ($@) { safe_hg(\&error, undef, @_) } +sub run_or_cry ($@) { safe_hg(sub { warn @_ }, undef, @_) } +sub run_or_non ($@) { safe_hg(undef, undef, @_) } + sub mercurial_log ($) { my $out = shift; my @infos; @@ -116,10 +160,7 @@ sub mercurial_log ($) { } sub rcs_update () { - my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update"); - if (system(@cmdline) != 0) { - warn "'@cmdline' failed: $!"; - } + run_or_cry('hg', '-q', 'update'); } sub rcs_prepedit ($) { @@ -129,62 +170,83 @@ sub rcs_prepedit ($) { sub rcs_commit (@) { my %params=@_; + return rcs_commit_helper(@_); +} + +sub rcs_commit_helper (@) { + my %params=@_; + + my %env=%ENV; + $ENV{HGENCODING} = 'utf-8'; + my $user="Anonymous"; + my $nickname; if (defined $params{session}) { if (defined $params{session}->param("name")) { $user = $params{session}->param("name"); } elsif (defined $params{session}->remote_addr()) { - $user = "Anonymous from ".$params{session}->remote_addr(); + $user = $params{session}->remote_addr(); } + + if (defined $params{session}->param("nickname")) { + $nickname=encode_utf8($params{session}->param("nickname")); + $nickname=~s/\s+/_/g; + $nickname=~s/[^-_0-9[:alnum:]]+//g; + } + $ENV{HGUSER} = encode_utf8($user . ' <' . $nickname . '@web>'); } if (! length $params{message}) { $params{message} = "no message given"; } - my @cmdline = ("hg", "-q", "-R", $config{srcdir}, "commit", - "-m", IkiWiki::possibly_foolish_untaint($params{message}), - "-u", IkiWiki::possibly_foolish_untaint($user)); - if (system(@cmdline) != 0) { - warn "'@cmdline' failed: $!"; + $params{message} = IkiWiki::possibly_foolish_untaint($params{message}); + + my @opts; + + if (exists $params{file}) { + push @opts, '--', $params{file}; } + # hg commit returns non-zero if nothing really changed. + # So we should ignore its exit status (hence run_or_non). + run_or_non('hg', 'commit', '-m', $params{message}, '-q', @opts); + %ENV=%env; return undef; # success } sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my %params=@_; - - error("rcs_commit_staged not implemented for mercurial"); # TODO + return rcs_commit_helper(@_); } sub rcs_add ($) { my ($file) = @_; - my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$config{srcdir}/$file"); - if (system(@cmdline) != 0) { - warn "'@cmdline' failed: $!"; - } + run_or_cry('hg', 'add', $file); } sub rcs_remove ($) { + # Remove file from archive. my ($file) = @_; - error("rcs_remove not implemented for mercurial"); # TODO + run_or_cry('hg', 'remove', '-f', $file); } sub rcs_rename ($$) { my ($src, $dest) = @_; - error("rcs_rename not implemented for mercurial"); # TODO + run_or_cry('hg', 'rename', '-f', $src, $dest); } sub rcs_recentchanges ($) { my ($num) = @_; + my %env=%ENV; + $ENV{HGENCODING} = 'utf-8'; + my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", $num, "--style", "default"); open (my $out, "@cmdline |"); @@ -212,20 +274,35 @@ sub rcs_recentchanges ($) { }; } + #"user ": parse out "user". my $user = $info->{"user"}; $user =~ s/\s*<.*>\s*$//; $user =~ s/^\s*//; + #"user ": if "@web" hits, set $web_commit=true. + my $web_commit = ($info->{'user'} =~ /\@web>/); + + #"user ": if user is a URL (hits "://") and "@web" + #was present, parse out nick. + my $nickname; + if ($user =~ /:\/\// && $web_commit) { + $nickname = $info->{'user'}; + $nickname =~ s/^[^<]*<([^\@]+)\@web>\s*$/$1/; + } + push @ret, { rev => $info->{"changeset"}, user => $user, - committype => "hg", + nickname => $nickname, + committype => $web_commit ? "web" : "hg", when => str2time($info->{"date"}), message => [@message], pages => [@pages], }; } + %ENV=%env; + return @ret; } diff --git a/debian/changelog b/debian/changelog index 8e280f9c7..30084304a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +ikiwiki (3.20110716) UNRELEASED; urgency=low + + * mercurial: openid nicknames are now used when committing. (Daniel Andersson) + * mercurial: implement rcs_commit_staged so comments, attachments, etc + can be used. (Daniel Andersson) + * mercurial: fix viewing of a diff containing non-utf8 changes. + (Daniel Andersson) + + -- Joey Hess Tue, 19 Jul 2011 11:22:52 -0400 + ikiwiki (3.20110715) unstable; urgency=low * rename: Fix logic error that broke renaming pages when the attachment diff --git a/doc/rcs.mdwn b/doc/rcs.mdwn index 4d75d6325..9f531d442 100644 --- a/doc/rcs.mdwn +++ b/doc/rcs.mdwn @@ -17,7 +17,7 @@ links to more information about each. feature |[[git]]|[[svn]]|[[bzr]] |[[monotone]]|[[mercurial]]|[[darcs]]|[[tla]] |[[cvs]] [[ikiwiki-makerepo]]|yes |yes |yes |yes |yes |yes |no |yes auto.setup |yes |yes |incomplete|yes |incomplete |yes |incomplete|yes -`rcs_commit_staged` |yes |yes |yes |yes |no |yes |no |yes +`rcs_commit_staged` |yes |yes |yes |yes |yes |yes |no |yes `rcs_rename` |yes |yes |yes |yes |no |yes |no |yes `rcs_remove` |yes |yes |yes |yes |no |yes |no |yes `rcs_diff` |yes |yes |yes |yes |no |yes |yes |yes @@ -27,7 +27,7 @@ auto.setup |yes |yes |incomplete|yes |incomplete |yes `rcs_revert` |yes |no |no |no |no |no |no |no anonymous push |yes |no |no |no |no |no |no |no conflict handling |yes |yes |yes |buggy |yes |yes |yes |yes -openid username |yes |no |no |no |no |no |no |no +openid username |yes |no |no |no |yes |yes |no |no """]] Notes: diff --git a/doc/todo/Attempt_to_extend_Mercurial_backend_support.mdwn b/doc/todo/Attempt_to_extend_Mercurial_backend_support.mdwn index b17960385..8ded94393 100644 --- a/doc/todo/Attempt_to_extend_Mercurial_backend_support.mdwn +++ b/doc/todo/Attempt_to_extend_Mercurial_backend_support.mdwn @@ -24,6 +24,8 @@ Diff follows, for anyone to annotate. First code version is also available at [m >> I changed the by `mercurial.pm` recorded commit messages and the `rcs_recentchanges` logic to include more information, to emulate the `git.pm` behaviour regarding name presentation on RecentChanges. I don't have anything more to add at the moment, so if the code passes review, I'm done, and I tag this page as "patch". [Final patch version as per this page at my hg repo](http://510x.se/hg/program/ikiwiki/file/bc0e2f838fe3/Plugin/mercurial.pm) ([raw format](http://46.239.104.5:81/hg/program/ikiwiki/raw-file/bc0e2f838fe3/Plugin/mercurial.pm)). I keep the below conversation for reference, but it's mostly outdated. --[[Daniel Andersson]] +[[merged|done]] --[[Joey]] + [[!tag patch]] *** -- cgit v1.2.3