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