(no commit message)
[ikiwiki.git] / doc / todo / Auto-setup_and_maintain_Mercurial_wrapper_hooks.mdwn
1 Attempt to fix a `TODO` in `Automator.pm` in combination with the Mercurial backend.
2
3 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`.
4 2. To reflect changes in `$config{srcdir}` and/or `$config{mercurial_wrapper}`, relevant lines in `hgrc` need to be updated on wrapper creation.
5
6 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.
7
8 Two ways follow below. I prefer the long one. --[[Daniel Andersson]]
9
10 Compact way (addresses only point 1)
11 ------------------------------------
12 [This patch at pastebin](http://pastebin.com/by9f4dwX) ([raw version](http://pastebin.com/raw.php?i=by9f4dwX)).
13
14 Set default `ikiwiki-wrapper` path.
15
16         diff -r 8faf136ca94f Setup/Automator.pm
17         --- a/Setup/Automator.pm        Tue Jul 19 21:04:13 2011 +0200
18         +++ b/Setup/Automator.pm        Wed Jul 20 15:33:21 2011 +0200
19         @@ -75,8 +75,7 @@
20                                 print STDERR "warning: do not know how to set up the bzr_wrapper hook!\n";
21                         }
22                         elsif ($config{rcs} eq 'mercurial') {
23         -                       # TODO
24         -                       print STDERR "warning: do not know how to set up the mercurial_wrapper hook!\n";
25         +                       $config{mercurial_wrapper}=$config{srcdir}."/.hg/ikiwiki-wrapper";
26                         }
27                         elsif ($config{rcs} eq 'tla') {
28                                 # TODO
29
30 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.
31
32 (Is there a security risk with relative paths?)
33
34         @@ -187,6 +186,22 @@
35                         die "ikiwiki --wrappers --setup $config{dumpsetup} failed";
36                 }
37          
38         +       # Setup initial config file for Mercurial to hook up the wrapper.
39         +       if ($config{rcs} eq 'mercurial' && exists $config{mercurial_wrapper}
40         +               && length $config{mercurial_wrapper}) {
41         +               # Use a relative path to avoid having to manually change the
42         +               # autogenerated hgrc if the user changes $config{srcdir}.
43         +               use File::Spec;
44         +               my $mercurial_wrapper_relpath=File::Spec->abs2rel($config{mercurial_wrapper}, $config{srcdir});
45         +               open (HGRC, '>', $config{srcdir}.'/.hg/hgrc');
46         +               print HGRC <<EOF;
47         +[hooks]
48         +post-commit.ikiwiki = $mercurial_wrapper_relpath
49         +incoming.ikiwiki = $mercurial_wrapper_relpath
50         +EOF
51         +               close (HGRC);
52         +       }
53         +
54                 # Add it to the wikilist.
55                 mkpath("$ENV{HOME}/.ikiwiki");
56                 open (WIKILIST, ">>$ENV{HOME}/.ikiwiki/wikilist") || die "$ENV{HOME}/.ikiwiki/wikilist: $!";
57
58
59 Less compact but more robust way (addresses point 1 and 2)
60 ----------------------------------------------------------
61 [This complete patch at pastebin](http://pastebin.com/AcDHjbK6) ([raw version](http://pastebin.com/raw.php?i=AcDHjbK6)).
62
63 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.
64
65 Set default `ikiwiki-wrapper` path.
66
67         diff -r b08179653c00 IkiWiki/Setup/Automator.pm
68         --- a/IkiWiki/Setup/Automator.pm        Wed Jul 20 16:56:09 2011 +0200
69         +++ b/IkiWiki/Setup/Automator.pm        Wed Jul 20 19:28:21 2011 +0200
70         @@ -75,8 +75,7 @@
71                                 print STDERR "warning: do not know how to set up the bzr_wrapper hook!\n";
72                         }
73                         elsif ($config{rcs} eq 'mercurial') {
74         -                       # TODO
75         -                       print STDERR "warning: do not know how to set up the mercurial_wrapper hook!\n";
76         +                       $config{mercurial_wrapper}=$config{srcdir}."/.hg/ikiwiki-wrapper";
77                         }
78                         elsif ($config{rcs} eq 'tla') {
79                                 # TODO
80
81 Create `$config{srcdir}/.hg/hgrc` during auto-installation with hook info.
82
83         @@ -182,6 +181,19 @@
84                         }
85                 }
86                 
87         +       # Setup initial config file for Mercurial to hook up the wrapper. The
88         +       # path to the wrapper will be automatically added when it is generated.
89         +       if ($config{rcs} eq 'mercurial' && exists $config{mercurial_wrapper}
90         +               && length $config{mercurial_wrapper}) {
91         +               open (HGRC, '>', $config{srcdir}.'/.hg/hgrc');
92         +               print HGRC <<EOF;
93         +[hooks]
94         +post-commit.ikiwiki = 
95         +incoming.ikiwiki = 
96         +EOF
97         +               close (HGRC);
98         +       }
99         +
100                 # Add wrappers, make live.
101                 if (system("ikiwiki", "--wrappers", "--setup", $config{dumpsetup}) != 0) {
102                         die "ikiwiki --wrappers --setup $config{dumpsetup} failed";
103
104 `hgrc` is setup initially. Below follows code to keep `hgrc` updated.
105
106 Add backend specific function `rcs_wrapper_postcall()` for later call in `Wrappers.pm`.
107
108         diff -r b08179653c00 IkiWiki/Plugin/mercurial.pm
109         --- a/IkiWiki/Plugin/mercurial.pm       Wed Jul 20 16:56:09 2011 +0200
110         +++ b/IkiWiki/Plugin/mercurial.pm       Wed Jul 20 19:28:21 2011 +0200
111         @@ -21,6 +21,7 @@
112                 hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
113                 hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
114                 hook(type => "rcs", id => "rcs_getmtime", call => \&rcs_getmtime);
115         +       hook(type => "rcs", id => "rcs_wrapper_postcall", call => \&rcs_wrapper_postcall);
116          }
117          
118          sub checkconfig () {
119
120 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).
121
122         @@ -28,6 +29,7 @@
123                         push @{$config{wrappers}}, {
124                                 wrapper => $config{mercurial_wrapper},
125                                 wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"),
126         +                       wrapper_postcall => (defined $config{mercurial_wrapper_hgrc_update} ? $config{mercurial_wrapper_hgrc_update} : "1"),
127                         };
128                 }
129          }
130
131 Include default configuration value and comment.
132
133         @@ -53,6 +55,13 @@
134                                 safe => 0,
135                                 rebuild => 0,
136                         },
137         +               mercurial_wrapper_hgrc_update => {
138         +                       type => "string",
139         +                       example => "1",
140         +                       description => "updates existing hgrc to reflect path changes for mercurial_wrapper",
141         +                       safe => 0,
142         +                       rebuild => 0,
143         +               },
144                         historyurl => {
145                                 type => "string",
146                                 example => "http://example.com:8000/log/tip/\[[file]]",
147
148 `hgrc` should be updated to point to the new wrapper path. The regexp transforms lines as e.g.
149
150         post-commit.ikiwiki = /home/daniel/blog/.hg/ikiwiki-wrapper-oldpath
151         incoming.ikiwiki = /home/daniel/blog/.hg/ikiwiki-wrapper-oldpath
152
153 to
154
155         post-commit.ikiwiki = $config{mercurial_wrapper}
156         incoming.ikiwiki = $config{mercurial_wrapper}
157
158 with absolute paths.
159
160         @@ -402,4 +411,23 @@
161                 return findtimes($file, 0);
162          }
163          
164         +sub rcs_wrapper_postcall($) {
165         +       # Update hgrc if it exists. Change post-commit/incoming hooks with the
166         +       # .ikiwiki suffix to point to the wrapper path given in the setup file.
167         +       # Work with a tempfile to not delete hgrc if the loop is interrupted
168         +       # midway.
169         +       my $hgrc=$config{srcdir}.'/.hg/hgrc';
170         +       my $backup_suffix='.ikiwiki.bak';
171         +       if (-e $hgrc) {
172         +               use File::Spec;
173         +               my $mercurial_wrapper_abspath=File::Spec->rel2abs($config{mercurial_wrapper}, $config{srcdir});
174         +               local ($^I, @ARGV)=($backup_suffix, $hgrc);
175         +               while (<>) {
176         +                       s/^(post-commit|incoming)(\.ikiwiki[ \t]*=[ \t]*).*$/$1$2$mercurial_wrapper_abspath/;
177         +                       print;
178         +               }
179         +               unlink($hgrc.$backup_suffix);
180         +       }
181         +}
182         +
183          1
184
185 `rcs_wrapper_postcall` is made available.
186
187         diff -r b08179653c00 IkiWiki.pm
188         --- a/IkiWiki.pm        Wed Jul 20 16:56:09 2011 +0200
189         +++ b/IkiWiki.pm        Wed Jul 20 19:28:21 2011 +0200
190         @@ -2059,6 +2059,10 @@
191                 $hooks{rcs}{rcs_getmtime}{call}->(@_);
192          }
193          
194         +sub rcs_wrapper_postcall (@) {
195         +       $hooks{rcs}{rcs_wrapper_postcall}{call}->(@_);
196         +}
197         +
198          sub rcs_receive () {
199                 $hooks{rcs}{rcs_receive}{call}->();
200          }
201
202
203 `rcs_wrapper_postcall` is called if $config{wrapper_postcall} is true, which it should only be for Mercurial at the moment.
204
205         diff -r b08179653c00 IkiWiki/Wrapper.pm
206         --- a/IkiWiki/Wrapper.pm        Wed Jul 20 16:56:09 2011 +0200
207         +++ b/IkiWiki/Wrapper.pm        Wed Jul 20 19:28:21 2011 +0200
208         @@ -238,6 +238,10 @@
209                 }
210                 #translators: The parameter is a filename.
211                 debug(sprintf(gettext("successfully generated %s"), $wrapper));
212         +
213         +       if (defined $config{wrapper_postcall} && $config{wrapper_postcall} ) {
214         +               IkiWiki::rcs_wrapper_postcall();
215         +       }
216          }
217          
218          1