finish with rcs plugin conversion

master
Joey Hess 2008-07-26 22:27:58 -04:00
parent 14cd75746a
commit 6154dd03cb
12 changed files with 415 additions and 245 deletions

View File

@ -414,13 +414,10 @@ sub checkconfig () { #{{{
unless exists $config{wikistatedir};
if ($config{rcs}) {
eval qq{use IkiWiki::Rcs::$config{rcs}};
if ($@) {
error("Failed to load RCS module IkiWiki::Rcs::$config{rcs}: $@");
}
loadplugin($config{rcs});
}
else {
require IkiWiki::Rcs::Stub;
loadplugin("norcs");
}
if (defined $config{umask}) {
@ -1428,6 +1425,46 @@ sub run_hooks ($$) { # {{{
return 1;
} #}}}
sub rcs_update () { #{{{
$hooks{rcs}{rcs_update}{call}->(@_);
} #}}}
sub rcs_prepedit ($) { #{{{
$hooks{rcs}{rcs_prepedit}{call}->(@_);
} #}}}
sub rcs_commit ($$$;$$) { #{{{
$hooks{rcs}{rcs_commit}{call}->(@_);
} #}}}
sub rcs_commit_staged ($$$) { #{{{
$hooks{rcs}{rcs_commit_staged}{call}->(@_);
} #}}}
sub rcs_add ($) { #{{{
$hooks{rcs}{rcs_add}{call}->(@_);
} #}}}
sub rcs_remove ($) { #{{{
$hooks{rcs}{rcs_remove}{call}->(@_);
} #}}}
sub rcs_rename ($$) { #{{{
$hooks{rcs}{rcs_rename}{call}->(@_);
} #}}}
sub rcs_recentchanges ($) { #{{{
$hooks{rcs}{rcs_recentchanges}{call}->(@_);
} #}}}
sub rcs_diff ($) { #{{{
$hooks{rcs}{rcs_diff}{call}->(@_);
} #}}}
sub rcs_getctime ($) { #{{{
$hooks{rcs}{rcs_getctime}{call}->(@_);
} #}}}
sub globlist_to_pagespec ($) { #{{{
my @globlist=split(' ', shift);

View File

@ -1,6 +1,5 @@
#!/usr/bin/perl
package IkiWiki;
package IkiWiki::Plugin::bzr;
use warnings;
use strict;
@ -8,19 +7,34 @@ use IkiWiki;
use Encode;
use open qw{:utf8 :std};
hook(type => "checkconfig", id => "bzr", call => sub { #{{{
sub import { #{{{
hook(type => "checkconfig", id => "bzr", call => \&checkconfig);
hook(type => "getsetup", id => "bzr", call => \&getsetup);
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub checkconfig () { #{{{
if (! defined $config{diffurl}) {
$config{diffurl}="";
}
if (length $config{bzr_wrapper}) {
if (defined $config{bzr_wrapper} && length $config{bzr_wrapper}) {
push @{$config{wrappers}}, {
wrapper => $config{bzr_wrapper},
wrappermode => (defined $config{bzr_wrappermode} ? $config{bzr_wrappermode} : "06755"),
};
}
}); #}}}
} #}}}
hook(type => "getsetup", id => "bzr", call => sub { #{{{
sub getsetup () { #{{{
return
bzr_wrapper => {
type => "string",
@ -50,7 +64,7 @@ hook(type => "getsetup", id => "bzr", call => sub { #{{{
safe => 1,
rebuild => 1,
},
}); #}}}
} #}}}
sub bzr_log ($) { #{{{
my $out = shift;
@ -101,10 +115,10 @@ sub bzr_author ($$) { #{{{
my ($user, $ipaddr) = @_;
if (defined $user) {
return possibly_foolish_untaint($user);
return IkiWiki::possibly_foolish_untaint($user);
}
elsif (defined $ipaddr) {
return "Anonymous from ".possibly_foolish_untaint($ipaddr);
return "Anonymous from ".IkiWiki::possibly_foolish_untaint($ipaddr);
}
else {
return "Anonymous";
@ -116,7 +130,7 @@ sub rcs_commit ($$$;$$) { #{{{
$user = bzr_author($user, $ipaddr);
$message = possibly_foolish_untaint($message);
$message = IkiWiki::possibly_foolish_untaint($message);
if (! length $message) {
$message = "no message given";
}
@ -137,7 +151,7 @@ sub rcs_commit_staged ($$$) {
$user = bzr_author($user, $ipaddr);
$message = possibly_foolish_untaint($message);
$message = IkiWiki::possibly_foolish_untaint($message);
if (! length $message) {
$message = "no message given";
}
@ -172,7 +186,7 @@ sub rcs_remove ($) { # {{{
sub rcs_rename ($$) { # {{{
my ($src, $dest) = @_;
my $parent = dirname($dest);
my $parent = IkiWiki::dirname($dest);
if (system("bzr", "add", "--quiet", "$config{srcdir}/$parent") != 0) {
warn("bzr add $parent failed\n");
}

View File

@ -1,6 +1,5 @@
#!/usr/bin/perl
package IkiWiki;
package IkiWiki::Plugin::git;
use warnings;
use strict;
@ -11,7 +10,22 @@ use open qw{:utf8 :std};
my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate Git sha1sums
my $dummy_commit_msg = 'dummy commit'; # message to skip in recent changes
hook(type => "checkconfig", id => "git", call => sub { #{{{
sub import { #{{{
hook(type => "checkconfig", id => "git", call => \&checkconfig);
hook(type => "getsetup", id => "git", call => \&getsetup);
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub checkconfig () { #{{{
if (! defined $config{diffurl}) {
$config{diffurl}="";
}
@ -21,15 +35,15 @@ hook(type => "checkconfig", id => "git", call => sub { #{{{
if (! defined $config{gitmaster_branch}) {
$config{gitmaster_branch}="master";
}
if (length $config{git_wrapper}) {
if (defined $config{git_wrapper} && length $config{git_wrapper}) {
push @{$config{wrappers}}, {
wrapper => $config{git_wrapper},
wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
};
}
}); #}}}
} #}}}
hook(type => "getsetup", id => "git", call => sub { #{{{
sub getsetup () { #{{{
return
git_wrapper => {
type => "string",
@ -73,9 +87,9 @@ hook(type => "getsetup", id => "git", call => sub { #{{{
safe => 0, # paranoia
rebuild => 0,
},
}); #}}}
} #}}}
sub _safe_git (&@) { #{{{
sub safe_git (&@) { #{{{
# Start a child process safely without resorting /bin/sh.
# Return command output or success state (in scalar context).
@ -107,12 +121,12 @@ sub _safe_git (&@) { #{{{
return wantarray ? @lines : ($? == 0);
}
# Convenient wrappers.
sub run_or_die ($@) { _safe_git(\&error, @_) }
sub run_or_cry ($@) { _safe_git(sub { warn @_ }, @_) }
sub run_or_non ($@) { _safe_git(undef, @_) }
sub run_or_die ($@) { safe_git(\&error, @_) }
sub run_or_cry ($@) { safe_git(sub { warn @_ }, @_) }
sub run_or_non ($@) { safe_git(undef, @_) }
#}}}
sub _merge_past ($$$) { #{{{
sub merge_past ($$$) { #{{{
# Unlike with Subversion, Git cannot make a 'svn merge -rN:M file'.
# Git merge commands work with the committed changes, except in the
# implicit case of '-m' of git checkout(1). So we should invent a
@ -206,7 +220,7 @@ sub _merge_past ($$$) { #{{{
return $conflict;
} #}}}
sub _parse_diff_tree ($@) { #{{{
sub parse_diff_tree ($@) { #{{{
# Parse the raw diff tree chunk and return the info hash.
# See git-diff-tree(1) for the syntax.
@ -326,7 +340,7 @@ sub git_commit_info ($;$) { #{{{
my ($prefix) = run_or_die('git', 'rev-parse', '--show-prefix');
my @ci;
while (my $parsed = _parse_diff_tree(($prefix or ""), \@raw_lines)) {
while (my $parsed = parse_diff_tree(($prefix or ""), \@raw_lines)) {
push @ci, $parsed;
}
@ -379,7 +393,7 @@ sub rcs_commit ($$$;$$) { #{{{
my ($prev) = $rcstoken =~ /^($sha1_pattern)$/; # untaint
if (defined $cur && defined $prev && $cur ne $prev) {
my $conflict = _merge_past($prev, $file, $dummy_commit_msg);
my $conflict = merge_past($prev, $file, $dummy_commit_msg);
return $conflict if defined $conflict;
}
@ -402,7 +416,7 @@ sub rcs_commit_staged ($$$) {
# git commit returns non-zero if file has not been really changed.
# so we should ignore its exit status (hence run_or_non).
$message = possibly_foolish_untaint($message);
$message = IkiWiki::possibly_foolish_untaint($message);
if (run_or_non('git', 'commit', '--cleanup=verbatim',
'-q', '-m', $message)) {
if (length $config{gitorigin_branch}) {

View File

@ -1,6 +1,5 @@
#!/usr/bin/perl
package IkiWiki;
package IkiWiki::Plugin::mercurial;
use warnings;
use strict;
@ -8,19 +7,34 @@ use IkiWiki;
use Encode;
use open qw{:utf8 :std};
hook(type => "checkconfig", id => "mercurial", call => sub { #{{{
sub import { #{{{
hook(type => "checkconfig", id => "mercurial", call => \&checkconfig);
hook(type => "getsetup", id => "mercurial", call => \&getsetup);
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub checkconfig () { #{{{
if (! defined $config{diffurl}) {
$config{diffurl}="";
}
if (length $config{mercurial_wrapper}) {
if (exists $config{mercurial_wrapper} && length $config{mercurial_wrapper}) {
push @{$config{wrappers}}, {
wrapper => $config{mercurial_wrapper},
wrappermode => (defined $config{mercurial_wrappermode} ? $config{mercurial_wrappermode} : "06755"),
};
}
}); #}}}
} #}}}
hook(type => "getsetup", id => "mercurial", call => sub { #{{{
sub getsetup () { #{{{
return
mercurial_wrapper => {
type => "string",
@ -50,7 +64,7 @@ hook(type => "getsetup", id => "mercurial", call => sub { #{{{
safe => 1,
rebuild => 1,
},
}); #}}}
} #}}}
sub mercurial_log ($) { #{{{
my $out = shift;
@ -113,16 +127,16 @@ sub rcs_commit ($$$;$$) { #{{{
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
if (defined $user) {
$user = possibly_foolish_untaint($user);
$user = IkiWiki::possibly_foolish_untaint($user);
}
elsif (defined $ipaddr) {
$user = "Anonymous from ".possibly_foolish_untaint($ipaddr);
$user = "Anonymous from ".IkiWiki::possibly_foolish_untaint($ipaddr);
}
else {
$user = "Anonymous";
}
$message = possibly_foolish_untaint($message);
$message = IkiWiki::possibly_foolish_untaint($message);
if (! length $message) {
$message = "no message given";
}

View File

@ -1,6 +1,5 @@
#!/usr/bin/perl
package IkiWiki;
package IkiWiki::Plugin::monotone;
use warnings;
use strict;
@ -11,7 +10,22 @@ use Date::Format qw(time2str);
my $sha1_pattern = qr/[0-9a-fA-F]{40}/; # pattern to validate sha1sums
hook(type => "checkconfig", id => "monotone", call => sub { #{{{
sub import { #{{{
hook(type => "checkconfig", id => "monotone", call => \&checkconfig);
hook(type => "getsetup", id => "monotone", call => \&getsetup);
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub checkconfig () { #{{{
if (!defined($config{mtnrootdir})) {
$config{mtnrootdir} = $config{srcdir};
}
@ -47,9 +61,9 @@ hook(type => "checkconfig", id => "monotone", call => sub { #{{{
wrappermode => (defined $config{mtn_wrappermode} ? $config{mtn_wrappermode} : "06755"),
};
}
}); #}}}
} #}}}
hook(type => "getsetup", id => "monotone", call => sub { #{{{
sub getsetup () { #{{{
return
mtn_wrapper => {
type => "string",
@ -99,7 +113,7 @@ hook(type => "getsetup", id => "monotone", call => sub { #{{{
safe => 0, # path
rebuild => 0,
},
}); #}}}
} #}}}
sub get_rev () { #{{{
my $sha1 = `mtn --root=$config{mtnrootdir} automate get_base_revision_id`;
@ -156,7 +170,7 @@ sub mtn_merge ($$$$) { #{{{
return $mergeRev;
} #}}}
sub commit_file_to_new_rev($$$$$$$$) { #{{{
sub commit_file_to_new_rev ($$$$$$$$) { #{{{
my $automator=shift;
my $wsfilename=shift;
my $oldFileID=shift;
@ -398,7 +412,7 @@ sub rcs_commit ($$$;$$) { #{{{
if (system("mtn", "--root=$config{mtnrootdir}", "commit", "--quiet",
"--author", $author, "--key", $config{mtnkey}, "-m",
possibly_foolish_untaint($message), $file) != 0) {
IkiWiki::possibly_foolish_untaint($message), $file) != 0) {
debug("Traditional commit failed! Returning data as conflict.");
my $conflict=readfile("$config{srcdir}/$file");
if (system("mtn", "--root=$config{mtnrootdir}", "revert",
@ -443,7 +457,7 @@ sub rcs_commit_staged ($$$) {
if (system("mtn", "--root=$config{mtnrootdir}", "commit", "--quiet",
"--author", $author, "--key", $config{mtnkey}, "-m",
possibly_foolish_untaint($message)) != 0) {
IkiWiki::possibly_foolish_untaint($message)) != 0) {
error("Monotone commit failed");
}
}

View File

@ -1,99 +1,58 @@
#!/usr/bin/perl
# Stubs for no revision control.
package IkiWiki;
package IkiWiki::Plugin::norcs;
use warnings;
use strict;
use IkiWiki;
sub rcs_update () {
# Update working directory to current version.
# (May be more complex for distributed RCS.)
}
sub import { #{{{
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub rcs_prepedit ($) {
# Prepares to edit a file under revision control. Returns a token
# that must be passed into rcs_commit when the file is ready
# for committing.
# The file is relative to the srcdir.
sub rcs_update () { #{{{
} #}}}
sub rcs_prepedit ($) { #{{{
return ""
}
} #}}}
sub rcs_commit ($$$;$$) {
# Tries to commit the page; returns undef on _success_ and
# a version of the page with the rcs's conflict markers on failure.
# The file is relative to the srcdir.
sub rcs_commit ($$$;$$) { #{{{
my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
return undef # success
}
} #}}}
sub rcs_commit_staged ($$$) {
# Commits all staged changes. Changes can be staged using rcs_add,
# rcs_remove, and rcs_rename.
sub rcs_commit_staged ($$$) { #{{{
my ($message, $user, $ipaddr)=@_;
return undef # success
}
} #}}}
sub rcs_add ($) {
# Add a file. The filename is relative to the root of the srcdir.
# Note that this should not check the new file in, it should only
# prepare for it to be checked in when rcs_commit is called.
# Note that the file may be in a new subdir that is not yet added
# to version control; the subdir can be added if so.
}
sub rcs_add ($) { #{{{
} #}}}
sub rcs_remove ($) {
# Remove a file. The filename is relative to the root of the srcdir.
# Note that this should not check the removal in, it should only
# prepare for it to be checked in when rcs_commit is called.
# Note that the new file may be in a new subdir that is not yet added
# to version control; the subdir can be added if so.
}
sub rcs_remove ($) { #{{{
} #}}}
sub rcs_rename ($$) {
# Rename a file. The filenames are relative to the root of the srcdir.
# Note that this should not commit the rename, it should only
# prepare it for when rcs_commit is called.
# The new filename may be in a new subdir, that is not yet added to
# version control. If so, the subdir will exist already, and should
# be added to revision control.
}
sub rcs_rename ($$) { #{{{
} #}}}
sub rcs_recentchanges ($) {
# Examine the RCS history and generate a list of recent changes.
# The data structure returned for each change is:
# {
# rev => # the RCSs id for this commit
# user => # name of user who made the change,
# committype => # either "web" or the name of the rcs,
# when => # time when the change was made,
# message => [
# { line => "commit message line" },
# { line => "commit message line" },
# # etc,
# ],
# pages => [
# {
# page => # name of page changed,
# diffurl => # optional url to a diff showing
# # the changes,
# },
# # repeat for each page changed in this commit,
# ],
# }
}
sub rcs_recentchanges ($) { #{{{
} #}}}
sub rcs_diff ($) {
# Optional, used to get diffs for recentchanges.
# The parameter is the rev from rcs_recentchanges.
# Should return a list of lines of the diff (including \n) in list
# context, and the whole diff in scalar context.
}
sub rcs_diff ($) { #{{{
} #}}}
sub rcs_getctime ($) {
# Optional, used to get the page creation time from the RCS.
sub rcs_getctime ($) { #{{{
error gettext("getctime not implemented");
}
} #}}}
1

View File

@ -1,13 +1,27 @@
#!/usr/bin/perl
package IkiWiki;
package IkiWiki::Plugin::svn;
use warnings;
use strict;
use IkiWiki;
use POSIX qw(setlocale LC_CTYPE);
hook(type => "checkconfig", id => "svn", call => sub { #{{{
sub import { #{{{
hook(type => "checkconfig", id => "svn", call => \&checkconfig);
hook(type => "getsetup", id => "svn", call => \&getsetup);
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub checkconfig () { #{{{
if (! defined $config{diffurl}) {
$config{diffurl}="";
}
@ -20,15 +34,15 @@ hook(type => "checkconfig", id => "svn", call => sub { #{{{
$config{svnpath}=~s/\/$//;
$config{svnpath}=~s/^\///;
}
if (length $config{svn_wrapper}) {
if (defined $config{svn_wrapper} && length $config{svn_wrapper}) {
push @{$config{wrappers}}, {
wrapper => $config{svn_wrapper},
wrappermode => (defined $config{svn_wrappermode} ? $config{svn_wrappermode} : "04755"),
};
}
}); #}}}
} #}}}
hook(type => "getsetup", id => "svn", call => sub { #{{{
sub getsetup () { #{{{
return
svnrepo => {
type => "string",
@ -72,7 +86,7 @@ hook(type => "getsetup", id => "svn", call => sub { #{{{
safe => 1,
rebuild => 1,
},
}); #}}}
} #}}}
# svn needs LC_CTYPE set to a UTF-8 locale, so try to find one. Any will do.
sub find_lc_ctype() {
@ -160,7 +174,7 @@ sub rcs_commit ($$$;$$) { #{{{
if (system("svn", "commit", "--quiet",
"--encoding", "UTF-8", "-m",
possibly_foolish_untaint($message),
IkiWiki::possibly_foolish_untaint($message),
$config{srcdir}) != 0) {
my $conflict=readfile("$config{srcdir}/$file");
if (system("svn", "revert", "--quiet", "$config{srcdir}/$file") != 0) {
@ -186,7 +200,7 @@ sub rcs_commit_staged ($$$) {
if (system("svn", "commit", "--quiet",
"--encoding", "UTF-8", "-m",
possibly_foolish_untaint($message),
IkiWiki::possibly_foolish_untaint($message),
$config{srcdir}) != 0) {
warn("svn commit failed\n");
return 1; # failure
@ -199,10 +213,10 @@ sub rcs_add ($) { #{{{
my $file=shift;
if (-d "$config{srcdir}/.svn") {
my $parent=dirname($file);
my $parent=IkiWiki::dirname($file);
while (! -d "$config{srcdir}/$parent/.svn") {
$file=$parent;
$parent=dirname($file);
$parent=IkiWiki::dirname($file);
}
if (system("svn", "add", "--quiet", "$config{srcdir}/$file") != 0) {
@ -329,7 +343,7 @@ sub rcs_recentchanges ($) { #{{{
} #}}}
sub rcs_diff ($) { #{{{
my $rev=possibly_foolish_untaint(int(shift));
my $rev=IkiWiki::possibly_foolish_untaint(int(shift));
return `svnlook diff $config{svnrepo} -r$rev --no-diff-deleted`;
} #}}}

View File

@ -1,24 +1,38 @@
#!/usr/bin/perl
package IkiWiki;
package IkiWiki::Plugin::tla;
use warnings;
use strict;
use IkiWiki;
hook(type => "checkconfig", id => "tla", call => sub { #{{{
sub import { #{{{
hook(type => "checkconfig", id => "tla", call => \&checkconfig);
hook(type => "getsetup", id => "tla", call => \&getsetup);
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
hook(type => "rcs", id => "rcs_commit", call => \&rcs_commit);
hook(type => "rcs", id => "rcs_commit_staged", call => \&rcs_commit_staged);
hook(type => "rcs", id => "rcs_add", call => \&rcs_add);
hook(type => "rcs", id => "rcs_remove", call => \&rcs_remove);
hook(type => "rcs", id => "rcs_rename", call => \&rcs_rename);
hook(type => "rcs", id => "rcs_recentchanges", call => \&rcs_recentchanges);
hook(type => "rcs", id => "rcs_diff", call => \&rcs_diff);
hook(type => "rcs", id => "rcs_getctime", call => \&rcs_getctime);
} #}}}
sub checkconfig () { #{{{
if (! defined $config{diffurl}) {
$config{diffurl}="";
}
if (length $config{tla_wrapper}) {
if (defined $config{tla_wrapper} && length $config{tla_wrapper}) {
push @{$config{wrappers}}, {
wrapper => $config{tla_wrapper},
wrappermode => (defined $config{tla_wrappermode} ? $config{tla_wrappermode} : "06755"),
};
}
}); #}}}
} #}}}
hook(type => "getsetup", id => "tla", call => sub { #{{{
sub getsetup () { #{{{
return
tla_wrapper => {
type => "string",
@ -48,9 +62,9 @@ hook(type => "getsetup", id => "tla", call => sub { #{{{
safe => 1,
rebuild => 1,
},
}); #}}}
} #}}}
sub quiet_system (@) {
sub quiet_system (@) { #{{{
# See Debian bug #385939.
open (SAVEOUT, ">&STDOUT");
close STDOUT;
@ -60,7 +74,7 @@ sub quiet_system (@) {
open (STDOUT, ">&SAVEOUT");
close SAVEOUT;
return $ret;
}
} #}}}
sub rcs_update () { #{{{
if (-d "$config{srcdir}/{arch}") {
@ -110,7 +124,7 @@ sub rcs_commit ($$$;$$) { #{{{
}
if (quiet_system("tla", "commit",
"-L".possibly_foolish_untaint($message),
"-L".IkiWiki::possibly_foolish_untaint($message),
'-d', $config{srcdir}) != 0) {
my $conflict=readfile("$config{srcdir}/$file");
if (system("tla", "undo", "-n", "--quiet", "-d", "$config{srcdir}") != 0) {

4
debian/changelog vendored
View File

@ -3,9 +3,11 @@ ikiwiki (2.60) UNRELEASED; urgency=low
* Add getsetup hook, all plugins that add fields to %config should use it.
* ikiwiki --dumpsetup can generate a nice setup file snapshotting ikiwiki's
current configuration.
* Large amounts of internal config data reorg.
* The way wrappers are defined in the setup file has changed. Old setup
files will continue to work, for now.
* Version control backends promoted to first-class plugins.
-- Joey Hess <joeyh@debian.org> Mon, 21 Jul 2008 11:35:46 -0400
ikiwiki (2.55) UNRELEASED; urgency=low

View File

@ -654,15 +654,107 @@ PageSpecs glob patterns, but instead only by a special `internal()`
### RCS plugins
ikiwiki's support for [[revision_control_systems|rcs]] also uses pluggable
perl modules. These are in the `IkiWiki::RCS` namespace, for example
`IkiWiki::RCS::svn`.
ikiwiki's support for [[revision_control_systems|rcs]] is also done via
plugins. See [[RCS_details|rcs/details]] for some more info.
Each RCS plugin must support all the `IkiWiki::rcs_*` functions.
See IkiWiki::RCS::Stub for the full list of functions. It's ok if
`rcs_getctime` does nothing except for throwing an error.
RCS plugins must register a number of hooks. Each hook has type 'rcs',
and the 'id' field is set to the name of the hook. For example:
hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
See [[RCS_details|rcs/details]] for some more info.
#### `rcs_update()`
Updates the working directory with any remote changes.
#### `rcs_prepedit($)`
Is passed a file to prepare to edit. It can generate and return an arbitrary
token, that will be passed into `rcs_commit` when committing. For example,
it might return the current revision ID of the file, and use that
information later when merging changes.
#### `rcs_commit($$$;$$)`
Passed a file, message, token (from `rcs_prepedit`), user, and ip address.
Should try to commit the file. Returns `undef` on *success* and a version
of the page with the rcs's conflict markers on failure.
#### `rcs_commit_staged($$$)`
Passed a message, user, and ip address. Should commit all staged changes.
Returns undef on success, and an error message on failure.
Changes can be staged by calls to `rcs_add, `rcs_remove`, and
`rcs_rename`.
#### `rcs_add($)`
Adds the passed file to the archive. The filename is relative to the root
of the srcdir.
Note that this should not check the new file in, it should only
prepare for it to be checked in when rcs_commit (or `rcs_commit_staged`) is
called. Note that the file may be in a new subdir that is not yet in
to version control; the subdir can be added if so.
#### `rcs_remove($)`
Remove a file. The filename is relative to the root of the srcdir.
Note that this should not check the removal in, it should only prepare for it
to be checked in when `rcs_commit` (or `rcs_commit_staged`) is called. Note
that the new file may be in a new subdir that is not yet inversion
control; the subdir can be added if so.
#### `rcs_rename($$)`
Rename a file. The filenames are relative to the root of the srcdir.
Note that this should not commit the rename, it should only
prepare it for when `rcs_commit` (or `rcs_commit_staged`) is called.
The new filename may be in a new subdir, that is not yet added to
version control. If so, the subdir will exist already, and should
be added to revision control.
#### `rcs_recentchanges($)`
Examine the RCS history and generate a list of recent changes.
The parameter is how many changes to return.
The data structure returned for each change is:
{
rev => # the RCSs id for this commit
user => # name of user who made the change,
committype => # either "web" or the name of the rcs,
when => # time when the change was made,
message => [
{ line => "commit message line 1" },
{ line => "commit message line 2" },
# etc,
],
pages => [
{
page => # name of page changed,
diffurl => # optional url to a diff of changes
},
# repeat for each page changed in this commit,
],
}
#### `rcs_diff($)`
The parameter is the rev from `rcs_recentchanges`.
Should return a list of lines of the diff (including \n) in list
context, and the whole diff in scalar context.
#### `rcs_getctime($)`
This is used to get the page creation time for a file from the RCS, by looking
it up in the history.
It's ok if this is not implemented, and throws an error.
### PageSpec plugins

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-07-25 16:16-0400\n"
"POT-Creation-Date: 2008-07-26 22:24-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -50,7 +50,7 @@ msgid "%s is not an editable page"
msgstr ""
#: ../IkiWiki/CGI.pm:437 ../IkiWiki/Plugin/brokenlinks.pm:24
#: ../IkiWiki/Plugin/inline.pm:261 ../IkiWiki/Plugin/opendiscussion.pm:17
#: ../IkiWiki/Plugin/inline.pm:306 ../IkiWiki/Plugin/opendiscussion.pm:17
#: ../IkiWiki/Plugin/orphans.pm:28 ../IkiWiki/Render.pm:78
#: ../IkiWiki/Render.pm:148
msgid "discussion"
@ -71,122 +71,122 @@ msgstr ""
msgid "You are banned."
msgstr ""
#: ../IkiWiki/CGI.pm:758 ../IkiWiki/CGI.pm:759 ../IkiWiki.pm:788
#: ../IkiWiki/CGI.pm:758 ../IkiWiki/CGI.pm:759 ../IkiWiki.pm:1086
msgid "Error"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:57
#: ../IkiWiki/Plugin/aggregate.pm:76
msgid "Aggregation triggered via web."
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:66
#: ../IkiWiki/Plugin/aggregate.pm:85
msgid "Nothing to do right now, all feeds are up-to-date!"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:193
#: ../IkiWiki/Plugin/aggregate.pm:212
#, perl-format
msgid "missing %s parameter"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:227
#: ../IkiWiki/Plugin/aggregate.pm:246
msgid "new feed"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:241
#: ../IkiWiki/Plugin/aggregate.pm:260
msgid "posts"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:243
#: ../IkiWiki/Plugin/aggregate.pm:262
msgid "new"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:406
#: ../IkiWiki/Plugin/aggregate.pm:425
#, perl-format
msgid "expiring %s (%s days old)"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:413
#: ../IkiWiki/Plugin/aggregate.pm:432
#, perl-format
msgid "expiring %s"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:440
#: ../IkiWiki/Plugin/aggregate.pm:459
#, perl-format
msgid "processed ok at %s"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:444
#: ../IkiWiki/Plugin/aggregate.pm:463
#, perl-format
msgid "checking feed %s ..."
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:449
#: ../IkiWiki/Plugin/aggregate.pm:468
#, perl-format
msgid "could not find feed at %s"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:464
#: ../IkiWiki/Plugin/aggregate.pm:483
msgid "feed not found"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:475
#: ../IkiWiki/Plugin/aggregate.pm:494
#, perl-format
msgid "(invalid UTF-8 stripped from feed)"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:481
#: ../IkiWiki/Plugin/aggregate.pm:500
#, perl-format
msgid "(feed entities escaped)"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:487
#: ../IkiWiki/Plugin/aggregate.pm:506
msgid "feed crashed XML::Feed!"
msgstr ""
#: ../IkiWiki/Plugin/aggregate.pm:561
#: ../IkiWiki/Plugin/aggregate.pm:580
#, perl-format
msgid "creating new page %s"
msgstr ""
#: ../IkiWiki/Plugin/amazon_s3.pm:30
#: ../IkiWiki/Plugin/amazon_s3.pm:31
msgid "deleting bucket.."
msgstr ""
#: ../IkiWiki/Plugin/amazon_s3.pm:37 ../IkiWiki/Setup.pm:117
#: ../IkiWiki/Plugin/amazon_s3.pm:38 ../ikiwiki.in:188
msgid "done"
msgstr ""
#: ../IkiWiki/Plugin/amazon_s3.pm:46
#: ../IkiWiki/Plugin/amazon_s3.pm:93
#, perl-format
msgid "Must specify %s"
msgstr ""
#: ../IkiWiki/Plugin/amazon_s3.pm:85
#: ../IkiWiki/Plugin/amazon_s3.pm:132
msgid "Failed to create bucket in S3: "
msgstr ""
#: ../IkiWiki/Plugin/amazon_s3.pm:170
#: ../IkiWiki/Plugin/amazon_s3.pm:217
msgid "Failed to save file to S3: "
msgstr ""
#: ../IkiWiki/Plugin/amazon_s3.pm:192
#: ../IkiWiki/Plugin/amazon_s3.pm:239
msgid "Failed to delete file from S3: "
msgstr ""
#: ../IkiWiki/Plugin/attachment.pm:22
#: ../IkiWiki/Plugin/attachment.pm:34
#, perl-format
msgid "there is already a page named %s"
msgstr ""
#: ../IkiWiki/Plugin/attachment.pm:41
#: ../IkiWiki/Plugin/attachment.pm:53
msgid "prohibited by allowed_attachments"
msgstr ""
#: ../IkiWiki/Plugin/attachment.pm:144
#: ../IkiWiki/Plugin/attachment.pm:156
msgid "bad attachment filename"
msgstr ""
#: ../IkiWiki/Plugin/attachment.pm:186
#: ../IkiWiki/Plugin/attachment.pm:198
msgid "attachment upload"
msgstr ""
@ -262,33 +262,33 @@ msgstr ""
msgid "failed to determine size of image %s"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:47
#: ../IkiWiki/Plugin/inline.pm:89
msgid "Must specify url to wiki with --url when using --rss or --atom"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:101
#: ../IkiWiki/Plugin/inline.pm:146
msgid "missing pages parameter"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:149
#: ../IkiWiki/Plugin/inline.pm:194
#, perl-format
msgid "unknown sort type %s"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:220
#: ../IkiWiki/Plugin/inline.pm:265
msgid "Add a new post titled:"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:236
#: ../IkiWiki/Plugin/inline.pm:281
#, perl-format
msgid "nonexistant template %s"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:269 ../IkiWiki/Render.pm:82
#: ../IkiWiki/Plugin/inline.pm:314 ../IkiWiki/Render.pm:82
msgid "Discussion"
msgstr ""
#: ../IkiWiki/Plugin/inline.pm:506
#: ../IkiWiki/Plugin/inline.pm:551
msgid "RPC::XML::Client not found, not pinging"
msgstr ""
@ -301,11 +301,11 @@ msgstr ""
msgid "%s is locked by %s and cannot be edited"
msgstr ""
#: ../IkiWiki/Plugin/mdwn.pm:28
#: ../IkiWiki/Plugin/mdwn.pm:40
msgid "multimarkdown is enabled, but Text::MultiMarkdown is not installed"
msgstr ""
#: ../IkiWiki/Plugin/mdwn.pm:51
#: ../IkiWiki/Plugin/mdwn.pm:63
#, perl-format
msgid "failed to load Markdown.pm perl module (%s) or /usr/bin/markdown (%s)"
msgstr ""
@ -322,11 +322,11 @@ msgstr ""
msgid "redir cycle is not allowed"
msgstr ""
#: ../IkiWiki/Plugin/mirrorlist.pm:23
#: ../IkiWiki/Plugin/mirrorlist.pm:35
msgid "Mirrors"
msgstr ""
#: ../IkiWiki/Plugin/mirrorlist.pm:23
#: ../IkiWiki/Plugin/mirrorlist.pm:35
msgid "Mirror"
msgstr ""
@ -334,11 +334,15 @@ msgstr ""
msgid "more"
msgstr ""
#: ../IkiWiki/Plugin/openid.pm:45
#: ../IkiWiki/Plugin/norcs.pm:55
msgid "getctime not implemented"
msgstr ""
#: ../IkiWiki/Plugin/openid.pm:57
msgid "Log in with"
msgstr ""
#: ../IkiWiki/Plugin/openid.pm:48
#: ../IkiWiki/Plugin/openid.pm:60
msgid "Get an OpenID"
msgstr ""
@ -350,31 +354,31 @@ msgstr ""
msgid "bad or missing template"
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:223
#: ../IkiWiki/Plugin/passwordauth.pm:243
msgid "Account creation successful. Now you can Login."
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:226
#: ../IkiWiki/Plugin/passwordauth.pm:246
msgid "Error creating account."
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:233
#: ../IkiWiki/Plugin/passwordauth.pm:253
msgid "No email address, so cannot email password reset instructions."
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:265
#: ../IkiWiki/Plugin/passwordauth.pm:287
msgid "Failed to send mail"
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:267
#: ../IkiWiki/Plugin/passwordauth.pm:289
msgid "You have been mailed password reset instructions."
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:302
#: ../IkiWiki/Plugin/passwordauth.pm:324
msgid "incorrect password reset url"
msgstr ""
#: ../IkiWiki/Plugin/passwordauth.pm:305
#: ../IkiWiki/Plugin/passwordauth.pm:327
msgid "password reset denied"
msgstr ""
@ -382,21 +386,21 @@ msgstr ""
msgid "Ping received."
msgstr ""
#: ../IkiWiki/Plugin/pinger.pm:37
#: ../IkiWiki/Plugin/pinger.pm:49
msgid "requires 'from' and 'to' parameters"
msgstr ""
#: ../IkiWiki/Plugin/pinger.pm:42
#: ../IkiWiki/Plugin/pinger.pm:54
#, perl-format
msgid "Will ping %s"
msgstr ""
#: ../IkiWiki/Plugin/pinger.pm:45
#: ../IkiWiki/Plugin/pinger.pm:57
#, perl-format
msgid "Ignoring ping directive for wiki %s (this wiki is %s)"
msgstr ""
#: ../IkiWiki/Plugin/pinger.pm:61
#: ../IkiWiki/Plugin/pinger.pm:73
msgid "LWP not found, not pinging"
msgstr ""
@ -476,23 +480,23 @@ msgstr ""
msgid "%A night"
msgstr ""
#: ../IkiWiki/Plugin/prettydate.pm:78
#: ../IkiWiki/Plugin/prettydate.pm:96
msgid "at teatime on %A"
msgstr ""
#: ../IkiWiki/Plugin/prettydate.pm:82
#: ../IkiWiki/Plugin/prettydate.pm:100
msgid "at midnight"
msgstr ""
#: ../IkiWiki/Plugin/prettydate.pm:85
#: ../IkiWiki/Plugin/prettydate.pm:103
msgid "at noon on %A"
msgstr ""
#: ../IkiWiki/Plugin/recentchanges.pm:76
#: ../IkiWiki/Plugin/recentchanges.pm:95
msgid "missing page"
msgstr ""
#: ../IkiWiki/Plugin/recentchanges.pm:78
#: ../IkiWiki/Plugin/recentchanges.pm:97
#, perl-format
msgid "The page %s does not exist."
msgstr ""
@ -576,17 +580,17 @@ msgstr ""
msgid "update for rename of %s to %s"
msgstr ""
#: ../IkiWiki/Plugin/search.pm:20
#: ../IkiWiki/Plugin/search.pm:32
#, perl-format
msgid "Must specify %s when using the search plugin"
msgstr ""
#: ../IkiWiki/Plugin/search.pm:166
#: ../IkiWiki/Plugin/search.pm:178
#, perl-format
msgid "need Digest::SHA1 to index %s"
msgstr ""
#: ../IkiWiki/Plugin/search.pm:201
#: ../IkiWiki/Plugin/search.pm:213
msgid "search"
msgstr ""
@ -688,10 +692,6 @@ msgstr ""
msgid "failed to generate image from code"
msgstr ""
#: ../IkiWiki/Rcs/Stub.pm:96
msgid "getctime not implemented"
msgstr ""
#: ../IkiWiki/Render.pm:276 ../IkiWiki/Render.pm:297
#, perl-format
msgid "skipping bad filename %s"
@ -739,23 +739,11 @@ msgstr ""
#. translators: The first parameter is a filename, and the second
#. translators: is a (probably not translated) error message.
#: ../IkiWiki/Setup.pm:25
#: ../IkiWiki/Setup.pm:23
#, perl-format
msgid "cannot read %s: %s"
msgstr ""
#: ../IkiWiki/Setup.pm:58
msgid "generating wrappers.."
msgstr ""
#: ../IkiWiki/Setup.pm:107
msgid "rebuilding wiki.."
msgstr ""
#: ../IkiWiki/Setup.pm:110
msgid "refreshing wiki.."
msgstr ""
#: ../IkiWiki/Wrapper.pm:16
#, perl-format
msgid "%s doesn't seem to be executable"
@ -792,23 +780,31 @@ msgstr ""
msgid "usage: ikiwiki [options] source dest"
msgstr ""
#: ../ikiwiki.in:82
#: ../ikiwiki.in:79
msgid "usage: --set var=value"
msgstr ""
#: ../IkiWiki.pm:126
#: ../ikiwiki.in:118
msgid "generating wrappers.."
msgstr ""
#: ../ikiwiki.in:177
msgid "rebuilding wiki.."
msgstr ""
#: ../ikiwiki.in:180
msgid "refreshing wiki.."
msgstr ""
#: ../IkiWiki.pm:410
msgid "Must specify url to wiki with --url when using --cgi"
msgstr ""
#. translators: The first parameter is a
#. translators: preprocessor directive name,
#. translators: the second a page name, the
#. translators: third a number.
#: ../IkiWiki.pm:771
#: ../IkiWiki.pm:1069
#, perl-format
msgid "%s preprocessing loop detected on %s at depth %i"
msgid "preprocessing loop detected on %s at depth %i"
msgstr ""
#: ../IkiWiki.pm:1219
#: ../IkiWiki.pm:1557
msgid "yes"
msgstr ""

View File

@ -6,7 +6,7 @@ use Test::More;
my @progs="ikiwiki.in";
my @libs="IkiWiki.pm";
# monotone, external, amazon_s3 skipped since they need perl modules
push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v IkiWiki/Rcs/monotone.pm | grep -v IkiWiki/Plugin/external.pm | grep -v IkiWiki/Plugin/amazon_s3.pm`;
push @libs, map { chomp; $_ } `find IkiWiki -type f -name \\*.pm | grep -v monotone.pm | grep -v external.pm | grep -v amazon_s3.pm`;
plan(tests => (@progs + @libs));