Merge branch 'master' of ssh://git.ikiwiki.info
[ikiwiki] / doc / todo / bzr.mdwn
1 This is mostly based on the Mercurial plugin (in fact, apart from the commands
2 being run, only the name of the rcs was changed in rcs_recentchanges, and
3 rcs_commit was only changed to work around bzr's lack of a switch to set the
4 username). bzr_log could probably be written better by someone better at perl,
5 and rcs_getctime and rcs_notify aren't written at all. --[[bma]]
6
7 (rcs_notify is not needed in this branch --[[Joey]])
8
9     #!/usr/bin/perl
10     
11     use warnings;
12     use strict;
13     use IkiWiki;
14     use Encode;
15     use open qw{:utf8 :std};
16     
17     package IkiWiki;
18     
19     sub bzr_log($) {
20             my $out = shift;
21     
22             my @lines = <$out>;
23     
24             my @entries = split(/\n-+\s/,join("", @lines));
25     
26             my @ret = ();
27     
28             foreach my $entry (@entries) {
29     
30                     my ($initial,$i) = split(/message:/,$entry,2);
31                     my ($message, $j, $files) = split(/(added|modified|removed):/,$i,3);
32                     $message =~ s/\n/\\n/g;
33                     $files =~ s/\n//g;
34                     $entry = $initial . "\ndescription: " . $message . "\nfiles: " . $files;
35     
36                     my @lines = split(/\n/,$entry);
37                     shift(@lines);
38     
39                     my %entry;
40                     foreach (@lines) {
41                             my ($key,$value) = split(/: /);
42                             $entry{$key} = $value;
43                     }
44                     $entry{description}=~s/\\n/\n/g;
45                     $entry{files}=~s/\s\s+/\ /g;
46                     $entry{files}=~s/^\s+//g;
47     
48                     $ret[@ret] = {
49                             "description" =>  $entry{description},
50                             "user" => $entry{committer},
51                             "files" => $entry{files},
52                             "date" => $entry{timestamp},
53                     }
54             }
55     
56             return @ret;
57     }
58     
59     sub rcs_update () {
60             # Not needed.
61     }
62     
63     sub rcs_prepedit ($) {
64             return "";
65     }
66     
67     sub rcs_commit ($$$;$$) {
68             my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
69     
70             if (defined $user) {
71                     $user = possibly_foolish_untaint($user);
72             }
73             elsif (defined $ipaddr) {
74                     $user = "Anonymous from ".possibly_foolish_untaint($ipaddr);
75             }
76             else {
77                     $user = "Anonymous";
78             }
79     
80             $message = possibly_foolish_untaint($message);
81             if (! length $message) {
82                     $message = "no message given";
83             }
84     
85             my $olduser = `bzr whoami`;
86             chomp $olduser;
87             system("bzr","whoami",$user); # This will set the branch username; there doesn't seem to be a way to do it on a per-commit basis.
88                                           # Save the old one and restore after the commit.
89             my @cmdline = ("bzr", "commit", "-m", $message, $config{srcdir}."/".$file);
90             if (system(@cmdline) != 0) {
91                     warn "'@cmdline' failed: $!";
92             }
93     
94             $olduser=possibly_foolish_untaint($olduser);
95             system("bzr","whoami",$olduser);
96     
97             return undef; # success
98     }
99     
100     sub rcs_add ($) {
101             my ($file) = @_;
102     
103             my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file");
104             if (system(@cmdline) != 0) {
105                     warn "'@cmdline' failed: $!";
106             }
107     }
108     
109     sub rcs_recentchanges ($) {
110             my ($num) = @_;
111     
112             eval q{use CGI 'escapeHTML'};
113             error($@) if $@;
114     
115             my @cmdline = ("bzr", "log", "--long", "--verbose", "--limit", $num,$config{srcdir});
116             open (my $out, "@cmdline |");
117     
118             eval q{use Date::Parse};
119             error($@) if $@;
120     
121             my @ret;
122             foreach my $info (bzr_log($out)) {
123                     my @pages = ();
124                     my @message = ();
125     
126                     foreach my $msgline (split(/\n/, $info->{description})) {
127                             push @message, { line => $msgline };
128                     }
129     
130                     foreach my $file (split / /,$info->{files}) {
131                             my $diffurl = $config{'diffurl'};
132                             $diffurl =~ s/\[\[file\]\]/$file/go;
133                             $diffurl =~ s/\[\[r2\]\]/$info->{changeset}/go;
134     
135                             push @pages, {
136                                     page => pagename($file),
137                                     diffurl => $diffurl,
138                             };
139                     }
140     
141                     my $user = $info->{"user"};
142                     $user =~ s/\s*<.*>\s*$//;
143                     $user =~ s/^\s*//;
144     
145                     push @ret, {
146                             rev        => $info->{"changeset"},
147                             user       => $user,
148                             committype => "bzr",
149                             when       => time - str2time($info->{"date"}),
150                             message    => [@message],
151                             pages      => [@pages],
152                     };
153             }
154     
155             return @ret;
156     }
157     
158     sub rcs_notify () {
159             # TODO
160     }
161     
162     sub rcs_getctime ($) {
163             # TODO
164     }
165     
166     1
167
168
169 [[patch]]
170
171
172 > Thanks for doing this.
173 > bzr 0.90 has support for --author to commit to set the author for one commit at a time,
174 > you might like to use that instead of changing the global username (which is racy).
175 >
176 > Wouter van Heyst and I were also working on a plugin for bzr, but we were waiting for
177 > the smart server to grow the ability to run server side hooks, so that you can edit locally
178 > and then push to rebuild the wiki, but there is no need to stop this going in in the mean
179 > time.
180 > Thanks again --[[JamesWestby]]
181
182 >> I didn't know about --author, it doesn't seem to be mentioned in the manual.
183 >> I'd update the patch to reflect this, but it breaks with the version of bzr
184 >> from Stable, and also the one I'm currently using from backports.org.
185
186 >>> It's new (in fact I'm not even sure that it made it in to 0.90, it might be in 0.91 due
187 >>> in a couple of weeks.
188 >>> I was just noting it for a future enhancement. --[[JamesWestby]]
189
190 > I've just posted another patch with support for bzr, including support for 
191 > --author and a testsuite to git://git.samba.org/jelmer/ikiwiki.git. I hadn't 
192 > seen this page earlier.  --[[jelmer]]
193
194 > I used jelmer's patch --[[done]]! --[[Joey]]