2 package IkiWiki
::Plugin
::bzr
;
8 use open qw{:utf8
:std
};
11 hook
(type
=> "checkconfig", id
=> "bzr", call
=> \
&checkconfig
);
12 hook
(type
=> "getsetup", id
=> "bzr", call
=> \
&getsetup
);
13 hook
(type
=> "rcs", id
=> "rcs_update", call
=> \
&rcs_update
);
14 hook
(type
=> "rcs", id
=> "rcs_prepedit", call
=> \
&rcs_prepedit
);
15 hook
(type
=> "rcs", id
=> "rcs_commit", call
=> \
&rcs_commit
);
16 hook
(type
=> "rcs", id
=> "rcs_commit_staged", call
=> \
&rcs_commit_staged
);
17 hook
(type
=> "rcs", id
=> "rcs_add", call
=> \
&rcs_add
);
18 hook
(type
=> "rcs", id
=> "rcs_remove", call
=> \
&rcs_remove
);
19 hook
(type
=> "rcs", id
=> "rcs_rename", call
=> \
&rcs_rename
);
20 hook
(type
=> "rcs", id
=> "rcs_recentchanges", call
=> \
&rcs_recentchanges
);
21 hook
(type
=> "rcs", id
=> "rcs_diff", call
=> \
&rcs_diff
);
22 hook
(type
=> "rcs", id
=> "rcs_getctime", call
=> \
&rcs_getctime
);
23 hook
(type
=> "rcs", id
=> "rcs_getmtime", call
=> \
&rcs_getmtime
);
27 if (defined $config{bzr_wrapper
} && length $config{bzr_wrapper
}) {
28 push @
{$config{wrappers
}}, {
29 wrapper
=> $config{bzr_wrapper
},
30 wrappermode
=> (defined $config{bzr_wrappermode
} ?
$config{bzr_wrappermode
} : "06755"),
38 safe
=> 0, # rcs plugin
44 #example => "", # FIXME add example
45 description
=> "bzr post-commit hook to generate",
52 description
=> "mode for bzr_wrapper (can safely be made suid)",
58 #example => "", # FIXME add example
59 description
=> "url to show file history, using loggerhead ([[file]] substituted)",
65 example
=> "http://example.com/revision?start_revid=[[r2]]#[[file]]-s",
66 description
=> "url to view a diff, using loggerhead ([[file]] and [[r2]] substituted)",
81 if ($line =~ /^message:/) {
85 elsif ($line =~ /^(modified|added|renamed|renamed and modified|removed):/) {
87 $info{$key} = "" unless defined $info{$key};
89 elsif (defined($key) and $line =~ /^ (.*)/) {
90 $info{$key} .= "$1\n";
92 elsif ($line eq "------------------------------------------------------------\n") {
93 push @infos, {%info} if keys %info;
97 elsif ($line =~ /: /) {
99 if ($line =~ /^revno: (\d+)/) {
104 ($key, $value) = split /: +/, $line, 2;
106 $info{$key} = $value;
110 push @infos, {%info} if keys %info;
116 my @cmdline = ("bzr", "update", "--quiet", $config{srcdir
});
117 if (system(@cmdline) != 0) {
118 warn "'@cmdline' failed: $!";
122 sub rcs_prepedit
($) {
129 return unless defined $session;
131 my $user=$session->param("name");
132 my $ipaddr=$session->remote_addr();
135 return IkiWiki
::possibly_foolish_untaint
($user);
137 elsif (defined $ipaddr) {
138 return "Anonymous from ".IkiWiki
::possibly_foolish_untaint
($ipaddr);
148 my $user=bzr_author
($params{session
});
150 $params{message
} = IkiWiki
::possibly_foolish_untaint
($params{message
});
151 if (! length $params{message
}) {
152 $params{message
} = "no message given";
155 my @cmdline = ("bzr", "commit", "--quiet", "-m", $params{message
},
156 (defined $user ?
("--author", $user) : ()),
157 $config{srcdir
}."/".$params{file
});
158 if (system(@cmdline) != 0) {
159 warn "'@cmdline' failed: $!";
162 return undef; # success
165 sub rcs_commit_staged
(@
) {
168 my $user=bzr_author
($params{session
});
170 $params{message
} = IkiWiki
::possibly_foolish_untaint
($params{message
});
171 if (! length $params{message
}) {
172 $params{message
} = "no message given";
175 my @cmdline = ("bzr", "commit", "--quiet", "-m", $params{message
},
176 (defined $user ?
("--author", $user) : ()),
178 if (system(@cmdline) != 0) {
179 warn "'@cmdline' failed: $!";
182 return undef; # success
188 my @cmdline = ("bzr", "add", "--quiet", "$config{srcdir}/$file");
189 if (system(@cmdline) != 0) {
190 warn "'@cmdline' failed: $!";
197 my @cmdline = ("bzr", "rm", "--force", "--quiet", "$config{srcdir}/$file");
198 if (system(@cmdline) != 0) {
199 warn "'@cmdline' failed: $!";
203 sub rcs_rename
($$) {
204 my ($src, $dest) = @_;
206 my $parent = IkiWiki
::dirname
($dest);
207 if (system("bzr", "add", "--quiet", "$config{srcdir}/$parent") != 0) {
208 warn("bzr add $parent failed\n");
211 my @cmdline = ("bzr", "mv", "--quiet", "$config{srcdir}/$src", "$config{srcdir}/$dest");
212 if (system(@cmdline) != 0) {
213 warn "'@cmdline' failed: $!";
217 sub rcs_recentchanges
($) {
220 my @cmdline = ("bzr", "log", "-v", "--show-ids", "--limit", $num,
222 open (my $out, "@cmdline |");
224 eval q{use Date::Parse};
228 foreach my $info (bzr_log
($out)) {
232 foreach my $msgline (split(/\n/, $info->{message
})) {
233 push @message, { line
=> $msgline };
236 foreach my $file (split(/\n/, $info->{files
})) {
237 my ($filename, $fileid) = ($file =~ /^(.*?) +([^ ]+)$/);
240 next if ($filename =~ /\/$/);
242 # Skip source name in renames
243 $filename =~ s/^.* => //;
245 my $diffurl = defined $config{'diffurl'} ?
$config{'diffurl'} : "";
246 $diffurl =~ s/\[\[file\]\]/$filename/go;
247 $diffurl =~ s/\[\[file-id\]\]/$fileid/go;
248 $diffurl =~ s/\[\[r2\]\]/$info->{revno}/go;
251 page
=> pagename
($filename),
256 my $user = $info->{"committer"};
257 if (defined($info->{"author"})) { $user = $info->{"author"}; }
258 $user =~ s/\s*<.*>\s*$//;
262 rev
=> $info->{"revno"},
265 when => str2time
($info->{"timestamp"}),
266 message
=> [@message],
275 my $taintedrev=shift;
277 my ($rev) = $taintedrev =~ /^(\d+(\.\d+)*)$/; # untaint
279 my $prevspec = "before:" . $rev;
280 my $revspec = "revno:" . $rev;
281 my @cmdline = ("bzr", "diff", "--old", $config{srcdir
},
282 "--new", $config{srcdir
},
283 "-r", $prevspec . ".." . $revspec);
284 open (my $out, "@cmdline |");
286 while (my $line=<$out>) {
287 last if defined $maxlines && @lines == $maxlines;
294 return join("", @lines);
298 sub extract_timestamp
(@
) {
299 open (my $out, "-|", @_);
300 my @log = bzr_log
($out);
302 if (length @log < 1) {
306 eval q{use Date::Parse};
309 my $time = str2time
($log[0]->{"timestamp"});
313 sub rcs_getctime
($) {
316 my @cmdline = ("bzr", "log", "--forward", "--limit", '1', "$config{srcdir}/$file");
317 return extract_timestamp
(@cmdline);
320 sub rcs_getmtime
($) {
323 my @cmdline = ("bzr", "log", "--limit", '1', "$config{srcdir}/$file");
324 return extract_timestamp
(@cmdline);