From f35d35abe36166893f68061a1fcb2a26bc056fbc Mon Sep 17 00:00:00 2001 From: David Riebenbauer Date: Sat, 30 Jan 2010 18:22:32 +0100 Subject: Automatically create tag pages, if "tag_autocreate=1" is set in the configuration. The pages will be created in tagbase, if and only if they do not exist in the srcdir yet. Tag pages will be create from "autotag.tmpl". At this stage a second refresh is needed for the tag pages to be rendered. Add autotag.tmpl template. --- IkiWiki/Plugin/tag.pm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index cdcfaf536..6c43a053d 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -36,6 +36,13 @@ sub getsetup () { safe => 1, rebuild => 1, }, + tag_autocreate => { + type => "boolean", + example => 0, + description => "Autocreate new tag pages", + safe => 1, + rebuild => 1, + }, } sub tagpage ($) { @@ -59,6 +66,21 @@ sub taglink ($$$;@) { return htmllink($page, $destpage, tagpage($tag), %opts); } +sub gentag ($) { + my $tag=shift; + if (defined $config{tag_autocreate} && $config{tag_autocreate}) { + my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); + $tagfile=~s/^\///; + return if (srcfile($tagfile,1)); + + debug(sprintf(gettext("creating tag page %s"), $tag)); + + my $template=template("autotag.tmpl"); + $template->param(tag => $tag); + writefile($tagfile, $config{srcdir}, $template->output); + } +} + sub preprocess_tag (@) { if (! @_) { return ""; @@ -72,6 +94,10 @@ sub preprocess_tag (@) { foreach my $tag (keys %params) { $tag=linkpage($tag); $tags{$page}{$tag}=1; + + # add tagpage if necessary + gentag($tag); + # hidden WikiLink add_link($page, tagpage($tag)); } -- cgit v1.2.3 From a8d313aba1094fc6d976c9ba3d09f58b768435c5 Mon Sep 17 00:00:00 2001 From: David Riebenbauer Date: Sun, 31 Jan 2010 01:12:20 +0100 Subject: Use add_autofile() in tag.pm to make the automatically created tagpages render. --- IkiWiki/Plugin/tag.pm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 6c43a053d..90833fd9c 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -78,6 +78,8 @@ sub gentag ($) { my $template=template("autotag.tmpl"); $template->param(tag => $tag); writefile($tagfile, $config{srcdir}, $template->output); + + IkiWiki::add_autofile("$config{srcdir}/$tagfile"); } } -- cgit v1.2.3 From 25741100b0a0d81ae5113dfabe5a1ed84cdf8746 Mon Sep 17 00:00:00 2001 From: David Riebenbauer Date: Tue, 2 Feb 2010 12:12:23 +0100 Subject: Export add_autofile() for use in Plugins. --- IkiWiki.pm | 2 +- IkiWiki/Plugin/tag.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki.pm b/IkiWiki.pm index ad9fb7c79..7d7f430b3 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -23,7 +23,7 @@ our @EXPORT = qw(hook debug error template htmlpage deptype htmllink readfile writefile pagetype srcfile pagename displaytime will_render gettext urlto targetpage add_underlay pagetitle titlepage linkpage newpagefile - inject add_link + inject add_link add_autofile %config %links %pagestate %wikistate %renderedfiles %pagesources %destsources); our $VERSION = 3.00; # plugin interface version, next is ikiwiki version diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 90833fd9c..c0b7feb23 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -79,7 +79,7 @@ sub gentag ($) { $template->param(tag => $tag); writefile($tagfile, $config{srcdir}, $template->output); - IkiWiki::add_autofile("$config{srcdir}/$tagfile"); + add_autofile("$config{srcdir}/$tagfile"); } } -- cgit v1.2.3 From a358d74bef51dae31332ff27e897fe04834571e6 Mon Sep 17 00:00:00 2001 From: David Riebenbauer Date: Wed, 3 Feb 2010 04:29:10 +0100 Subject: Check for existence off srcfile in add_autofile add_autofile has to have checks, whether to create the file, anyway, so this will make things more consistent. Correcter check for the result of verify_src_file(). Cosmetic rename of a variable $addfile to $autofile. --- IkiWiki.pm | 11 ++++++++--- IkiWiki/Plugin/tag.pm | 5 ++--- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki.pm b/IkiWiki.pm index 90e623330..56c491339 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1897,9 +1897,14 @@ sub add_link ($$) { } sub add_autofile ($) { - my $addfile=shift; - my ($file,$page) = verify_src_file($addfile,$config{srcdir}); - if ($page) { + my $autofile=shift; + + if (srcfile($autofile, 1)) { + return 0; + } + + my ($file, $page) = verify_src_file("$config{srcdir}/$autofile", $config{srcdir}); + if (defined $file) { push @autofiles, $file; } } diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index c0b7feb23..c6c99ae45 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -71,15 +71,14 @@ sub gentag ($) { if (defined $config{tag_autocreate} && $config{tag_autocreate}) { my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); $tagfile=~s/^\///; - return if (srcfile($tagfile,1)); + + return if (! add_autofile($tagfile)); debug(sprintf(gettext("creating tag page %s"), $tag)); my $template=template("autotag.tmpl"); $template->param(tag => $tag); writefile($tagfile, $config{srcdir}, $template->output); - - add_autofile("$config{srcdir}/$tagfile"); } } -- cgit v1.2.3 From 981400177d68a279f485727be3f013e68f0bf691 Mon Sep 17 00:00:00 2001 From: David Riebenbauer Date: Sat, 3 Apr 2010 21:10:16 +0200 Subject: Make sure deleted tag pages don't get recreated. The reason to do this is basically a user interaction design decision. It is achieved by adding an entry, associated to the creating plugin, to %pagestate. To find out if files were deleted a new global hash %del_hash is %introduced. --- IkiWiki.pm | 19 +++++++++++++++---- IkiWiki/Plugin/tag.pm | 2 +- IkiWiki/Render.pm | 5 ++++- 3 files changed, 20 insertions(+), 6 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki.pm b/IkiWiki.pm index 1770703a5..966a3bbc6 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -14,7 +14,7 @@ use open qw{:utf8 :std}; use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase %pagestate %wikistate %renderedfiles %oldrenderedfiles %pagesources %destsources %depends %depends_simple %hooks - %forcerebuild %loaded_plugins @autofiles}; + %forcerebuild %loaded_plugins %autofiles %del_hash}; use Exporter q{import}; our @EXPORT = qw(hook debug error template htmlpage deptype @@ -1895,17 +1895,28 @@ sub add_link ($$) { unless grep { $_ eq $link } @{$links{$page}}; } -sub add_autofile ($) { +sub add_autofile ($$) { my $autofile=shift; + my $plugin=shift; if (srcfile($autofile, 1)) { return 0; } my ($file, $page) = verify_src_file("$config{srcdir}/$autofile", $config{srcdir}); - if (defined $file) { - push @autofiles, $file; + + if ((!defined $file) || + (exists $pagestate{$page}{$plugin}{autofile_deleted})) { + return 0; + } + + if (exists $del_hash{$file}) { + $pagestate{$page}{$plugin}{autofile_deleted}=1; + return 0; } + + $autofiles{$file}=$plugin; + return 1; } sub pagespec_translate ($) { diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index c6c99ae45..fdd63d637 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -72,7 +72,7 @@ sub gentag ($) { my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); $tagfile=~s/^\///; - return if (! add_autofile($tagfile)); + return if (! add_autofile($tagfile, "tag")); debug(sprintf(gettext("creating tag page %s"), $tag)); diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index fc71c8919..0c21455fb 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -637,12 +637,14 @@ sub refresh () { my ($changed, $internal_changed)=find_changed($files); run_hooks(needsbuild => sub { shift->($changed) }); my $oldlink_targets=calculate_old_links($changed, $del); + %del_hash = map { $_ => 1 } @{$del}; foreach my $file (@$changed) { scan($file); } - while (my $autofile = shift (@autofiles)) { + while (my $autofile = shift @{[keys %autofiles]}) { + my $plugin=$autofiles{$autofile}; my $page=pagename($autofile); if ($pages->{$page}) { debug(sprintf(gettext("%s has multiple possible source pages"), $page)); @@ -654,6 +656,7 @@ sub refresh () { push @{$changed}, $autofile if find_changed([$autofile]); scan($autofile); + delete $autofiles{$autofile}; } calculate_links(); -- cgit v1.2.3 From c1a42e76bc6667bfb2882a12d53c25d9f952ca82 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Fri, 2 Apr 2010 00:28:02 +0100 Subject: implement typed links; add tagged_is_strict config option --- IkiWiki.pm | 58 ++++++++++++++++++---- IkiWiki/Plugin/tag.pm | 36 +++++++++----- IkiWiki/Render.pm | 33 ++++++++++++ .../tagged__40____41___matching_wikilinks.mdwn | 3 ++ doc/ikiwiki/pagespec.mdwn | 3 ++ doc/plugins/tag.mdwn | 5 ++ doc/plugins/write.mdwn | 21 +++++++- t/index.t | 17 +++++-- t/tag.t | 45 +++++++++++++++++ 9 files changed, 193 insertions(+), 28 deletions(-) create mode 100755 t/tag.t (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki.pm b/IkiWiki.pm index 6739ba56c..25e9247b2 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -14,7 +14,7 @@ use open qw{:utf8 :std}; use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase %pagestate %wikistate %renderedfiles %oldrenderedfiles %pagesources %destsources %depends %depends_simple %hooks - %forcerebuild %loaded_plugins}; + %forcerebuild %loaded_plugins %typedlinks %oldtypedlinks}; use Exporter q{import}; our @EXPORT = qw(hook debug error template htmlpage deptype @@ -24,7 +24,7 @@ our @EXPORT = qw(hook debug error template htmlpage deptype add_underlay pagetitle titlepage linkpage newpagefile inject add_link %config %links %pagestate %wikistate %renderedfiles - %pagesources %destsources); + %pagesources %destsources %typedlinks); our $VERSION = 3.00; # plugin interface version, next is ikiwiki version our $version='unknown'; # VERSION_AUTOREPLACE done by Makefile, DNE our $installdir='/usr'; # INSTALLDIR_AUTOREPLACE done by Makefile, DNE @@ -1503,7 +1503,7 @@ sub loadindex () { if (! $config{rebuild}) { %pagesources=%pagemtime=%oldlinks=%links=%depends= %destsources=%renderedfiles=%pagecase=%pagestate= - %depends_simple=(); + %depends_simple=%typedlinks=%oldtypedlinks=(); } my $in; if (! open ($in, "<", "$config{wikistatedir}/indexdb")) { @@ -1569,6 +1569,14 @@ sub loadindex () { if (exists $d->{state}) { $pagestate{$page}=$d->{state}; } + if (exists $d->{typedlinks}) { + $typedlinks{$page}=$d->{typedlinks}; + + while (my ($type, $links) = each %{$typedlinks{$page}}) { + next unless %$links; + $oldtypedlinks{$page}{$type} = {%$links}; + } + } } $oldrenderedfiles{$page}=[@{$d->{dest}}]; } @@ -1617,6 +1625,10 @@ sub saveindex () { $index{page}{$src}{depends_simple} = $depends_simple{$page}; } + if (exists $typedlinks{$page} && %{$typedlinks{$page}}) { + $index{page}{$src}{typedlinks} = $typedlinks{$page}; + } + if (exists $pagestate{$page}) { foreach my $id (@hookids) { foreach my $key (keys %{$pagestate{$page}{$id}}) { @@ -1926,12 +1938,17 @@ sub inject { use warnings; } -sub add_link ($$) { +sub add_link ($$;$) { my $page=shift; my $link=shift; + my $type=shift; push @{$links{$page}}, $link unless grep { $_ eq $link } @{$links{$page}}; + + if (defined $type) { + $typedlinks{$page}{$type}{$link} = 1; + } } sub pagespec_translate ($) { @@ -2212,6 +2229,11 @@ sub match_link ($$;@) { $link=derel($link, $params{location}); my $from=exists $params{location} ? $params{location} : ''; + my $linktype=$params{linktype}; + my $qualifier=''; + if (defined $linktype) { + $qualifier=" with type $linktype"; + } my $links = $IkiWiki::links{$page}; return IkiWiki::FailReason->new("$page has no links", $page => $IkiWiki::DEPEND_LINKS, "" => 1) @@ -2219,19 +2241,33 @@ sub match_link ($$;@) { my $bestlink = IkiWiki::bestlink($from, $link); foreach my $p (@{$links}) { if (length $bestlink) { - return IkiWiki::SuccessReason->new("$page links to $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1) - if $bestlink eq IkiWiki::bestlink($page, $p); + if ((!defined $linktype || exists $IkiWiki::typedlinks{$page}{$linktype}{$p}) && $bestlink eq IkiWiki::bestlink($page, $p)) { + return IkiWiki::SuccessReason->new("$page links to $link$qualifier", $page => $IkiWiki::DEPEND_LINKS, "" => 1) + } } else { - return IkiWiki::SuccessReason->new("$page links to page $p matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1) - if match_glob($p, $link, %params); + if ((!defined $linktype || exists $IkiWiki::typedlinks{$page}{$linktype}{$p}) && match_glob($p, $link, %params)) { + return IkiWiki::SuccessReason->new("$page links to page $p$qualifier, matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1) + } my ($p_rel)=$p=~/^\/?(.*)/; $link=~s/^\///; - return IkiWiki::SuccessReason->new("$page links to page $p_rel matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1) - if match_glob($p_rel, $link, %params); + if ((!defined $linktype || exists $IkiWiki::typedlinks{$page}{$linktype}{$p_rel}) && match_glob($p_rel, $link, %params)) { + return IkiWiki::SuccessReason->new("$page links to page $p_rel$qualifier, matching $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1) + } } } - return IkiWiki::FailReason->new("$page does not link to $link", $page => $IkiWiki::DEPEND_LINKS, "" => 1); + return IkiWiki::FailReason->new("$page does not link to $link$qualifier", $page => $IkiWiki::DEPEND_LINKS, "" => 1); +} + +sub match_typedlink($$;@) { + my $page = shift; + my $args = shift; + + if ($args =~ /^(\w+)\s+(.*)$/) { + return match_link($page, $2, @_, linktype => $1); + } + + return IkiWiki::ErrorReason->new("typedlink expects e.g. 'tag *' but got: $args"); } sub match_backlink ($$;@) { diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index cdcfaf536..af4bff1bc 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -6,8 +6,6 @@ use warnings; use strict; use IkiWiki 3.00; -my %tags; - sub import { hook(type => "getopt", id => "tag", call => \&getopt); hook(type => "getsetup", id => "tag", call => \&getsetup); @@ -36,6 +34,13 @@ sub getsetup () { safe => 1, rebuild => 1, }, + tagged_is_strict => { + type => "boolean", + default => 0, + description => "if 1, tagged() doesn't match normal WikiLinks to tag pages", + safe => 1, + rebuild => 1, + }, } sub tagpage ($) { @@ -71,9 +76,8 @@ sub preprocess_tag (@) { foreach my $tag (keys %params) { $tag=linkpage($tag); - $tags{$page}{$tag}=1; # hidden WikiLink - add_link($page, tagpage($tag)); + add_link($page, tagpage($tag), 'tag'); } return ""; @@ -87,15 +91,13 @@ sub preprocess_taglink (@) { return join(" ", map { if (/(.*)\|(.*)/) { my $tag=linkpage($2); - $tags{$params{page}}{$tag}=1; - add_link($params{page}, tagpage($tag)); + add_link($params{page}, tagpage($tag), 'tag'); return taglink($params{page}, $params{destpage}, $tag, linktext => pagetitle($1)); } else { my $tag=linkpage($_); - $tags{$params{page}}{$tag}=1; - add_link($params{page}, tagpage($tag)); + add_link($params{page}, tagpage($tag), 'tag'); return taglink($params{page}, $params{destpage}, $tag); } } @@ -110,17 +112,19 @@ sub pagetemplate (@) { my $destpage=$params{destpage}; my $template=$params{template}; + my $tags = $typedlinks{$page}{tag}; + $template->param(tags => [ map { link => taglink($page, $destpage, $_, rel => "tag") - }, sort keys %{$tags{$page}} - ]) if exists $tags{$page} && %{$tags{$page}} && $template->query(name => "tags"); + }, sort keys %$tags + ]) if defined $tags && %$tags && $template->query(name => "tags"); if ($template->query(name => "categories")) { # It's an rss/atom template. Add any categories. - if (exists $tags{$page} && %{$tags{$page}}) { + if (defined $tags && %$tags) { $template->param(categories => [map { category => $_ }, - sort keys %{$tags{$page}}]); + sort keys %$tags]); } } } @@ -130,7 +134,13 @@ package IkiWiki::PageSpec; sub match_tagged ($$;@) { my $page = shift; my $glob = shift; - return match_link($page, IkiWiki::Plugin::tag::tagpage($glob)); + + if ($IkiWiki::config{tagged_is_strict}) { + return match_link($page, IkiWiki::Plugin::tag::tagpage($glob), linktype => 'tag'); + } + else { + return match_link($page, IkiWiki::Plugin::tag::tagpage($glob)); + } } 1 diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index abafb0887..5810fc974 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -167,6 +167,7 @@ sub scan ($) { else { $links{$page}=[]; } + delete $typedlinks{$page}; run_hooks(scan => sub { shift->( @@ -398,6 +399,7 @@ sub find_del_files ($) { push @del, $pagesources{$page}; } $links{$page}=[]; + delete $typedlinks{$page}; $renderedfiles{$page}=[]; $pagemtime{$page}=0; } @@ -499,6 +501,29 @@ sub remove_unrendered () { } } +sub link_types_changed ($$) { + # each is of the form { type => { link => 1 } } + my $new = shift; + my $old = shift; + + return 0 if !defined $new && !defined $old; + return 1 if !defined $new || !defined $old; + + while (my ($type, $links) = each %$new) { + foreach my $link (keys %$links) { + return 1 unless exists $old{$type}{$link}; + } + } + + while (my ($type, $links) = each %$old) { + foreach my $link (keys %$links) { + return 1 unless exists $new{$type}{$link}; + } + } + + return 0; +} + sub calculate_changed_links ($$$) { my ($changed, $del, $oldlink_targets)=@_; @@ -525,6 +550,14 @@ sub calculate_changed_links ($$$) { } $linkchangers{lc($page)}=1; } + + # we currently assume that changing the type of a link doesn't + # change backlinks + if (!exists $linkchangers{lc($page)}) { + if (link_types_changed($typedlinks{$page}, $oldlinktypes{$page})) { + $linkchangers{lc($page)}=1; + } + } } return \%backlinkchanged, \%linkchangers; diff --git a/doc/bugs/tagged__40____41___matching_wikilinks.mdwn b/doc/bugs/tagged__40____41___matching_wikilinks.mdwn index e7e4af7c3..9037d6c02 100644 --- a/doc/bugs/tagged__40____41___matching_wikilinks.mdwn +++ b/doc/bugs/tagged__40____41___matching_wikilinks.mdwn @@ -28,6 +28,9 @@ rationale on this, or what am I doing wrong, and how to achieve what I want? >> is valid. [[todo/matching_different_kinds_of_links]] is probably >> how it will eventually be solved. --[[Joey]] +>>> [[Done]]: you can now set the `tagged_is_strict` config option to `1` +>>> if you don't want `tagged` to match other wikilinks. --[[smcv]] + > And this is an illustration why a clean work-around (without changing the software) is not possible: while thinking about [[todo/matching_different_kinds_of_links]], I thought one could work around the problem by simply explicitly including the kind of the relation into the link target (like the tagbase in tags), and by having a separate page without the "tagbase" to link to when one wants simply to refer to the tag without tagging. But this won't work: one has to at least once refer to the real tag page if one wants to talk about it, and this reference will count as tagging (unwanted). --Ivan Z. > But well, perhaps there is a workaround without introducing different kinds of links. One could modify the [[tag plugin|plugins/tag]] so that it adds 2 links to a page: for tagging -- `tagbase/TAG`, and for navigation -- `tagdescription/TAG` (displayed at the bottom). Then the `tagdescription/TAG` page would hold whatever list one wishes (with `tagged(TAG)` in the pagespec), and whenever one wants to merely refer to the tag, one should link to `tagdescription/TAG`--this link won't count as tagging. So, `tagbase/TAG` would become completely auxiliary (internal) link targets for ikiwiki, the users would edit or link to only `tagdescription/TAG`. --Ivan Z. diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn index 5c191f23f..ca6693024 100644 --- a/doc/ikiwiki/pagespec.mdwn +++ b/doc/ikiwiki/pagespec.mdwn @@ -52,6 +52,9 @@ Some more elaborate limits can be added to what matches using these functions: specified IP address. * "`postcomment(glob)`" - matches only when comments are being posted to a page matching the specified glob +* "`typedlink(type glob)`" - matches pages that link to a given page (or glob) + with a given link type. Plugins can create links with a specific type: + for instance, the tag plugin creates links of type `tag`. For example, to match all pages in a blog that link to the page about music and were written in 2005: diff --git a/doc/plugins/tag.mdwn b/doc/plugins/tag.mdwn index 8ff70a069..8cd79da41 100644 --- a/doc/plugins/tag.mdwn +++ b/doc/plugins/tag.mdwn @@ -8,6 +8,11 @@ These directives allow tagging pages. It also provides the `tagged()` [[ikiwiki/PageSpec]], which can be used to match pages that are tagged with a specific tag. +If the `tagged_is_strict` config option is set, `tagged()` will only match +tags explicitly set with [[ikiwiki/directive/tag]] or +[[ikiwiki/directive/taglink]]; if not (the default), it will also match +any other [[WikiLinks|ikiwiki/WikiLink]] to the tag page. + [[!if test="enabled(tag)" then=""" This wiki has the tag plugin enabled, so you'll see a note below that this page is tagged with the "tags" tag. diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 96a2aa16d..fe7cf0183 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -633,6 +633,22 @@ reference. Do not modify this hash directly; call `add_link()`. $links{"foo"} = ["bar", "baz"]; +### `%typedlinks` + +The `%typedlinks` hash records links of specific types. Do not modify this +hash directly; call `add_link()`. The keys are page names, and the values +are hash references. In each page's hash reference, the keys are link types +defined by plugins, and the values are hash references with link targets +as keys, and 1 as a dummy value, something like this: + + $typedlinks{"foo"} = { + tag => { short_word => 1, metasyntactic_variable => 1 }, + next_page => { bar => 1 }, + }; + +Ordinary [[WikiLinks|ikiwiki/WikiLink]] appear in `%links`, but not in +`%typedlinks`. + ### `%pagesources` The `%pagesources` has can be used to look up the source filename @@ -939,11 +955,14 @@ Optionally, a third parameter can be passed, to specify the preferred filename of the page. For example, `targetpage("foo", "rss", "feed")` will yield something like `foo/feed.rss`. -### `add_link($$)` +### `add_link($$;$)` This adds a link to `%links`, ensuring that duplicate links are not added. Pass it the page that contains the link, and the link text. +An optional third parameter sets the link type (`undef` produces an ordinary +[[ikiwiki/WikiLink]]). + ## Miscellaneous ### Internal use pages diff --git a/t/index.t b/t/index.t index 2f23524a7..44273059d 100755 --- a/t/index.t +++ b/t/index.t @@ -4,7 +4,7 @@ use strict; use IkiWiki; package IkiWiki; # use internal variables -use Test::More tests => 27; +use Test::More tests => 31; $config{wikistatedir}="/tmp/ikiwiki-test.$$"; system "rm -rf $config{wikistatedir}"; @@ -31,6 +31,7 @@ $renderedfiles{"bar"}=["bar.html", "bar.rss", "sparkline-foo.gif"]; $renderedfiles{"bar.png"}=["bar.png"]; $links{"Foo"}=["bar.png"]; $links{"bar"}=["Foo", "new-page"]; +$typedlinks{"bar"}={tag => {"Foo" => 1}}; $links{"bar.png"}=[]; $depends{"Foo"}={}; $depends{"bar"}={"foo*" => 1}; @@ -45,7 +46,7 @@ ok(-s "$config{wikistatedir}/indexdb", "index file created"); # Clear state. %oldrenderedfiles=%pagectime=(); -%pagesources=%pagemtime=%oldlinks=%links=%depends= +%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks= %destsources=%renderedfiles=%pagecase=%pagestate=(); ok(loadindex(), "load index"); @@ -104,10 +105,16 @@ is_deeply(\%destsources, { "sparkline-foo.gif" => "bar", "bar.png" => "bar.png", }, "%destsources generated correctly"); +is_deeply(\%typedlinks, { + bar => {tag => {"Foo" => 1}}, +}, "%typedlinks loaded correctly"); +is_deeply(\%oldtypedlinks, { + bar => {tag => {"Foo" => 1}}, +}, "%oldtypedlinks loaded correctly"); # Clear state. %oldrenderedfiles=%pagectime=(); -%pagesources=%pagemtime=%oldlinks=%links=%depends= +%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks= %destsources=%renderedfiles=%pagecase=%pagestate=(); # When state is loaded for a wiki rebuild, only ctime and oldrenderedfiles @@ -140,5 +147,9 @@ is_deeply(\%pagecase, { }, "%pagecase generated correctly"); is_deeply(\%destsources, { }, "%destsources generated correctly"); +is_deeply(\%typedlinks, { +}, "%typedlinks cleared correctly"); +is_deeply(\%oldtypedlinks, { +}, "%oldtypedlinks cleared correctly"); system "rm -rf $config{wikistatedir}"; diff --git a/t/tag.t b/t/tag.t new file mode 100755 index 000000000..3383fd475 --- /dev/null +++ b/t/tag.t @@ -0,0 +1,45 @@ +#!/usr/bin/perl +package IkiWiki; + +use warnings; +use strict; +use Test::More tests => 10; + +BEGIN { use_ok("IkiWiki"); } +BEGIN { use_ok("IkiWiki::Plugin::tag"); } + +ok(! system("rm -rf t/tmp; mkdir t/tmp")); + +$config{userdir} = "users"; +$config{tagbase} = "tags"; +$config{tagged_is_strict} = 1; + +%oldrenderedfiles=%pagectime=(); +%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks= +%destsources=%renderedfiles=%pagecase=%pagestate=(); + +foreach my $page (qw(tags/numbers tags/letters one two alpha beta)) { + $pagesources{$page} = "$page.mdwn"; + $pagemtime{$page} = $pagectime{$page} = 1000000; +} + +$links{one}=[qw(tags/numbers alpha tags/letters)]; +$links{two}=[qw(tags/numbers)]; +$links{alpha}=[qw(tags/letters one)]; +$links{beta}=[qw(tags/letters)]; +$typedlinks{one}={tag => {"tags/numbers" => 1 }}; +$typedlinks{two}={tag => {"tags/numbers" => 1 }}; +$typedlinks{alpha}={tag => {"tags/letters" => 1 }}; +$typedlinks{beta}={tag => {"tags/letters" => 1 }}; + +ok(pagespec_match("one", "tagged(numbers)")); +ok(!pagespec_match("two", "tagged(alpha)")); +ok(pagespec_match("one", "link(tags/numbers)")); +ok(pagespec_match("one", "link(alpha)")); + +ok(pagespec_match("one", "typedlink(tag tags/numbers)")); +ok(!pagespec_match("one", "typedlink(tag tags/letters)")); +# invalid syntax +ok(pagespec_match("one", "typedlink(tag)")->isa("IkiWiki::ErrorReason")); + +1; -- cgit v1.2.3 From ef6344144051ed70649ccbff01bcc4fce927ee2f Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sun, 4 Apr 2010 00:24:27 +0100 Subject: Remove tagged_is_strict option, and just behave as though it was enabled Jon was worried about the backwards-compatibility break involved in making tagged() not match non-tag links, but Joey seems less concerned about it. --- IkiWiki/Plugin/tag.pm | 17 +---------------- doc/bugs/tagged__40____41___matching_wikilinks.mdwn | 3 +-- doc/plugins/tag.mdwn | 5 ----- t/tag.t | 1 - 4 files changed, 2 insertions(+), 24 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index af4bff1bc..7a85874f6 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -34,13 +34,6 @@ sub getsetup () { safe => 1, rebuild => 1, }, - tagged_is_strict => { - type => "boolean", - default => 0, - description => "if 1, tagged() doesn't match normal WikiLinks to tag pages", - safe => 1, - rebuild => 1, - }, } sub tagpage ($) { @@ -132,15 +125,7 @@ sub pagetemplate (@) { package IkiWiki::PageSpec; sub match_tagged ($$;@) { - my $page = shift; - my $glob = shift; - - if ($IkiWiki::config{tagged_is_strict}) { - return match_link($page, IkiWiki::Plugin::tag::tagpage($glob), linktype => 'tag'); - } - else { - return match_link($page, IkiWiki::Plugin::tag::tagpage($glob)); - } + return match_link($_[0], IkiWiki::Plugin::tag::tagpage($_[1]), linktype => 'tag'); } 1 diff --git a/doc/bugs/tagged__40____41___matching_wikilinks.mdwn b/doc/bugs/tagged__40____41___matching_wikilinks.mdwn index 9037d6c02..a211654f1 100644 --- a/doc/bugs/tagged__40____41___matching_wikilinks.mdwn +++ b/doc/bugs/tagged__40____41___matching_wikilinks.mdwn @@ -28,8 +28,7 @@ rationale on this, or what am I doing wrong, and how to achieve what I want? >> is valid. [[todo/matching_different_kinds_of_links]] is probably >> how it will eventually be solved. --[[Joey]] ->>> [[Done]]: you can now set the `tagged_is_strict` config option to `1` ->>> if you don't want `tagged` to match other wikilinks. --[[smcv]] +>>> [[Done]]: `tagged` no longer matches other wikilinks. --[[smcv]] > And this is an illustration why a clean work-around (without changing the software) is not possible: while thinking about [[todo/matching_different_kinds_of_links]], I thought one could work around the problem by simply explicitly including the kind of the relation into the link target (like the tagbase in tags), and by having a separate page without the "tagbase" to link to when one wants simply to refer to the tag without tagging. But this won't work: one has to at least once refer to the real tag page if one wants to talk about it, and this reference will count as tagging (unwanted). --Ivan Z. diff --git a/doc/plugins/tag.mdwn b/doc/plugins/tag.mdwn index 8cd79da41..8ff70a069 100644 --- a/doc/plugins/tag.mdwn +++ b/doc/plugins/tag.mdwn @@ -8,11 +8,6 @@ These directives allow tagging pages. It also provides the `tagged()` [[ikiwiki/PageSpec]], which can be used to match pages that are tagged with a specific tag. -If the `tagged_is_strict` config option is set, `tagged()` will only match -tags explicitly set with [[ikiwiki/directive/tag]] or -[[ikiwiki/directive/taglink]]; if not (the default), it will also match -any other [[WikiLinks|ikiwiki/WikiLink]] to the tag page. - [[!if test="enabled(tag)" then=""" This wiki has the tag plugin enabled, so you'll see a note below that this page is tagged with the "tags" tag. diff --git a/t/tag.t b/t/tag.t index 3383fd475..cf3bbdf01 100755 --- a/t/tag.t +++ b/t/tag.t @@ -12,7 +12,6 @@ ok(! system("rm -rf t/tmp; mkdir t/tmp")); $config{userdir} = "users"; $config{tagbase} = "tags"; -$config{tagged_is_strict} = 1; %oldrenderedfiles=%pagectime=(); %pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks= -- cgit v1.2.3 From b7d50abc0f3dbe99d2a3664c12ea95d24bfcf04b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 17 Apr 2010 13:35:15 -0400 Subject: refactor autofiles Made add_autofile take a generator function, and just register the autofile, for later possible creation. The testing is moved into Render, which allows cleaning up some stuff. --- IkiWiki.pm | 35 ++++++++++------------------------ IkiWiki/Plugin/tag.pm | 12 ++++++------ IkiWiki/Render.pm | 52 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 54 insertions(+), 45 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki.pm b/IkiWiki.pm index 3812961dc..c22c75df8 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -15,7 +15,7 @@ use vars qw{%config %links %oldlinks %pagemtime %pagectime %pagecase %pagestate %wikistate %renderedfiles %oldrenderedfiles %pagesources %destsources %depends %depends_simple %hooks %forcerebuild %loaded_plugins %typedlinks %oldtypedlinks - %autofiles %del_hash}; + %autofiles}; use Exporter q{import}; our @EXPORT = qw(hook debug error template htmlpage deptype @@ -1956,6 +1956,15 @@ sub add_link ($$;$) { } } +sub add_autofile ($$$) { + my $file=shift; + my $plugin=shift; + my $generator=shift; + + $autofiles{$file}{plugin}=$plugin; + $autofiles{$file}{generator}=$generator; +} + sub sortspec_translate ($$) { my $spec = shift; my $reverse = shift; @@ -2021,30 +2030,6 @@ sub sortspec_translate ($$) { return eval 'sub { '.$code.' }'; } -sub add_autofile ($$) { - my $autofile=shift; - my $plugin=shift; - - if (srcfile($autofile, 1)) { - return 0; - } - - my ($file, $page) = verify_src_file("$config{srcdir}/$autofile", $config{srcdir}); - - if ((!defined $file) || - (exists $pagestate{$page}{$plugin}{autofile_deleted})) { - return 0; - } - - if (exists $del_hash{$file}) { - $pagestate{$page}{$plugin}{autofile_deleted}=1; - return 0; - } - - $autofiles{$file}=$plugin; - return 1; -} - sub pagespec_translate ($) { my $spec=shift; diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 9e6f417bf..7a918a4e8 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -70,13 +70,13 @@ sub gentag ($) { my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); $tagfile=~s/^\///; - return if (! add_autofile($tagfile, "tag")); + add_autofile($tagfile, sub { + debug(sprintf(gettext("creating tag page %s"), $tag)); - debug(sprintf(gettext("creating tag page %s"), $tag)); - - my $template=template("autotag.tmpl"); - $template->param(tag => $tag); - writefile($tagfile, $config{srcdir}, $template->output); + my $template=template("autotag.tmpl"); + $template->param(tag => $tag); + writefile($tagfile, $config{srcdir}, $template->output); + }); } } diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index c80030deb..83242a197 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -680,6 +680,37 @@ sub render_backlinks ($) { } } +sub gen_autofile ($$$) { + my $autofile=shift; + my $pages=shift; + my $del=shift; + + if (srcfile($autofile, 1)) { + return 0; + } + + my ($file, $page) = verify_src_file("$config{srcdir}/$autofile", $config{srcdir}); + + if ((!defined $file) || + (exists $wikistate{$autofiles{$autofile}{plugin}}{autofile_deleted})) { + return 0; + } + + if ($pages->{$page}) { + return 0; + } + + if (grep { $_ eq $file } @$del) { + $wikistate{$autofiles{$autofile}{generator}}{autofile_deleted}=1; + return 0; + } + + $autofiles{$autofile}{generator}->(); + $pages->{$page}=1; + return 1; +} + + sub refresh () { srcdir_check(); run_hooks(refresh => sub { shift->() }); @@ -689,26 +720,19 @@ sub refresh () { my ($changed, $internal_changed)=find_changed($files); run_hooks(needsbuild => sub { shift->($changed) }); my $oldlink_targets=calculate_old_links($changed, $del); - %del_hash = map { $_ => 1 } @{$del}; foreach my $file (@$changed) { scan($file); } - while (my $autofile = shift @{[keys %autofiles]}) { - my $plugin=$autofiles{$autofile}; - my $page=pagename($autofile); - if ($pages->{$page}) { - debug(sprintf(gettext("%s has multiple possible source pages"), $page)); + foreach my $autofile (keys %autofiles) { + if (gen_autofile($autofile, $pages, $del)) { + push @{$files}, $autofile; + push @{$new}, $autofile if find_new_files([$autofile]); + push @{$changed}, $autofile if find_changed([$autofile]); + + scan($autofile); } - $pages->{$page}=1; - - push @{$files}, $autofile; - push @{$new}, $autofile if find_new_files([$autofile]); - push @{$changed}, $autofile if find_changed([$autofile]); - - scan($autofile); - delete $autofiles{$autofile}; } calculate_links(); -- cgit v1.2.3 From adc196a8b53c0b0b4f9ec4cbcea85ba37e421b59 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 17 Apr 2010 15:40:39 -0400 Subject: tag_autocreate fixups Fix style of prompt. Optional to rebuild when it is changed. (Needed to get new all missing tags) --- IkiWiki/Plugin/tag.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 7a918a4e8..1145a9f13 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -37,9 +37,9 @@ sub getsetup () { tag_autocreate => { type => "boolean", example => 0, - description => "Autocreate new tag pages", + description => "autocreate new tag pages?", safe => 1, - rebuild => 1, + rebuild => undef, }, } @@ -66,7 +66,7 @@ sub taglink ($$$;@) { sub gentag ($) { my $tag=shift; - if (defined $config{tag_autocreate} && $config{tag_autocreate}) { + if ($config{tag_autocreate}) { my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); $tagfile=~s/^\///; -- cgit v1.2.3 From 3651e6263c55a0b6184fe46c856a96740621361f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 17 Apr 2010 15:43:58 -0400 Subject: fix autofile call --- IkiWiki/Plugin/tag.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 1145a9f13..957b012ef 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -70,7 +70,7 @@ sub gentag ($) { my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); $tagfile=~s/^\///; - add_autofile($tagfile, sub { + add_autofile($tagfile, "tag", sub { debug(sprintf(gettext("creating tag page %s"), $tag)); my $template=template("autotag.tmpl"); -- cgit v1.2.3 From b00d8771cc212349ca886401bc68facdf08e0d3c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 17 Apr 2010 15:48:00 -0400 Subject: call gentag for taglinks too --- IkiWiki/Plugin/tag.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 957b012ef..9f6df5fc4 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -45,7 +45,7 @@ sub getsetup () { sub tagpage ($) { my $tag=shift; - + if ($tag !~ m{^\.?/} && defined $config{tagbase}) { $tag="/".$config{tagbase}."/".$tag; @@ -96,7 +96,6 @@ sub preprocess_tag (@) { # hidden WikiLink add_link($page, tagpage($tag), 'tag'); - # add tagpage if necessary gentag($tag); } @@ -112,12 +111,14 @@ sub preprocess_taglink (@) { if (/(.*)\|(.*)/) { my $tag=linkpage($2); add_link($params{page}, tagpage($tag), 'tag'); + gentag($tag); return taglink($params{page}, $params{destpage}, $tag, linktext => pagetitle($1)); } else { my $tag=linkpage($_); add_link($params{page}, tagpage($tag), 'tag'); + gentag($tag); return taglink($params{page}, $params{destpage}, $tag); } } -- cgit v1.2.3 From 2fc342b048d23d8355631000b7285fb5d26b258a Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 17 Apr 2010 16:01:41 -0400 Subject: fix autotag behavior for relative tags A tag like ./foo is searched for relative to the tagging page. However, if multiple pages use such a tag, the only one sure to be in common is in the root, so autocreate it there to avoid scattering redunadant autocreated tags around the tree. (This is probably not ideal.) Also renamed the tagpage and taglink functions for clarity. --- IkiWiki/Plugin/tag.pm | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 9f6df5fc4..d2a3d4dfd 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -43,7 +43,7 @@ sub getsetup () { }, } -sub tagpage ($) { +sub taglink ($) { my $tag=shift; if ($tag !~ m{^\.?/} && @@ -55,20 +55,28 @@ sub tagpage ($) { return $tag; } -sub taglink ($$$;@) { +sub htmllink_tag ($$$;@) { my $page=shift; my $destpage=shift; my $tag=shift; my %opts=@_; - return htmllink($page, $destpage, tagpage($tag), %opts); + return htmllink($page, $destpage, taglink($tag), %opts); } sub gentag ($) { my $tag=shift; + if ($config{tag_autocreate}) { - my $tagfile = newpagefile(tagpage($tag), $config{default_pageext}); - $tagfile=~s/^\///; + my $tagpage=taglink($tag); + if ($tagpage=~/^\.\/(.*)/) { + $tagpage=$1; + } + else { + $tagpage=~s/^\///; + } + + my $tagfile = newpagefile($tagpage, $config{default_pageext}); add_autofile($tagfile, "tag", sub { debug(sprintf(gettext("creating tag page %s"), $tag)); @@ -94,7 +102,7 @@ sub preprocess_tag (@) { $tag=linkpage($tag); # hidden WikiLink - add_link($page, tagpage($tag), 'tag'); + add_link($page, taglink($tag), 'tag'); gentag($tag); } @@ -110,16 +118,16 @@ sub preprocess_taglink (@) { return join(" ", map { if (/(.*)\|(.*)/) { my $tag=linkpage($2); - add_link($params{page}, tagpage($tag), 'tag'); + add_link($params{page}, taglink($tag), 'tag'); gentag($tag); - return taglink($params{page}, $params{destpage}, $tag, + return htmllink_tag($params{page}, $params{destpage}, $tag, linktext => pagetitle($1)); } else { my $tag=linkpage($_); - add_link($params{page}, tagpage($tag), 'tag'); + add_link($params{page}, taglink($tag), 'tag'); gentag($tag); - return taglink($params{page}, $params{destpage}, $tag); + return htmllink_tag($params{page}, $params{destpage}, $tag); } } grep { @@ -137,7 +145,7 @@ sub pagetemplate (@) { $template->param(tags => [ map { - link => taglink($page, $destpage, $_, rel => "tag") + link => htmllink_tag($page, $destpage, $_, rel => "tag") }, sort keys %$tags ]) if defined $tags && %$tags && $template->query(name => "tags"); @@ -153,7 +161,7 @@ sub pagetemplate (@) { package IkiWiki::PageSpec; sub match_tagged ($$;@) { - return match_link($_[0], IkiWiki::Plugin::tag::tagpage($_[1]), linktype => 'tag'); + return match_link($_[0], IkiWiki::Plugin::tag::taglink($_[1]), linktype => 'tag'); } 1 -- cgit v1.2.3 From fd6fb4c5071d9317b4388a0db6b97037cc010477 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 16:13:37 -0400 Subject: commit autocreated tag pages --- IkiWiki/Plugin/tag.pm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index d2a3d4dfd..c98dd80b2 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -79,11 +79,18 @@ sub gentag ($) { my $tagfile = newpagefile($tagpage, $config{default_pageext}); add_autofile($tagfile, "tag", sub { - debug(sprintf(gettext("creating tag page %s"), $tag)); + my $message=sprintf(gettext("creating tag page %s"), $tag); + debug($message); my $template=template("autotag.tmpl"); $template->param(tag => $tag); writefile($tagfile, $config{srcdir}, $template->output); + if ($config{rcs}) { + IkiWiki::disable_commit_hook(); + IkiWiki::rcs_add($tagfile); + IkiWiki::rcs_commit_staged($message, undef, undef); + IkiWiki::enable_commit_hook(); + } }); } } -- cgit v1.2.3 From 8cde2365e43f1c96432dcedb378be55d2308dd08 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 19:09:59 -0400 Subject: add separate template variable for tag page and sanitize displayed tag name --- IkiWiki/Plugin/tag.pm | 3 ++- templates/autotag.tmpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index c98dd80b2..6a6517671 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -83,7 +83,8 @@ sub gentag ($) { debug($message); my $template=template("autotag.tmpl"); - $template->param(tag => $tag); + $template->param(tag => IkiWiki::basename($tag)); + $template->param(tagpage => $tagpage); writefile($tagfile, $config{srcdir}, $template->output); if ($config{rcs}) { IkiWiki::disable_commit_hook(); diff --git a/templates/autotag.tmpl b/templates/autotag.tmpl index a8824171b..7b0d4c90f 100644 --- a/templates/autotag.tmpl +++ b/templates/autotag.tmpl @@ -1,3 +1,3 @@ -## Pages tagged ## +## Pages tagged ## [[!inline pages="tagged()" actions="no" archive="yes"]] -- cgit v1.2.3 From 77779dc4a09a9b686935e8e615cf2502f7125bb4 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 19:46:27 -0400 Subject: pass pagespec parameters along from match_tagged --- IkiWiki/Plugin/tag.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 7a85874f6..62e0cc3b8 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -125,7 +125,9 @@ sub pagetemplate (@) { package IkiWiki::PageSpec; sub match_tagged ($$;@) { - return match_link($_[0], IkiWiki::Plugin::tag::tagpage($_[1]), linktype => 'tag'); + my $page=shift; + my $glob=shift; + return match_link($page, IkiWiki::Plugin::tag::tagpage($glob), linktype => 'tag', @_); } 1 -- cgit v1.2.3 From 0e2b5ebe314c617ae4139b5daad314e01208d37b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 19:49:11 -0400 Subject: clarify --- IkiWiki/Plugin/tag.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 72ae682f3..dd7583ab2 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -170,8 +170,8 @@ package IkiWiki::PageSpec; sub match_tagged ($$;@) { my $page=shift; - my $glob=shift; - return match_link($page, IkiWiki::Plugin::tag::taglink($glob), linktype => 'tag', @_); + my $glob=IkiWiki::Plugin::tag::taglink(shift); + return match_link($page, $glob, linktype => 'tag', @_); } 1 -- cgit v1.2.3 From 752ccf8b48bab173839b5c7892e9868ee71846f0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 20:08:23 -0400 Subject: fixes --- IkiWiki/Plugin/tag.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index dd7583ab2..a7f37a512 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -79,12 +79,12 @@ sub gentag ($) { my $tagfile = newpagefile($tagpage, $config{default_pageext}); add_autofile($tagfile, "tag", sub { - my $message=sprintf(gettext("creating tag page %s"), $tag); + my $message=sprintf(gettext("creating tag page %s"), $tagpage); debug($message); my $template=template("autotag.tmpl"); - $template->param(tag => IkiWiki::basename($tag)); - $template->param(tagpage => $tagpage); + $template->param(tagname => IkiWiki::basename($tag)); + $template->param(tag => $tag); writefile($tagfile, $config{srcdir}, $template->output); if ($config{rcs}) { IkiWiki::disable_commit_hook(); -- cgit v1.2.3 From 129cd00bdb03e32df8645b12138cb4c79952775e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 20:15:11 -0400 Subject: remove broken ./tag support The commit that added the (working) support for using /tag to override tagbase also tried to make ./tag work. Problem is, tags are links, and ./foo is not a valid link (though I think there's a wishlist about it). So, using ./tag really resulted in tag creation links that led to a "bad page name" error. And even if the tag were created in the right place, the link didn't go to it. --- IkiWiki/Plugin/tag.pm | 2 +- doc/ikiwiki/directive/tag.mdwn | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 62e0cc3b8..8ec08e936 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -39,7 +39,7 @@ sub getsetup () { sub tagpage ($) { my $tag=shift; - if ($tag !~ m{^\.?/} && + if ($tag !~ m{^/} && defined $config{tagbase}) { $tag="/".$config{tagbase}."/".$tag; $tag=~y#/#/#s; # squash dups diff --git a/doc/ikiwiki/directive/tag.mdwn b/doc/ikiwiki/directive/tag.mdwn index 64736f8cd..807a96f25 100644 --- a/doc/ikiwiki/directive/tag.mdwn +++ b/doc/ikiwiki/directive/tag.mdwn @@ -28,7 +28,7 @@ into the `link()` [[ikiwiki/PageSpec]] you use: e.g., if your tagbase is If you want to override the tagbase for a particular tag, you can use something like this: - \[[!tag ./foo]] + \[[!tag /foo]] \[[!taglink /foo]] [[!meta robots="noindex, follow"]] -- cgit v1.2.3 From d048e9c64aca24b8e064aaf1608862b50c427de2 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 21 Apr 2010 20:39:20 -0400 Subject: turn on tag_autocreate by default if tagbase is set --- IkiWiki/Plugin/tag.pm | 5 +++-- debian/NEWS | 4 ++++ doc/ikiwiki/directive/tag.mdwn | 3 ++- doc/plugins/tag.mdwn | 8 ++++++-- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index cd7ecc212..62f030f4e 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -36,7 +36,7 @@ sub getsetup () { }, tag_autocreate => { type => "boolean", - example => 0, + example => 1, description => "autocreate new tag pages?", safe => 1, rebuild => undef, @@ -67,7 +67,8 @@ sub htmllink_tag ($$$;@) { sub gentag ($) { my $tag=shift; - if ($config{tag_autocreate}) { + if ($config{tag_autocreate} || + ($config{tagbase} && ! defined $config{tag_autocreate})) { my $tagpage=taglink($tag); if ($tagpage=~/^\.\/(.*)/) { $tagpage=$1; diff --git a/debian/NEWS b/debian/NEWS index 9fd882ad2..8b87bc601 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -11,6 +11,10 @@ ikiwiki (3.20100406) unstable; urgency=low not regular wikilinks. If your wiki accidentially relied on the old, buggy behavior, you might need to change pagespecs to use `link()`. + Tag pages can automatically be created as new tags are used. This + feature is enabled by default if you have configured a tagbase. It + can be turned on or off using the `tag_autocreate` setting. + The title_natural sort method (as used by the inline directive, etc) have been moved to the new sortnaturally plugin, which is not enabled by default since it requires the Sort::Naturally perl module. diff --git a/doc/ikiwiki/directive/tag.mdwn b/doc/ikiwiki/directive/tag.mdwn index 807a96f25..c8d9b9816 100644 --- a/doc/ikiwiki/directive/tag.mdwn +++ b/doc/ikiwiki/directive/tag.mdwn @@ -19,7 +19,8 @@ instead: Note that if the wiki is configured to use a tagbase, then the tags will be located under a base directory, such as "tags/". This is a useful way to avoid having to write the full path to tags, if you want to keep them -grouped together out of the way. +grouped together out of the way. Also, since ikiwiki then knows where to put +tags, it will automatically create tag pages when new tags are used. Bear in mind that specifying a tagbase means you will need to incorporate it into the `link()` [[ikiwiki/PageSpec]] you use: e.g., if your tagbase is diff --git a/doc/plugins/tag.mdwn b/doc/plugins/tag.mdwn index bdf39d7e8..8e1286e62 100644 --- a/doc/plugins/tag.mdwn +++ b/doc/plugins/tag.mdwn @@ -8,8 +8,12 @@ These directives allow tagging pages. It also provides the `tagged()` [[ikiwiki/PageSpec]], which can be used to match pages that are tagged with a specific tag. -If the `tag_autocreate` setting is enabled, tag pages will automatically be -created as needed. +The `tagbase` setting can be used to make tags default to being put in a +particular subdirectory. + +The `tag_autocreate` setting can be used to control whether new tag pages +are created as needed. It defaults to being done only if a `tagbase` is +set. [[!if test="enabled(tag)" then=""" This wiki has the tag plugin enabled, so you'll see a note below that this -- cgit v1.2.3 From ecdfd1b8644bc926db008054ab6192e18351afed Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 23 Jun 2010 17:35:21 -0400 Subject: rcs_commit and rcs_commit_staged api changes Using named parameters for these is overdue. Passing the session in a parameter instead of passing username and IP separately will later allow storing other session info, like username or part of the email. Note that these functions are not part of the exported API, and the prototype change will catch (most) skew, so I am not changing API versions. Any third-party plugins that call them will need updated though. --- IkiWiki.pm | 4 +- IkiWiki/Plugin/attachment.pm | 10 ++-- IkiWiki/Plugin/autoindex.pm | 4 +- IkiWiki/Plugin/bzr.pm | 43 +++++++++-------- IkiWiki/Plugin/comments.pm | 14 +++--- IkiWiki/Plugin/cvs.pm | 59 ++++++++++++----------- IkiWiki/Plugin/darcs.pm | 75 +++++++++++++++--------------- IkiWiki/Plugin/editpage.pm | 10 ++-- IkiWiki/Plugin/git.pm | 52 +++++++++++++-------- IkiWiki/Plugin/mercurial.pm | 32 ++++++------- IkiWiki/Plugin/monotone.pm | 85 +++++++++++++++------------------- IkiWiki/Plugin/norcs.pm | 6 +-- IkiWiki/Plugin/poll.pm | 10 ++-- IkiWiki/Plugin/remove.pm | 7 +-- IkiWiki/Plugin/rename.pm | 5 +- IkiWiki/Plugin/svn.pm | 59 ++++++++++++----------- IkiWiki/Plugin/tag.pm | 2 +- IkiWiki/Plugin/tla.pm | 34 ++++++++------ debian/changelog | 5 +- doc/plugins/write.mdwn | 16 ++++--- ikiwiki-calendar.in | 2 +- ikiwiki.spec | 2 +- po/ikiwiki.pot | 108 +++++++++++++++++++++---------------------- t/bazaar.t | 25 ++++++++-- t/cvs.t | 6 ++- t/git.t | 12 +++-- t/mercurial.t | 11 ++++- t/svn.t | 6 ++- 28 files changed, 380 insertions(+), 324 deletions(-) (limited to 'IkiWiki/Plugin/tag.pm') diff --git a/IkiWiki.pm b/IkiWiki.pm index 203da3ba2..35b38df46 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -1840,11 +1840,11 @@ sub rcs_prepedit ($) { $hooks{rcs}{rcs_prepedit}{call}->(@_); } -sub rcs_commit ($$$;$$) { +sub rcs_commit (@) { $hooks{rcs}{rcs_commit}{call}->(@_); } -sub rcs_commit_staged ($$$) { +sub rcs_commit_staged (@) { $hooks{rcs}{rcs_commit_staged}{call}->(@_); } diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm index 216e00b3d..ee105a170 100644 --- a/IkiWiki/Plugin/attachment.pm +++ b/IkiWiki/Plugin/attachment.pm @@ -183,10 +183,12 @@ sub formbuilder (@) { if ($config{rcs}) { IkiWiki::rcs_add($filename); IkiWiki::disable_commit_hook(); - IkiWiki::rcs_commit($filename, gettext("attachment upload"), - IkiWiki::rcs_prepedit($filename), - $session->param("name"), - $session->remote_addr()); + IkiWiki::rcs_commit( + file => $filename, + message => gettext("attachment upload"), + token => IkiWiki::rcs_prepedit($filename), + session => $session, + ); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } diff --git a/IkiWiki/Plugin/autoindex.pm b/IkiWiki/Plugin/autoindex.pm index c3eb53300..11595e217 100644 --- a/IkiWiki/Plugin/autoindex.pm +++ b/IkiWiki/Plugin/autoindex.pm @@ -117,8 +117,8 @@ sub refresh () { } if ($config{rcs}) { IkiWiki::rcs_commit_staged( - gettext("automatic index generation"), - undef, undef); + message => gettext("automatic index generation"), + ); IkiWiki::enable_commit_hook(); } } diff --git a/IkiWiki/Plugin/bzr.pm b/IkiWiki/Plugin/bzr.pm index 44ab9a86a..562d5d389 100644 --- a/IkiWiki/Plugin/bzr.pm +++ b/IkiWiki/Plugin/bzr.pm @@ -123,8 +123,13 @@ sub rcs_prepedit ($) { return ""; } -sub bzr_author ($$) { - my ($user, $ipaddr) = @_; +sub bzr_author ($) { + my $session=shift; + + return unless defined $session; + + my $user=$session->param("name"); + my $ipaddr=$session->remote_addr(); if (defined $user) { return IkiWiki::possibly_foolish_untaint($user); @@ -137,18 +142,19 @@ sub bzr_author ($$) { } } -sub rcs_commit ($$$;$$$) { - my ($file, $message, $rcstoken, $user, $ipaddr, $emailuser) = @_; +sub rcs_commit (@) { + my %params=@_; - $user = bzr_author($user, $ipaddr); + my $user=bzr_author($params{session}); - $message = IkiWiki::possibly_foolish_untaint($message); - if (! length $message) { - $message = "no message given"; + $params{message} = IkiWiki::possibly_foolish_untaint($params{message}); + if (! length $params{message}) { + $params{message} = "no message given"; } - my @cmdline = ("bzr", "commit", "--quiet", "-m", $message, "--author", $user, - $config{srcdir}."/".$file); + my @cmdline = ("bzr", "commit", "--quiet", "-m", $params{message}, + (defined $user ? ("--author", $user) : ()), + $config{srcdir}."/".$params{file}); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } @@ -156,19 +162,18 @@ sub rcs_commit ($$$;$$$) { return undef; # success } -sub rcs_commit_staged ($$$;$) { - # Commits all staged changes. Changes can be staged using rcs_add, - # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; +sub rcs_commit_staged (@) { + my %params=@_; - $user = bzr_author($user, $ipaddr); + my $user=bzr_author($params{session}); - $message = IkiWiki::possibly_foolish_untaint($message); - if (! length $message) { - $message = "no message given"; + $params{message} = IkiWiki::possibly_foolish_untaint($params{message}); + if (! length $params{message}) { + $params{message} = "no message given"; } - my @cmdline = ("bzr", "commit", "--quiet", "-m", $message, "--author", $user, + my @cmdline = ("bzr", "commit", "--quiet", "-m", $params{message}, + (defined $user ? ("--author", $user) : ()), $config{srcdir}); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 4770209c9..41c6948e8 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -513,9 +513,10 @@ sub editcomment ($$) { IkiWiki::rcs_add($file); IkiWiki::disable_commit_hook(); - $conflict = IkiWiki::rcs_commit_staged($message, - $session->param('name'), - $session->remote_addr()); + $conflict = IkiWiki::rcs_commit_staged( + message => $message, + session => $session, + ); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } @@ -603,9 +604,10 @@ sub commentmoderation ($$) { if ($config{rcs} and $config{comments_commit}) { my $message = gettext("Comment moderation"); IkiWiki::disable_commit_hook(); - $conflict=IkiWiki::rcs_commit_staged($message, - $session->param('name'), - $session->remote_addr()); + $conflict=IkiWiki::rcs_commit_staged( + message => $message, + session => $session, + ); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } diff --git a/IkiWiki/Plugin/cvs.pm b/IkiWiki/Plugin/cvs.pm index a9fe162a1..c6687d780 100644 --- a/IkiWiki/Plugin/cvs.pm +++ b/IkiWiki/Plugin/cvs.pm @@ -183,41 +183,47 @@ sub rcs_prepedit ($) { return defined $rev ? $rev : ""; } -sub rcs_commit ($$$;$$$) { +sub commitmessage (@) { + my %params=@_; + + if (defined $params{session}) { + if (defined $params{session}->param("name")) { + return "web commit by ". + $params{session}->param("name"). + (length $params{message} ? ": $params{message}" : ""); + } + elsif (defined $params{session}->remote_addr()) { + return "web commit from ". + $params{session}->remote_addr(). + (length $params{message} ? ": $params{message}" : ""); + } + } + return $params{message}; +} + +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. - my $file=shift; - my $message=shift; - my $rcstoken=shift; - my $user=shift; - my $ipaddr=shift; - my $emailuser=shift; + my %params=@_; return unless cvs_is_controlling; - if (defined $user) { - $message="web commit by $user".(length $message ? ": $message" : ""); - } - elsif (defined $ipaddr) { - $message="web commit from $ipaddr".(length $message ? ": $message" : ""); - } - # Check to see if the page has been changed by someone # else since rcs_prepedit was called. - my ($oldrev)=$rcstoken=~/^([0-9]+)$/; # untaint - my $rev=cvs_info("Repository revision", "$config{srcdir}/$file"); + my ($oldrev)=$params{token}=~/^([0-9]+)$/; # untaint + my $rev=cvs_info("Repository revision", "$config{srcdir}/$params{file}"); if (defined $rev && defined $oldrev && $rev != $oldrev) { # Merge their changes into the file that we've # changed. - cvs_runcvs('update', $file) || + cvs_runcvs('update', $params{file}) || warn("cvs merge from $oldrev to $rev failed\n"); } if (! cvs_runcvs('commit', '-m', - IkiWiki::possibly_foolish_untaint $message)) { - my $conflict=readfile("$config{srcdir}/$file"); - cvs_runcvs('update', '-C', $file) || + IkiWiki::possibly_foolish_untaint(commitmessage(%params)))) { + my $conflict=readfile("$config{srcdir}/$params{file}"); + cvs_runcvs('update', '-C', $params{file}) || warn("cvs revert failed\n"); return $conflict; } @@ -225,20 +231,13 @@ sub rcs_commit ($$$;$$$) { return undef # success } -sub rcs_commit_staged ($$$;$) { +sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; - - if (defined $user) { - $message="web commit by $user".(length $message ? ": $message" : ""); - } - elsif (defined $ipaddr) { - $message="web commit from $ipaddr".(length $message ? ": $message" : ""); - } + my %params=@_; if (! cvs_runcvs('commit', '-m', - IkiWiki::possibly_foolish_untaint $message)) { + IkiWiki::possibly_foolish_untaint(commitmessage(%params)))) { warn "cvs staged commit failed\n"; return 1; # failure } diff --git a/IkiWiki/Plugin/darcs.pm b/IkiWiki/Plugin/darcs.pm index 345456c01..0dfc8708d 100644 --- a/IkiWiki/Plugin/darcs.pm +++ b/IkiWiki/Plugin/darcs.pm @@ -140,14 +140,31 @@ sub rcs_prepedit ($) { return $rev; } -sub rcs_commit ($$$;$$$) { +sub commitauthor (@) { + my %params=@_; + + my $author="anon\@web"; + if (defined $params{session}) { + if (defined $params{session}->param("name")) { + return $params{session}->param("name").'@web'; + } + elsif (defined $params{session}->remote_addr()) { + return $params{session}->remote_addr().'@web'; + } + } + return 'anon@web'; +} + +sub rcs_commit (@) { # Commit the page. Returns 'undef' on success and a version of the page # with conflict markers on failure. + my %params=@_; - my ($file, $message, $rcstoken, $user, $ipaddr, $emailuser) = @_; + my ($file, $message, $token) = + ($params{file}, $params{message}, $params{token}); # Compute if the "revision" of $file changed. - my $changed = darcs_rev($file) ne $rcstoken; + my $changed = darcs_rev($file) ne $token; # Yes, the following is a bit convoluted. if ($changed) { @@ -155,7 +172,7 @@ sub rcs_commit ($$$;$$$) { rename("$config{srcdir}/$file", "$config{srcdir}/$file.save") or error("failed to rename $file to $file.save: $!"); - # Roll the repository back to $rcstoken. + # Roll the repository back to $token. # TODO. Can we be sure that no changes are lost? I think that # we can, if we make sure that the 'darcs push' below will always @@ -166,37 +183,28 @@ sub rcs_commit ($$$;$$$) { # TODO: 'yes | ...' needed? Doesn't seem so. silentsystem('darcs', "revert", "--repodir", $config{srcdir}, "--all") == 0 || error("'darcs revert' failed"); - # Remove all patches starting at $rcstoken. + # Remove all patches starting at $token. my $child = open(DARCS_OBLITERATE, "|-"); if (! $child) { open(STDOUT, ">/dev/null"); exec('darcs', "obliterate", "--repodir", $config{srcdir}, - "--match", "hash " . $rcstoken) and + "--match", "hash " . $token) and error("'darcs obliterate' failed"); } 1 while print DARCS_OBLITERATE "y"; close(DARCS_OBLITERATE); - # Restore the $rcstoken one. + # Restore the $token one. silentsystem('darcs', "pull", "--quiet", "--repodir", $config{srcdir}, - "--match", "hash " . $rcstoken, "--all") == 0 || + "--match", "hash " . $token, "--all") == 0 || error("'darcs pull' failed"); - # We're back at $rcstoken. Re-install the modified file. + # We're back at $token. Re-install the modified file. rename("$config{srcdir}/$file.save", "$config{srcdir}/$file") or error("failed to rename $file.save to $file: $!"); } # Record the changes. - my $author; - if (defined $user) { - $author = "$user\@web"; - } - elsif (defined $ipaddr) { - $author = "$ipaddr\@web"; - } - else { - $author = "anon\@web"; - } + my $author=commitauthor(%params); if (!defined $message || !length($message)) { $message = "empty message"; } @@ -211,13 +219,13 @@ sub rcs_commit ($$$;$$$) { # If this updating yields any conflicts, we'll record them now to resolve # them. If nothing is recorded, there are no conflicts. - $rcstoken = darcs_rev($file); + $token = darcs_rev($file); # TODO: Use only the first line here, i.e. only the patch name? writefile("$file.log", $config{srcdir}, 'resolve conflicts: ' . $message); silentsystem('darcs', 'record', '--repodir', $config{srcdir}, '--all', '-m', 'resolve conflicts: ' . $message, '--author', $author, $file) == 0 || error("'darcs record' failed"); - my $conflicts = darcs_rev($file) ne $rcstoken; + my $conflicts = darcs_rev($file) ne $token; unlink("$config{srcdir}/$file.log") or error("failed to remove '$file.log'"); @@ -239,25 +247,18 @@ sub rcs_commit ($$$;$$$) { } } -sub rcs_commit_staged ($$$;$) { - my ($message, $user, $ipaddr, $emailuser) = @_; +sub rcs_commit_staged (@) { + my %params=@_; - my $author; - if (defined $user) { - $author = "$user\@web"; - } - elsif (defined $ipaddr) { - $author = "$ipaddr\@web"; - } - else { - $author = "anon\@web"; - } - if (!defined $message || !length($message)) { - $message = "empty message"; + my $author=commitauthor(%params); + if (!defined $params{message} || !length($params{message})) { + $params{message} = "empty message"; } - silentsystem('darcs', "record", "--repodir", $config{srcdir}, "-a", "-A", $author, - "-m", $message) == 0 || error("'darcs record' failed"); + silentsystem('darcs', "record", "--repodir", $config{srcdir}, + "-a", "-A", $author, + "-m", $params{message}, + ) == 0 || error("'darcs record' failed"); # Push the changes to the main repository. silentsystem('darcs', 'push', '--quiet', '--repodir', $config{srcdir}, '--all') == 0 || diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index a8e75121f..1a04a72b5 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -401,10 +401,12 @@ sub cgi_editpage ($$) { # signaling to it that it should not try to # do anything. disable_commit_hook(); - $conflict=rcs_commit($file, $message, - $form->field("rcsinfo"), - $session->param("name"), - $session->remote_addr()); + $conflict=rcs_commit( + file => $file, + message => $message, + token => $form->field("rcsinfo"), + session => $session, + ); enable_commit_hook(); rcs_update(); } diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index b56f229d7..b02fc118d 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -464,43 +464,55 @@ sub rcs_prepedit ($) { return git_sha1($file); } -sub rcs_commit ($$$;$$$) { +sub rcs_commit (@) { # Try to commit the page; returns undef on _success_ and # a version of the page with the rcs's conflict markers on # failure. - - my ($file, $message, $rcstoken, $user, $ipaddr, $emailuser) = @_; + my %params=@_; # Check to see if the page has been changed by someone else since # rcs_prepedit was called. - my $cur = git_sha1($file); - my ($prev) = $rcstoken =~ /^($sha1_pattern)$/; # untaint + my $cur = git_sha1($params{file}); + my ($prev) = $params{token} =~ /^($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, $params{file}, $dummy_commit_msg); return $conflict if defined $conflict; } - rcs_add($file); - return rcs_commit_staged($message, $user, $ipaddr); + rcs_add($params{file}); + return rcs_commit_staged( + message => $params{message}, + session => $params{session}, + ); } -sub rcs_commit_staged ($$$;$) { +sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; - - # Set the commit author and email to the web committer. + my %params=@_; + my %env=%ENV; - if (defined $user || defined $ipaddr) { - my $u=encode_utf8(defined $user ? $user : $ipaddr); - $ENV{GIT_AUTHOR_NAME}=$u; - $ENV{GIT_AUTHOR_EMAIL}="$u\@web"; + + if (defined $params{session}) { + # Set the commit author and email based on web session info. + my $u; + if (defined $params{session}->param("name")) { + $u=$params{session}->param("name"); + } + elsif (defined $params{session}->remote_addr()) { + $u=$params{session}->remote_addr(); + } + if (defined $u) { + $u=encode_utf8($u); + $ENV{GIT_AUTHOR_NAME}=$u; + $ENV{GIT_AUTHOR_EMAIL}="$u\@web"; + } } - $message = IkiWiki::possibly_foolish_untaint($message); + $params{message} = IkiWiki::possibly_foolish_untaint($params{message}); my @opts; - if ($message !~ /\S/) { + if ($params{message} !~ /\S/) { # Force git to allow empty commit messages. # (If this version of git supports it.) my ($version)=`git --version` =~ /git version (.*)/; @@ -508,13 +520,13 @@ sub rcs_commit_staged ($$$;$) { push @opts, '--cleanup=verbatim'; } else { - $message.="."; + $params{message}.="."; } } push @opts, '-q'; # git commit returns non-zero if file has not been really changed. # so we should ignore its exit status (hence run_or_non). - if (run_or_non('git', 'commit', @opts, '-m', $message)) { + if (run_or_non('git', 'commit', @opts, '-m', $params{message})) { if (length $config{gitorigin_branch}) { run_or_cry('git', 'push', $config{gitorigin_branch}); } diff --git a/IkiWiki/Plugin/mercurial.pm b/IkiWiki/Plugin/mercurial.pm index 1793ab4bb..edf915ae9 100644 --- a/IkiWiki/Plugin/mercurial.pm +++ b/IkiWiki/Plugin/mercurial.pm @@ -126,26 +126,26 @@ sub rcs_prepedit ($) { return ""; } -sub rcs_commit ($$$;$$$) { - my ($file, $message, $rcstoken, $user, $ipaddr, $emailuser) = @_; +sub rcs_commit (@) { + my %params=@_; - if (defined $user) { - $user = IkiWiki::possibly_foolish_untaint($user); - } - elsif (defined $ipaddr) { - $user = "Anonymous from ".IkiWiki::possibly_foolish_untaint($ipaddr); - } - else { - $user = "Anonymous"; + my $user="Anonymous"; + if (defined $params{session}) { + if (defined $params{session}->param("name")) { + $user = $params{session}->param("name"); + } + elsif (defined $params{session}->remote_addr()) { + $user = "Anonymous from ".$params{session}->remote_addr(); + } } - $message = IkiWiki::possibly_foolish_untaint($message); - if (! length $message) { - $message = "no message given"; + if (! length $params{message}) { + $params{message} = "no message given"; } my @cmdline = ("hg", "-q", "-R", $config{srcdir}, "commit", - "-m", $message, "-u", $user); + "-m", IkiWiki::possibly_foolish_untaint($params{message}), + "-u", IkiWiki::possibly_foolish_untaint($user)); if (system(@cmdline) != 0) { warn "'@cmdline' failed: $!"; } @@ -153,10 +153,10 @@ sub rcs_commit ($$$;$$$) { return undef; # success } -sub rcs_commit_staged ($$$;$) { +sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; + my %params=@_; error("rcs_commit_staged not implemented for mercurial"); # TODO } diff --git a/IkiWiki/Plugin/monotone.pm b/IkiWiki/Plugin/monotone.pm index 55d8039e0..95fbcee76 100644 --- a/IkiWiki/Plugin/monotone.pm +++ b/IkiWiki/Plugin/monotone.pm @@ -293,32 +293,33 @@ sub rcs_prepedit ($) { return get_rev(); } -sub rcs_commit ($$$;$$$) { +sub commitauthor (@) { + my %params=@_; + + if (defined $params{session}) { + if (defined $params{session}->param("name")) { + return "Web user: " . $params{session}->param("name"); + } + elsif (defined $params{session}->remote_addr()) { + return "Web IP: " . $params{session}->remote_addr(); + } + } + return "Web: Anonymous"; +} + + +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. - my $file=shift; - my $message=shift; - my $rcstoken=shift; - my $user=shift; - my $ipaddr=shift; - my $emailuser=shift; - my $author; + my %params=@_; - if (defined $user) { - $author="Web user: " . $user; - } - elsif (defined $ipaddr) { - $author="Web IP: " . $ipaddr; - } - else { - $author="Web: Anonymous"; - } + my $author=IkiWiki::possibly_foolish_untaint(commitauthor(%params)), chdir $config{srcdir} or error("Cannot chdir to $config{srcdir}: $!"); - my ($oldrev)= $rcstoken=~ m/^($sha1_pattern)$/; # untaint + my ($oldrev) = $params{token} =~ m/^($sha1_pattern)$/; # untaint my $rev = get_rev(); if (defined $rev && defined $oldrev && $rev ne $oldrev) { my $automator = Monotone->new(); @@ -327,8 +328,8 @@ sub rcs_commit ($$$;$$$) { # Something has been committed, has this file changed? my ($out, $err); $automator->setOpts("r", $oldrev, "r", $rev); - ($out, $err) = $automator->call("content_diff", $file); - debug("Problem committing $file") if ($err ne ""); + ($out, $err) = $automator->call("content_diff", $params{file}); + debug("Problem committing $params{file}") if ($err ne ""); my $diff = $out; if ($diff) { @@ -337,11 +338,11 @@ sub rcs_commit ($$$;$$$) { # # first get the contents debug("File changed: forming branch"); - my $newfile=readfile("$config{srcdir}/$file"); + my $newfile=readfile("$config{srcdir}/$params{file}"); # then get the old content ID from the diff - if ($diff !~ m/^---\s$file\s+($sha1_pattern)$/m) { - error("Unable to find previous file ID for $file"); + if ($diff !~ m/^---\s$params{file}\s+($sha1_pattern)$/m) { + error("Unable to find previous file ID for $params{file}"); } my $oldFileID = $1; @@ -352,13 +353,13 @@ sub rcs_commit ($$$;$$$) { my $branch = $1; # then put the new content into the DB (and record the new content ID) - my $newRevID = commit_file_to_new_rev($automator, $file, $oldFileID, $newfile, $oldrev, $branch, $author, $message); + my $newRevID = commit_file_to_new_rev($automator, $params{file}, $oldFileID, $newfile, $oldrev, $branch, $author, $params{message}); $automator->close(); # if we made it to here then the file has been committed... revert the local copy - if (system("mtn", "--root=$config{mtnrootdir}", "revert", $file) != 0) { - debug("Unable to revert $file after merge on conflicted commit!"); + if (system("mtn", "--root=$config{mtnrootdir}", "revert", $params{file}) != 0) { + debug("Unable to revert $params{file} after merge on conflicted commit!"); } debug("Divergence created! Attempting auto-merge."); @@ -407,7 +408,7 @@ sub rcs_commit ($$$;$$$) { # for cleanup note, this relies on the fact # that ikiwiki seems to call rcs_prepedit() # again after we return - return readfile("$config{srcdir}/$file"); + return readfile("$config{srcdir}/$params{file}"); } return undef; } @@ -419,11 +420,12 @@ sub rcs_commit ($$$;$$$) { if (system("mtn", "--root=$config{mtnrootdir}", "commit", "--quiet", "--author", $author, "--key", $config{mtnkey}, "-m", - IkiWiki::possibly_foolish_untaint($message), $file) != 0) { + IkiWiki::possibly_foolish_untaint($params{message}), + $params{file}) != 0) { debug("Traditional commit failed! Returning data as conflict."); - my $conflict=readfile("$config{srcdir}/$file"); + my $conflict=readfile("$config{srcdir}/$params{file}"); if (system("mtn", "--root=$config{mtnrootdir}", "revert", - "--quiet", $file) != 0) { + "--quiet", $params{file}) != 0) { debug("monotone revert failed"); } return $conflict; @@ -439,32 +441,21 @@ sub rcs_commit ($$$;$$$) { return undef # success } -sub rcs_commit_staged ($$$;$) { +sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; - + my %params=@_; + # Note - this will also commit any spurious changes that happen to be # lying around in the working copy. There shouldn't be any, but... chdir $config{srcdir} or error("Cannot chdir to $config{srcdir}: $!"); - my $author; - - if (defined $user) { - $author="Web user: " . $user; - } - elsif (defined $ipaddr) { - $author="Web IP: " . $ipaddr; - } - else { - $author="Web: Anonymous"; - } - if (system("mtn", "--root=$config{mtnrootdir}", "commit", "--quiet", - "--author", $author, "--key", $config{mtnkey}, "-m", - IkiWiki::possibly_foolish_untaint($message)) != 0) { + "--author", IkiWiki::possibly_foolish_untaint(commitauthor(%params)), + "--key", $config{mtnkey}, "-m", + IkiWiki::possibly_foolish_untaint($params{message})) != 0) { error("Monotone commit failed"); } } diff --git a/IkiWiki/Plugin/norcs.pm b/IkiWiki/Plugin/norcs.pm index 5131a1502..a3bb6240e 100644 --- a/IkiWiki/Plugin/norcs.pm +++ b/IkiWiki/Plugin/norcs.pm @@ -38,13 +38,11 @@ sub rcs_prepedit ($) { return "" } -sub rcs_commit ($$$;$$$) { - my ($file, $message, $rcstoken, $user, $ipaddr, $emailuser) = @_; +sub rcs_commit (@) { return undef # success } -sub rcs_commit_staged ($$$;$) { - my ($message, $user, $ipaddr, $emailuser)=@_; +sub rcs_commit_staged (@) { return undef # success } diff --git a/IkiWiki/Plugin/poll.pm b/IkiWiki/Plugin/poll.pm index e50efa5e0..b333e2cdc 100644 --- a/IkiWiki/Plugin/poll.pm +++ b/IkiWiki/Plugin/poll.pm @@ -134,10 +134,12 @@ sub sessioncgi ($$) { $oldchoice=$session->param($choice_param); if ($config{rcs}) { IkiWiki::disable_commit_hook(); - IkiWiki::rcs_commit($pagesources{$page}, "poll vote ($choice)", - IkiWiki::rcs_prepedit($pagesources{$page}), - $session->param("name"), - $session->remote_addr()); + IkiWiki::rcs_commit( + file => $pagesources{$page}, + message => "poll vote ($choice)", + token => IkiWiki::rcs_prepedit($pagesources{$page}), + session => $session, + ); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } diff --git a/IkiWiki/Plugin/remove.pm b/IkiWiki/Plugin/remove.pm index b664cbf74..95f148183 100644 --- a/IkiWiki/Plugin/remove.pm +++ b/IkiWiki/Plugin/remove.pm @@ -213,9 +213,10 @@ sub sessioncgi ($$) { foreach my $file (@files) { IkiWiki::rcs_remove($file); } - IkiWiki::rcs_commit_staged(gettext("removed"), - $session->param("name"), - $session->remote_addr()); + IkiWiki::rcs_commit_staged( + message => gettext("removed"), + session => $session, + ); IkiWiki::enable_commit_hook(); IkiWiki::rcs_update(); } diff --git a/IkiWiki/Plugin/rename.pm b/IkiWiki/Plugin/rename.pm index 977c09e67..61d39d4b5 100644 --- a/IkiWiki/Plugin/rename.pm +++ b/IkiWiki/Plugin/rename.pm @@ -349,9 +349,8 @@ sub sessioncgi ($$) { $pagesources{$rename->{src}}=$rename->{destfile}; } IkiWiki::rcs_commit_staged( - sprintf(gettext("rename %s to %s"), $srcfile, $destfile), - $session->param("name"), - $session->remote_addr(), + message => sprintf(gettext("rename %s to %s"), $srcfile, $destfile), + session => $session, ) if $config{rcs}; # Then link fixups. diff --git a/IkiWiki/Plugin/svn.pm b/IkiWiki/Plugin/svn.pm index ffacb8cf9..f1e608408 100644 --- a/IkiWiki/Plugin/svn.pm +++ b/IkiWiki/Plugin/svn.pm @@ -144,44 +144,50 @@ sub rcs_prepedit ($) { } } -sub rcs_commit ($$$;$$$) { +sub commitmessage (@) { + my %params=@_; + + if (defined $params{session}) { + if (defined $params{session}->param("name")) { + return "web commit by ". + $params{session}->param("name"). + (length $params{message} ? ": $params{message}" : ""); + } + elsif (defined $params{session}->remote_addr()) { + return "web commit from ". + $params{session}->remote_addr(). + (length $params{message} ? ": $params{message}" : ""); + } + } + return $params{message}; +} + +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. - my $file=shift; - my $message=shift; - my $rcstoken=shift; - my $user=shift; - my $ipaddr=shift; - my $emailuser=shift; - - if (defined $user) { - $message="web commit by $user".(length $message ? ": $message" : ""); - } - elsif (defined $ipaddr) { - $message="web commit from $ipaddr".(length $message ? ": $message" : ""); - } + my %params=@_; if (-d "$config{srcdir}/.svn") { # Check to see if the page has been changed by someone # else since rcs_prepedit was called. - my ($oldrev)=$rcstoken=~/^([0-9]+)$/; # untaint - my $rev=svn_info("Revision", "$config{srcdir}/$file"); + my ($oldrev)=$params{token}=~/^([0-9]+)$/; # untaint + my $rev=svn_info("Revision", "$config{srcdir}/$params{file}"); if (defined $rev && defined $oldrev && $rev != $oldrev) { # Merge their changes into the file that we've # changed. if (system("svn", "merge", "--quiet", "-r$oldrev:$rev", - "$config{srcdir}/$file", "$config{srcdir}/$file") != 0) { + "$config{srcdir}/$params{file}", "$config{srcdir}/$params{file}") != 0) { warn("svn merge -r$oldrev:$rev failed\n"); } } if (system("svn", "commit", "--quiet", "--encoding", "UTF-8", "-m", - IkiWiki::possibly_foolish_untaint($message), + IkiWiki::possibly_foolish_untaint(commitmessage(%params)), $config{srcdir}) != 0) { - my $conflict=readfile("$config{srcdir}/$file"); - if (system("svn", "revert", "--quiet", "$config{srcdir}/$file") != 0) { + my $conflict=readfile("$config{srcdir}/$params{file}"); + if (system("svn", "revert", "--quiet", "$config{srcdir}/$params{file}") != 0) { warn("svn revert failed\n"); } return $conflict; @@ -190,21 +196,14 @@ sub rcs_commit ($$$;$$$) { return undef # success } -sub rcs_commit_staged ($$$;$) { +sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; - - if (defined $user) { - $message="web commit by $user".(length $message ? ": $message" : ""); - } - elsif (defined $ipaddr) { - $message="web commit from $ipaddr".(length $message ? ": $message" : ""); - } + my %params=@_; if (system("svn", "commit", "--quiet", "--encoding", "UTF-8", "-m", - IkiWiki::possibly_foolish_untaint($message), + IkiWiki::possibly_foolish_untaint(commitmessage(%params)), $config{srcdir}) != 0) { warn("svn commit failed\n"); return 1; # failure diff --git a/IkiWiki/Plugin/tag.pm b/IkiWiki/Plugin/tag.pm index 62f030f4e..55064a9a3 100644 --- a/IkiWiki/Plugin/tag.pm +++ b/IkiWiki/Plugin/tag.pm @@ -90,7 +90,7 @@ sub gentag ($) { if ($config{rcs}) { IkiWiki::disable_commit_hook(); IkiWiki::rcs_add($tagfile); - IkiWiki::rcs_commit_staged($message, undef, undef); + IkiWiki::rcs_commit_staged(message => $message); IkiWiki::enable_commit_hook(); } }); diff --git a/IkiWiki/Plugin/tla.pm b/IkiWiki/Plugin/tla.pm index 80c015e3c..da4385446 100644 --- a/IkiWiki/Plugin/tla.pm +++ b/IkiWiki/Plugin/tla.pm @@ -98,19 +98,23 @@ sub rcs_prepedit ($) { } } -sub rcs_commit ($$$;$$$) { - my $file=shift; - my $message=shift; - my $rcstoken=shift; - my $user=shift; - my $ipaddr=shift; - my $emailuser=shift; - - if (defined $user) { - $message="web commit by $user".(length $message ? ": $message" : ""); - } - elsif (defined $ipaddr) { - $message="web commit from $ipaddr".(length $message ? ": $message" : ""); +sub rcs_commit (@) { + my %params=@_; + + my ($file, $message, $rcstoken)= + ($params{file}, $params{message}, $params{token}); + + if (defined $params{session}) { + if (defined $params{session}->param("name")) { + $message="web commit by ". + $params{session}->param("name"). + (length $message ? ": $message" : ""); + } + elsif (defined $params{session}->remote_addr()) { + $message="web commit from ". + $params{session}->remote_addr(). + (length $message ? ": $message" : ""); + } } if (-d "$config{srcdir}/{arch}") { @@ -140,10 +144,10 @@ sub rcs_commit ($$$;$$$) { return undef # success } -sub rcs_commit_staged ($$$;$) { +sub rcs_commit_staged (@) { # Commits all staged changes. Changes can be staged using rcs_add, # rcs_remove, and rcs_rename. - my ($message, $user, $ipaddr, $emailuser)=@_; + my %params=@_; error("rcs_commit_staged not implemented for tla"); # TODO } diff --git a/debian/changelog b/debian/changelog index 2dfebd0b2..f7452a070 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,8 @@ ikiwiki (3.20100624) UNRELEASED; urgency=low * API: Add new optional field usershort to rcs_recentchanges. - * API: rcs_commit and rcs_commit_staged are passed a new parameter - that may contain the username component of the email address of - the user making the commit. + * API: rcs_commit and rcs_commit_staged are now passed named + parameters. -- Joey Hess Wed, 23 Jun 2010 15:30:04 -0400 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index ab2934bf1..a2b954bd4 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -1051,18 +1051,20 @@ 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($$$;$$$)` +#### `rcs_commit(@)` + +Passed named parameters: `file`, `message`, `token` (from `rcs_prepedit`), +and `session` (optional). -Passed a file, message, token (from `rcs_prepedit`), user, ip address, -and optionally the username component of the committer's email 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($$$;$)` +#### `rcs_commit_staged(@)` + +Passed named parameters: `message`, and `session` (optional). -Passed a message, user, ip address, and optionally the username component of -the committer's email address. Should commit all staged changes. -Returns undef on success, and an error message on failure. +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`. diff --git a/ikiwiki-calendar.in b/ikiwiki-calendar.in index 04352b970..60df99855 100755 --- a/ikiwiki-calendar.in +++ b/ikiwiki-calendar.in @@ -59,7 +59,7 @@ foreach my $y ($startyear..$endyear) { } } -IkiWiki::rcs_commit_staged(gettext("calendar update"), undef, undef) +IkiWiki::rcs_commit_staged(message => gettext("calendar update")) if $config{rcs}; exec("ikiwiki", "-setup", $setup, "-refresh"); diff --git a/ikiwiki.spec b/ikiwiki.spec index 9a4bbf6bc..9644fd396 100644 --- a/ikiwiki.spec +++ b/ikiwiki.spec @@ -1,5 +1,5 @@ Name: ikiwiki -Version: 3.20100623 +Version: 3.20100624 Release: 1%{?dist} Summary: A wiki compiler diff --git a/po/ikiwiki.pot b/po/ikiwiki.pot index 437cdbdcc..e50fa0f68 100644 --- a/po/ikiwiki.pot +++ b/po/ikiwiki.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2010-06-10 15:02-0400\n" +"POT-Creation-Date: 2010-06-23 17:10-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -52,7 +52,7 @@ msgstr "" msgid "You are banned." msgstr "" -#: ../IkiWiki/CGI.pm:426 ../IkiWiki/CGI.pm:427 ../IkiWiki.pm:1316 +#: ../IkiWiki/CGI.pm:426 ../IkiWiki/CGI.pm:427 ../IkiWiki.pm:1317 msgid "Error" msgstr "" @@ -163,19 +163,19 @@ msgstr "" msgid "prohibited by allowed_attachments" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:141 +#: ../IkiWiki/Plugin/attachment.pm:144 msgid "bad attachment filename" msgstr "" -#: ../IkiWiki/Plugin/attachment.pm:183 +#: ../IkiWiki/Plugin/attachment.pm:188 msgid "attachment upload" msgstr "" -#: ../IkiWiki/Plugin/autoindex.pm:117 +#: ../IkiWiki/Plugin/autoindex.pm:120 msgid "automatic index generation" msgstr "" -#: ../IkiWiki/Plugin/blogspam.pm:109 +#: ../IkiWiki/Plugin/blogspam.pm:110 msgid "" "Sorry, but that looks like spam to blogspam: " @@ -248,19 +248,19 @@ msgstr "" msgid "Added a comment: %s" msgstr "" -#: ../IkiWiki/Plugin/comments.pm:552 ../IkiWiki/Plugin/websetup.pm:272 +#: ../IkiWiki/Plugin/comments.pm:554 ../IkiWiki/Plugin/websetup.pm:268 msgid "you are not logged in as an admin" msgstr "" -#: ../IkiWiki/Plugin/comments.pm:603 +#: ../IkiWiki/Plugin/comments.pm:605 msgid "Comment moderation" msgstr "" -#: ../IkiWiki/Plugin/comments.pm:641 +#: ../IkiWiki/Plugin/comments.pm:645 msgid "comment moderation" msgstr "" -#: ../IkiWiki/Plugin/comments.pm:790 +#: ../IkiWiki/Plugin/comments.pm:802 #, perl-format msgid "%i comment" msgid_plural "%i comments" @@ -270,7 +270,7 @@ msgstr[1] "" #. translators: Here "Comment" is a verb; #. translators: the user clicks on it to #. translators: post a comment. -#: ../IkiWiki/Plugin/comments.pm:800 +#: ../IkiWiki/Plugin/comments.pm:812 msgid "Comment" msgstr "" @@ -305,9 +305,9 @@ msgstr "" msgid "creating %s" msgstr "" -#: ../IkiWiki/Plugin/editpage.pm:312 ../IkiWiki/Plugin/editpage.pm:334 -#: ../IkiWiki/Plugin/editpage.pm:345 ../IkiWiki/Plugin/editpage.pm:390 -#: ../IkiWiki/Plugin/editpage.pm:429 +#: ../IkiWiki/Plugin/editpage.pm:312 ../IkiWiki/Plugin/editpage.pm:332 +#: ../IkiWiki/Plugin/editpage.pm:343 ../IkiWiki/Plugin/editpage.pm:388 +#: ../IkiWiki/Plugin/editpage.pm:430 #, perl-format msgid "editing %s" msgstr "" @@ -320,12 +320,12 @@ msgstr "" msgid "match not specified" msgstr "" -#: ../IkiWiki/Plugin/edittemplate.pm:64 +#: ../IkiWiki/Plugin/edittemplate.pm:70 #, perl-format msgid "edittemplate %s registered for %s" msgstr "" -#: ../IkiWiki/Plugin/edittemplate.pm:125 ../IkiWiki/Plugin/inline.pm:339 +#: ../IkiWiki/Plugin/edittemplate.pm:131 ../IkiWiki/Plugin/inline.pm:339 #: ../IkiWiki/Plugin/template.pm:44 msgid "failed to process template:" msgstr "" @@ -356,18 +356,18 @@ msgstr "" msgid "%s is an attachment, not a page." msgstr "" -#: ../IkiWiki/Plugin/git.pm:687 ../IkiWiki/Plugin/git.pm:705 -#: ../IkiWiki/Receive.pm:130 +#: ../IkiWiki/Plugin/git.pm:724 ../IkiWiki/Plugin/git.pm:742 +#: ../IkiWiki/Receive.pm:129 #, perl-format msgid "you are not allowed to change %s" msgstr "" -#: ../IkiWiki/Plugin/git.pm:727 +#: ../IkiWiki/Plugin/git.pm:764 #, perl-format msgid "you cannot act on a file with mode %s" msgstr "" -#: ../IkiWiki/Plugin/git.pm:731 +#: ../IkiWiki/Plugin/git.pm:768 msgid "you are not allowed to change file modes" msgstr "" @@ -513,7 +513,7 @@ msgstr "" msgid "more" msgstr "" -#: ../IkiWiki/Plugin/openid.pm:58 +#: ../IkiWiki/Plugin/openid.pm:70 #, perl-format msgid "failed to load openid module: " msgstr "" @@ -610,7 +610,7 @@ msgstr "" msgid "rebuilding all pages to fix meta titles" msgstr "" -#: ../IkiWiki/Plugin/po.pm:394 ../IkiWiki/Render.pm:769 +#: ../IkiWiki/Plugin/po.pm:394 ../IkiWiki/Render.pm:784 #, perl-format msgid "building %s" msgstr "" @@ -619,48 +619,48 @@ msgstr "" msgid "updated PO files" msgstr "" -#: ../IkiWiki/Plugin/po.pm:456 +#: ../IkiWiki/Plugin/po.pm:455 msgid "" "Can not remove a translation. If the master page is removed, however, its " "translations will be removed as well." msgstr "" -#: ../IkiWiki/Plugin/po.pm:476 +#: ../IkiWiki/Plugin/po.pm:475 msgid "" "Can not rename a translation. If the master page is renamed, however, its " "translations will be renamed as well." msgstr "" -#: ../IkiWiki/Plugin/po.pm:876 +#: ../IkiWiki/Plugin/po.pm:875 #, perl-format msgid "POT file (%s) does not exist" msgstr "" -#: ../IkiWiki/Plugin/po.pm:890 +#: ../IkiWiki/Plugin/po.pm:889 #, perl-format msgid "failed to copy underlay PO file to %s" msgstr "" -#: ../IkiWiki/Plugin/po.pm:899 +#: ../IkiWiki/Plugin/po.pm:898 #, perl-format msgid "failed to update %s" msgstr "" -#: ../IkiWiki/Plugin/po.pm:905 +#: ../IkiWiki/Plugin/po.pm:904 #, perl-format msgid "failed to copy the POT file to %s" msgstr "" -#: ../IkiWiki/Plugin/po.pm:941 +#: ../IkiWiki/Plugin/po.pm:940 msgid "N/A" msgstr "" -#: ../IkiWiki/Plugin/po.pm:954 +#: ../IkiWiki/Plugin/po.pm:953 #, perl-format msgid "failed to translate %s" msgstr "" -#: ../IkiWiki/Plugin/po.pm:1038 +#: ../IkiWiki/Plugin/po.pm:1037 msgid "removed obsolete PO files" msgstr "" @@ -803,7 +803,7 @@ msgstr "" msgid "Please select the attachments to remove." msgstr "" -#: ../IkiWiki/Plugin/remove.pm:216 +#: ../IkiWiki/Plugin/remove.pm:217 msgid "removed" msgstr "" @@ -853,7 +853,7 @@ msgstr "" msgid "rename %s to %s" msgstr "" -#: ../IkiWiki/Plugin/rename.pm:576 +#: ../IkiWiki/Plugin/rename.pm:577 #, perl-format msgid "update for rename of %s to %s" msgstr "" @@ -988,26 +988,26 @@ msgstr "" msgid "enable %s?" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:276 +#: ../IkiWiki/Plugin/websetup.pm:272 msgid "setup file for this wiki is not known" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:292 +#: ../IkiWiki/Plugin/websetup.pm:288 msgid "main" msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:435 +#: ../IkiWiki/Plugin/websetup.pm:431 msgid "" "The configuration changes shown below require a wiki rebuild to take effect." msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:439 +#: ../IkiWiki/Plugin/websetup.pm:435 msgid "" "For the configuration changes shown below to fully take effect, you may need " "to rebuild the wiki." msgstr "" -#: ../IkiWiki/Plugin/websetup.pm:476 +#: ../IkiWiki/Plugin/websetup.pm:472 #, perl-format msgid "Error: %s exited nonzero (%s). Discarding setup changes." msgstr "" @@ -1017,7 +1017,7 @@ msgstr "" msgid "cannot determine id of untrusted committer %s" msgstr "" -#: ../IkiWiki/Receive.pm:86 +#: ../IkiWiki/Receive.pm:85 #, perl-format msgid "bad file name %s" msgstr "" @@ -1034,47 +1034,47 @@ msgid "" "allow this" msgstr "" -#: ../IkiWiki/Render.pm:311 +#: ../IkiWiki/Render.pm:316 #, perl-format msgid "skipping bad filename %s" msgstr "" -#: ../IkiWiki/Render.pm:327 +#: ../IkiWiki/Render.pm:332 #, perl-format msgid "%s has multiple possible source pages" msgstr "" -#: ../IkiWiki/Render.pm:369 +#: ../IkiWiki/Render.pm:372 #, perl-format msgid "querying %s for file creation and modification times.." msgstr "" -#: ../IkiWiki/Render.pm:431 +#: ../IkiWiki/Render.pm:446 #, perl-format msgid "removing obsolete %s" msgstr "" -#: ../IkiWiki/Render.pm:505 +#: ../IkiWiki/Render.pm:520 #, perl-format msgid "building %s, which links to %s" msgstr "" -#: ../IkiWiki/Render.pm:514 +#: ../IkiWiki/Render.pm:529 #, perl-format msgid "removing %s, no longer built by %s" msgstr "" -#: ../IkiWiki/Render.pm:597 ../IkiWiki/Render.pm:679 +#: ../IkiWiki/Render.pm:612 ../IkiWiki/Render.pm:694 #, perl-format msgid "building %s, which depends on %s" msgstr "" -#: ../IkiWiki/Render.pm:692 +#: ../IkiWiki/Render.pm:707 #, perl-format msgid "building %s, to update its backlinks" msgstr "" -#: ../IkiWiki/Render.pm:821 +#: ../IkiWiki/Render.pm:836 #, perl-format msgid "ikiwiki: cannot build %s" msgstr "" @@ -1179,31 +1179,31 @@ msgstr "" msgid "cannot use multiple rcs plugins" msgstr "" -#: ../IkiWiki.pm:606 +#: ../IkiWiki.pm:607 #, perl-format msgid "failed to load external plugin needed for %s plugin: %s" msgstr "" -#: ../IkiWiki.pm:1298 +#: ../IkiWiki.pm:1299 #, perl-format msgid "preprocessing loop detected on %s at depth %i" msgstr "" -#: ../IkiWiki.pm:1993 +#: ../IkiWiki.pm:1994 msgid "yes" msgstr "" -#: ../IkiWiki.pm:2070 +#: ../IkiWiki.pm:2071 #, perl-format msgid "invalid sort type %s" msgstr "" -#: ../IkiWiki.pm:2091 +#: ../IkiWiki.pm:2092 #, perl-format msgid "unknown sort type %s" msgstr "" -#: ../IkiWiki.pm:2227 +#: ../IkiWiki.pm:2228 #, perl-format msgid "cannot match pages: %s" msgstr "" diff --git a/t/bazaar.t b/t/bazaar.t index 0bdd883d5..3e54ec4dc 100755 --- a/t/bazaar.t +++ b/t/bazaar.t @@ -24,11 +24,19 @@ IkiWiki::checkconfig(); system "bzr init $config{srcdir}"; +use CGI::Session; +my $session=CGI::Session->new; +$session->param("name", "Joe User"); + # Web commit my $test1 = readfile("t/test1.mdwn"); writefile('test1.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test1.mdwn"); -IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo", "Joe User"); +IkiWiki::rcs_commit( + file => "test1.mdwn", + message => "Added the first page", + token => "moo", + session => $session); my @changes; @changes = IkiWiki::rcs_recentchanges(3); @@ -66,7 +74,10 @@ ok($mtime >= time() - 20); writefile('test3.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test3.mdwn"); IkiWiki::rcs_rename("test3.mdwn", "test4.mdwn"); -IkiWiki::rcs_commit_staged("Added the 4th page", "moo", "Joe User"); +IkiWiki::rcs_commit_staged( + message => "Added the 4th page", + session => $session, +); @changes = IkiWiki::rcs_recentchanges(4); @@ -75,7 +86,10 @@ is($changes[0]{pages}[0]{"page"}, "test4"); ok(mkdir($config{srcdir}."/newdir")); IkiWiki::rcs_rename("test4.mdwn", "newdir/test5.mdwn"); -IkiWiki::rcs_commit_staged("Added the 5th page", "moo", "Joe User"); +IkiWiki::rcs_commit_staged( + message => "Added the 5th page", + session => $session, +); @changes = IkiWiki::rcs_recentchanges(4); @@ -83,6 +97,9 @@ is($#changes, 3); is($changes[0]{pages}[0]{"page"}, "newdir/test5"); IkiWiki::rcs_remove("newdir/test5.mdwn"); -IkiWiki::rcs_commit_staged("Remove the 5th page", "moo", "Joe User"); +IkiWiki::rcs_commit_staged( + message => "Remove the 5th page", + session => $session, +); system "rm -rf $dir"; diff --git a/t/cvs.t b/t/cvs.t index 2808973be..96359ab6e 100755 --- a/t/cvs.t +++ b/t/cvs.t @@ -46,7 +46,11 @@ system "cvs -d $cvsrepo co -d $config{srcdir} ikiwiki >/dev/null"; my $test1 = readfile("t/test1.mdwn"); writefile('test1.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test1.mdwn"); -IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo"); +IkiWiki::rcs_commit( + files => "test1.mdwn", + message => "Added the first page", + token => "moo" +); my @changes; @changes = IkiWiki::rcs_recentchanges(3); diff --git a/t/git.t b/t/git.t index f1c24b359..ee778ebf0 100755 --- a/t/git.t +++ b/t/git.t @@ -38,7 +38,11 @@ is($changes[0]{pages}[0]{"page"}, ".gitignore"); my $test1 = readfile("t/test1.mdwn"); writefile('test1.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test1.mdwn"); -IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo"); +IkiWiki::rcs_commit( + file => "test1.mdwn", + message => "Added the first page", + token => "moo", +); @changes = IkiWiki::rcs_recentchanges(3); @@ -68,7 +72,7 @@ is($changes[1]{pages}[0]{"page"}, "test1"); writefile('test3.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test3.mdwn"); IkiWiki::rcs_rename("test3.mdwn", "test4.mdwn"); -IkiWiki::rcs_commit_staged("Added the 4th page", "moo", "Joe User"); +IkiWiki::rcs_commit_staged(message => "Added the 4th page"); @changes = IkiWiki::rcs_recentchanges(4); @@ -77,7 +81,7 @@ is($changes[0]{pages}[0]{"page"}, "test4"); ok(mkdir($config{srcdir}."/newdir")); IkiWiki::rcs_rename("test4.mdwn", "newdir/test5.mdwn"); -IkiWiki::rcs_commit_staged("Added the 5th page", "moo", "Joe User"); +IkiWiki::rcs_commit_staged(message => "Added the 5th page"); @changes = IkiWiki::rcs_recentchanges(4); @@ -85,6 +89,6 @@ is($#changes, 3); is($changes[0]{pages}[0]{"page"}, "newdir/test5"); IkiWiki::rcs_remove("newdir/test5.mdwn"); -IkiWiki::rcs_commit_staged("Remove the 5th page", "moo", "Joe User"); +IkiWiki::rcs_commit_staged(message => "Remove the 5th page"); system "rm -rf $dir"; diff --git a/t/mercurial.t b/t/mercurial.t index 954b17526..b64ea8e56 100755 --- a/t/mercurial.t +++ b/t/mercurial.t @@ -22,13 +22,22 @@ $config{srcdir} = "$dir/repo"; IkiWiki::loadplugins(); IkiWiki::checkconfig(); +use CGI::Session; +my $session=CGI::Session->new; +$session->param("name", "Joe User"); + system "hg init $config{srcdir}"; # Web commit my $test1 = readfile("t/test1.mdwn"); writefile('test1.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test1.mdwn"); -IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo", "Joe User"); +IkiWiki::rcs_commit( + file => "test1.mdwn", + message => "Added the first page", + token => "moo", + session => $session, +); my @changes; @changes = IkiWiki::rcs_recentchanges(3); diff --git a/t/svn.t b/t/svn.t index 5223b4409..82b71b5fc 100755 --- a/t/svn.t +++ b/t/svn.t @@ -36,7 +36,11 @@ system "svn co file://$svnrepo/trunk $config{srcdir} >/dev/null"; my $test1 = readfile("t/test1.mdwn"); writefile('test1.mdwn', $config{srcdir}, $test1); IkiWiki::rcs_add("test1.mdwn"); -IkiWiki::rcs_commit("test1.mdwn", "Added the first page", "moo"); +IkiWiki::rcs_commit( + file => "test1.mdwn", + message => "Added the first page", + token => "moo", +); my @changes; @changes = IkiWiki::rcs_recentchanges(3); -- cgit v1.2.3