From dee2940c0bc97080088c99f399cd0ff0df3bec23 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 16 Apr 2010 18:29:45 -0400 Subject: [PATCH] automatically run --gettime, and optimise it for git * Automatically run --gettime the first time ikiwiki is run on a given srcdir. * Optimise --gettime for git, so it's appropriatly screamingly fast. (This could be done for other backends too.) * However, --gettime for git no longer follows renames. * Use above to fix up timestamps on docwiki, as well as ensure that timestamps on basewiki files shipped in the deb are sane. --- IkiWiki.pm | 2 +- IkiWiki/Plugin/git.pm | 48 +++++++++++++++++++++++++++++++----------- IkiWiki/Render.pm | 11 ++++++++-- debian/changelog | 7 ++++++ debian/control | 2 +- doc/plugins/write.mdwn | 4 ++++ doc/usage.mdwn | 2 +- docwiki.setup | 17 ++++++++++++++- ikiwiki.in | 2 +- 9 files changed, 76 insertions(+), 19 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 7655dada5..b37b1f344 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -442,7 +442,6 @@ sub getsetup () { }, gettime => { type => "internal", - default => 0, description => "running in gettime mode", safe => 0, rebuild => 0, @@ -1512,6 +1511,7 @@ sub loadindex () { open ($in, "<", "$config{wikistatedir}/indexdb") || return; } else { + $config{gettime}=1; # first build return; } } diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index 86d80186f..aa402c04f 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -616,27 +616,51 @@ sub rcs_diff ($) { } } -sub rcs_getctime ($) { +{ +my %time_cache; + +sub findtimes ($$) { my $file=shift; + my $id=shift; # 0 = mtime ; 1 = ctime + # Remove srcdir prefix $file =~ s/^\Q$config{srcdir}\E\/?//; - my @raw_lines = run_or_die('git', 'log', - '--follow', '--no-merges', - '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c', - '-r', '--', $file); - my @ci; - while (my $parsed = parse_diff_tree("", \@raw_lines)) { - push @ci, $parsed; + if (! keys %time_cache) { + my $date; + foreach my $line (run_or_die('git', 'log', + '--pretty=format:%ct', + '--name-only', '--relative')) { + if (! defined $date && $line =~ /^(\d+)$/) { + $date=$line; + } + elsif (! length $line) { + $date=undef; + } + else { + if (! $time_cache{$line}) { + $time_cache{$line}[0]=$date; # mtime + } + $time_cache{$line}[1]=$date; # ctime + } + } } - my $ctime = $ci[$#ci]->{'author_epoch'}; - debug("ctime for '$file': ". localtime($ctime)); - return $ctime; + return exists $time_cache{$file} ? $time_cache{$file}[$id] : 0; +} + +} + +sub rcs_getctime ($) { + my $file=shift; + + return findtimes($file, 1); } sub rcs_getmtime ($) { - error "rcs_getmtime is not implemented for git\n"; # TODO + my $file=shift; + + return findtimes($file, 0); } sub rcs_receive () { diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index e1cb68462..a6b0f0617 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -352,6 +352,8 @@ sub find_new_files ($) { my @new; my @internal_new; + my $times_noted; + foreach my $file (@$files) { my $page=pagename($file); if (exists $pagesources{$page} && $pagesources{$page} ne $file) { @@ -363,7 +365,12 @@ sub find_new_files ($) { if (isinternal($page)) { push @internal_new, $file; } - else { + elsif ($config{rcs}) { + if (! $times_noted) { + debug(sprintf(gettext("querying %s for file creation and modification times.."), $config{rcs})); + $times_noted=1; + } + push @new, $file; if ($config{gettime} && -e "$config{srcdir}/$file") { eval { @@ -377,7 +384,7 @@ sub find_new_files ($) { } my $mtime; eval { - my $mtime=rcs_getmtime("$config{srcdir}/$file"); + $mtime=rcs_getmtime("$config{srcdir}/$file"); }; if ($@) { print STDERR $@; diff --git a/debian/changelog b/debian/changelog index 615d5916f..60a67cbe3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -47,8 +47,15 @@ ikiwiki (3.20100415) UNRELEASED; urgency=low * Rename --getctime to --gettime. (The old name still works for backwards compatability.) * --gettime now also looks up last modification time. + * Automatically run --gettime the first time ikiwiki is run on + a given srcdir. * Add rcs_getmtime to plugin API; currently only implemented for git. + * Optimise --gettime for git, so it's appropriatly screamingly + fast. (This could be done for other backends too.) + * However, --gettime for git no longer follows renames. + * Use above to fix up timestamps on docwiki, as well as ensure that + timestamps on basewiki files shipped in the deb are sane. -- Joey Hess Sun, 04 Apr 2010 12:17:11 -0400 diff --git a/debian/control b/debian/control index 87f7d8209..ae06f32b0 100644 --- a/debian/control +++ b/debian/control @@ -7,7 +7,7 @@ Build-Depends-Indep: dpkg-dev (>= 1.9.0), libxml-simple-perl, libtimedate-perl, libhtml-template-perl, libhtml-scrubber-perl, wdg-html-validator, libhtml-parser-perl, liburi-perl, perlmagick, po4a (>= 0.34), - libfile-chdir-perl + libfile-chdir-perl, Maintainer: Joey Hess Uploaders: Josh Triplett Standards-Version: 3.8.4 diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index cf7044b2c..0bf6fcf48 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -1085,6 +1085,8 @@ it up in the history. It's ok if this is not implemented, and throws an error. +If the RCS cannot determine a ctime for the file, return 0. + #### `rcs_getmtime($)` This is used to get the page modification time for a file from the RCS, by @@ -1092,6 +1094,8 @@ looking it up in the history. It's ok if this is not implemented, and throws an error. +If the RCS cannot determine a mtime for the file, return 0. + #### `rcs_receive()` This is called when ikiwiki is running as a pre-receive hook (or diff --git a/doc/usage.mdwn b/doc/usage.mdwn index 553fef01e..2e12517ea 100644 --- a/doc/usage.mdwn +++ b/doc/usage.mdwn @@ -320,7 +320,7 @@ also be configured using a setup file. intercepted. If you enable this option then you must run at least the CGI portion of ikiwiki over SSL. -* --gettime +* --gettime, --no-gettime Extract creation and modification times for each new page from the the revision control's log. This is done automatically when building a diff --git a/docwiki.setup b/docwiki.setup index 8278b73ea..6bc200066 100644 --- a/docwiki.setup +++ b/docwiki.setup @@ -1,6 +1,18 @@ #!/usr/bin/perl # Configuration file for ikiwiki to build its documentation wiki. +# Use git during the build, if it's available and if we're building +# from a git checkout. This ensures ikiwiki gets the right mtimes and +# ctimes for files in the doc wiki. +our $rcs="norcs"; +BEGIN { + my $git=`which git 2>&1`; + chomp $git; + if (-x $git && -d ".git") { + $rcs="git"; + } +} + use IkiWiki::Setup::Standard { wikiname => "ikiwiki", srcdir => "doc", @@ -9,7 +21,7 @@ use IkiWiki::Setup::Standard { underlaydirbase => "underlays", underlaydir => "underlays/basewiki", discussion => 0, - exclude => qr/\/discussion|bugs\/*|todo\/*|forum\/*/, + exclude => qr/\/discussion|bugs\/*|todo\/*|forum\/*/, # save space locale => '', verbose => 1, syslog => 0, @@ -17,4 +29,7 @@ use IkiWiki::Setup::Standard { usedirs => 0, prefix_directives => 1, add_plugins => [qw{goodstuff version haiku polygen fortune table}], + disable_plugins => [qw{recentchanges}], # not appropriate for doc dir + rcs => $rcs, + gitorigin_branch => '', # don't pull during build } diff --git a/ikiwiki.in b/ikiwiki.in index 801ff9a0b..acd37f802 100755 --- a/ikiwiki.in +++ b/ikiwiki.in @@ -45,7 +45,7 @@ sub getconfig () { "usedirs!" => \$config{usedirs}, "prefix-directives!" => \$config{prefix_directives}, "getctime" => \$config{gettime}, - "gettime" => \$config{gettime}, + "gettime!" => \$config{gettime}, "numbacklinks=i" => \$config{numbacklinks}, "rcs=s" => \$config{rcs}, "no-rcs" => sub { $config{rcs}="" }, -- 2.32.0.93.g670b81a890