Attempt to fix a `TODO` in `Automator.pm` in combination with the Mercurial backend. 1. To define hooks, Mercurial uses paths given in the config file `.hg/hgrc`. To enable Mercurial to call `ikiwiki-wrapper` automatically after blog/wiki setup, ikiwiki thus needs to create `hgrc`. 2. To reflect changes in `$config{srcdir}` and/or `$config{mercurial_wrapper}`, relevant lines in `hgrc` need to be updated on wrapper creation. ikiwiki can keep track of lines in `hgrc` for which it is responsible by adding a `.ikiwiki` suffix to its hooks. This is correct and recommended markup, Mercurial-wise. Two ways follow below. I prefer the long one. --[[Daniel Andersson]] > I comment myself: this can probably be solved without adding ad-hoc hooks and stuff (maybe not as "correct" as changing the config file only directly after wrappers have been generated, but good enough). I have a large rewrite of `mercurial.pm` ready, currently under local testing before I upload it for comments, trying to make it equal in function to `git.pm`. Comments below are of course welcome, but I will look into other ways of solving it later. Maybe `rcs_checkconfig` or `rcs_genwrapper` should host the `hgrc`-changing code. --[[Daniel Andersson]] >> Having a hook that runs after a wrapper is generated may well be a good >> thing anyway. In ikiwiki-hosting, there are some genwrapper hooks >> that don't add any code to the wrapper, but are there only to run at, >> essentially, that time. >> >> With that said, here it seems like unnecessary complexity. >> Why is `mercurial_wrapper` configurable at all? Why not just always >> write it to a specific place relative to the srcdir, and always make >> the hgrc look there? >> >> (Other rcs plugins have good reasons to make their wrappers >> configurable, because one might want the wrapper to run as a git >> post-update or post-commit hook.) --[[Joey]] Compact way (addresses only point 1) ------------------------------------ [This patch at pastebin](http://pastebin.com/by9f4dwX) ([raw version](http://pastebin.com/raw.php?i=by9f4dwX)). Set default `ikiwiki-wrapper` path. diff -r 8faf136ca94f Setup/Automator.pm --- a/Setup/Automator.pm Tue Jul 19 21:04:13 2011 +0200 +++ b/Setup/Automator.pm Wed Jul 20 15:33:21 2011 +0200 @@ -75,8 +75,7 @@ print STDERR "warning: do not know how to set up the bzr_wrapper hook!\n"; } elsif ($config{rcs} eq 'mercurial') { - # TODO - print STDERR "warning: do not know how to set up the mercurial_wrapper hook!\n"; + $config{mercurial_wrapper}=$config{srcdir}."/.hg/ikiwiki-wrapper"; } elsif ($config{rcs} eq 'tla') { # TODO Create `$config{srcdir}/.hg/hgrc` with hook info during auto-installation script. Use relative paths to not require manual `hgrc` intervention if `$config{srcdir}` is changed. If `$config{mercurial_wrapper}` is changed, manual edit of `hgrc` is needed to catch the new wrapper path. (Is there a security risk with relative paths?) > The code seems to assume that hg will be run from within the srcdir, > specifically the top of the srcdir. If it's run from somewhere else, > even a subdirectory, this will fail to find the wrapper, or could > run some other program. Unless mercurial always interprets these paths > as relative to the top of the repository? --[[Joey]] @@ -187,6 +186,22 @@ die "ikiwiki --wrappers --setup $config{dumpsetup} failed"; } + # Setup initial config file for Mercurial to hook up the wrapper. + if ($config{rcs} eq 'mercurial' && exists $config{mercurial_wrapper} + && length $config{mercurial_wrapper}) { + # Use a relative path to avoid having to manually change the + # autogenerated hgrc if the user changes $config{srcdir}. + use File::Spec; + my $mercurial_wrapper_relpath=File::Spec->abs2rel($config{mercurial_wrapper}, $config{srcdir}); + open (HGRC, '>', $config{srcdir}.'/.hg/hgrc'); + print HGRC <>$ENV{HOME}/.ikiwiki/wikilist") || die "$ENV{HOME}/.ikiwiki/wikilist: $!"; Less compact but more robust way (addresses point 1 and 2) ---------------------------------------------------------- [This complete patch at pastebin](http://pastebin.com/AcDHjbK6) ([raw version](http://pastebin.com/raw.php?i=AcDHjbK6)). This way leaks onto additional files and adds general functionality that may or may not be wanted. The main part of the extra code is contained within `mercurial.pm`, though. Set default `ikiwiki-wrapper` path. diff -r b08179653c00 IkiWiki/Setup/Automator.pm --- a/IkiWiki/Setup/Automator.pm Wed Jul 20 16:56:09 2011 +0200 +++ b/IkiWiki/Setup/Automator.pm Wed Jul 20 19:28:21 2011 +0200 @@ -75,8 +75,7 @@ print STDERR "warning: do not know how to set up the bzr_wrapper hook!\n"; } elsif ($config{rcs} eq 'mercurial') { - # TODO - print STDERR "warning: do not know how to set up the mercurial_wrapper hook!\n"; + $config{mercurial_wrapper}=$config{srcdir}."/.hg/ikiwiki-wrapper"; } elsif ($config{rcs} eq 'tla') { # TODO Create `$config{srcdir}/.hg/hgrc` during auto-installation with hook info. @@ -182,6 +181,19 @@ } } + # Setup initial config file for Mercurial to hook up the wrapper. The + # path to the wrapper will be automatically added when it is generated. + if ($config{rcs} eq 'mercurial' && exists $config{mercurial_wrapper} + && length $config{mercurial_wrapper}) { + open (HGRC, '>', $config{srcdir}.'/.hg/hgrc'); + print HGRC < "rcs", id => "rcs_diff", call => \&rcs_diff); hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime); hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime); + hook(type => "rcs", id => "rcs_wrapper_postcall", call => \&rcs_wrapper_postcall); } sub checkconfig () { Pass variable to `gen_wrapper()` to decide if `rcs_wrapper_postcall()` should run. Default is `1` to update `hgrc`, since it is done non-intrusive (won't create `hgrc` if it doesn't exist, won't overwrite anything unless it is set by ikiwiki itself). @@ -28,6 +29,7 @@ push @{$config{wrappers}}, { wrapper => $config{mercurial_wrapper}, wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"), + wrapper_postcall => (defined $config{mercurial_wrapper_hgrc_update} ? $config{mercurial_wrapper_hgrc_update} : "1"), }; } } Include default configuration value and comment. @@ -53,6 +55,13 @@ safe => 0, rebuild => 0, }, + mercurial_wrapper_hgrc_update => { + type => "string", + example => "1", + description => "updates existing hgrc to reflect path changes for mercurial_wrapper", + safe => 0, + rebuild => 0, + }, historyurl => { type => "string", example => "http://example.com:8000/log/tip/\[[file]]", `hgrc` should be updated to point to the new wrapper path. The regexp transforms lines as e.g. post-commit.ikiwiki = /home/daniel/blog/.hg/ikiwiki-wrapper-oldpath incoming.ikiwiki = /home/daniel/blog/.hg/ikiwiki-wrapper-oldpath to post-commit.ikiwiki = $config{mercurial_wrapper} incoming.ikiwiki = $config{mercurial_wrapper} with absolute paths. @@ -402,4 +411,23 @@ return findtimes($file, 0); } +sub rcs_wrapper_postcall($) { + # Update hgrc if it exists. Change post-commit/incoming hooks with the + # .ikiwiki suffix to point to the wrapper path given in the setup file. + # Work with a tempfile to not delete hgrc if the loop is interrupted + # midway. + my $hgrc=$config{srcdir}.'/.hg/hgrc'; + my $backup_suffix='.ikiwiki.bak'; + if (-e $hgrc) { + use File::Spec; + my $mercurial_wrapper_abspath=File::Spec->rel2abs($config{mercurial_wrapper}, $config{srcdir}); + local ($^I, @ARGV)=($backup_suffix, $hgrc); + while (<>) { + s/^(post-commit|incoming)(\.ikiwiki[ \t]*=[ \t]*).*$/$1$2$mercurial_wrapper_abspath/; + print; + } + unlink($hgrc.$backup_suffix); + } +} + 1 `rcs_wrapper_postcall` is made available. diff -r b08179653c00 IkiWiki.pm --- a/IkiWiki.pm Wed Jul 20 16:56:09 2011 +0200 +++ b/IkiWiki.pm Wed Jul 20 19:28:21 2011 +0200 @@ -2059,6 +2059,10 @@ $hooks{rcs}{rcs_getmtime}{call}->(@_); } +sub rcs_wrapper_postcall (@) { + $hooks{rcs}{rcs_wrapper_postcall}{call}->(@_); +} + sub rcs_receive () { $hooks{rcs}{rcs_receive}{call}->(); } `rcs_wrapper_postcall` is called if $config{wrapper_postcall} is true, which it should only be for Mercurial at the moment. diff -r b08179653c00 IkiWiki/Wrapper.pm --- a/IkiWiki/Wrapper.pm Wed Jul 20 16:56:09 2011 +0200 +++ b/IkiWiki/Wrapper.pm Wed Jul 20 19:28:21 2011 +0200 @@ -238,6 +238,10 @@ } #translators: The parameter is a filename. debug(sprintf(gettext("successfully generated %s"), $wrapper)); + + if (defined $config{wrapper_postcall} && $config{wrapper_postcall} ) { + IkiWiki::rcs_wrapper_postcall(); + } } 1