From 2d1ff30e13d91cc4fa355bc392ba6044c6a6f31e Mon Sep 17 00:00:00 2001 From: Amitai Schlair Date: Sun, 30 Aug 2009 01:14:22 -0400 Subject: Knock off another to-do item: "Don't slurp the entire cvsps output into memory (!)." --- IkiWiki/Plugin/cvs.pm | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'IkiWiki') diff --git a/IkiWiki/Plugin/cvs.pm b/IkiWiki/Plugin/cvs.pm index ccd9527cd..c1b40bda1 100644 --- a/IkiWiki/Plugin/cvs.pm +++ b/IkiWiki/Plugin/cvs.pm @@ -278,12 +278,26 @@ sub rcs_recentchanges($) { chdir $config{srcdir} || error("Cannot chdir to $config{srcdir}: $!"); - # there's no option to get the last N changesets, so read backwards - open CVSPS, "env TZ=UTC cvsps -q --cvs-direct -z 30 -x |" || error "couldn't get cvsps output: $!\n"; - my @spsvc = reverse ; # is this great? no it is not - close CVSPS || error "couldn't close cvsps output: $!\n"; + # There's no cvsps option to get the last N changesets. + # Write full output to a temp file and read backwards. - while (my $line = shift @spsvc) { + eval q{use File::Temp qw/tempfile/}; + error($@) if $@; + eval q{use File::ReadBackwards}; + error($@) if $@; + + my (undef, $tmpfile) = tempfile(OPEN=>0); + system("env TZ=UTC cvsps -q --cvs-direct -z 30 -x >$tmpfile"); + if ($? == -1) { + error "couldn't run cvsps: $!\n"; + } elsif (($? >>8) != 0) { + error "cvsps exited " . ($? >> 8) . ": $!\n"; + } + + tie(*SPSVC, 'File::ReadBackwards', $tmpfile) + || error "couldn't open $tmpfile for read: $!\n"; + + while (my $line = ) { $line =~ /^$/ || error "expected blank line, got $line"; my ($rev, $user, $committype, $when); @@ -303,7 +317,7 @@ sub rcs_recentchanges($) { # @pages (and revisions) # - while ($line = shift @spsvc) { + while ($line = ) { last if ($line =~ /^Members:/); for ($line) { s/^\s+//; @@ -323,7 +337,7 @@ sub rcs_recentchanges($) { } if length $page; } - while ($line = shift @spsvc) { + while ($line = ) { last if ($line =~ /^Log:$/); chomp $line; unshift @message, { line => $line }; @@ -337,31 +351,31 @@ sub rcs_recentchanges($) { $committype="cvs"; } - $line = shift @spsvc; # Tag - $line = shift @spsvc; # Branch + $line = ; # Tag + $line = ; # Branch - $line = shift @spsvc; + $line = ; if ($line =~ /^Author: (.*)$/) { $user = $1 unless defined $user && length $user; } else { error "expected Author, got $line"; } - $line = shift @spsvc; + $line = ; if ($line =~ /^Date: (.*)$/) { $when = str2time($1, 'UTC'); } else { error "expected Date, got $line"; } - $line = shift @spsvc; + $line = ; if ($line =~ /^PatchSet (.*)$/) { $rev = $1; } else { error "expected PatchSet, got $line"; } - $line = shift @spsvc; # --------------------- + $line = ; # --------------------- push @ret, { rev => $rev, @@ -371,9 +385,11 @@ sub rcs_recentchanges($) { message => [@message], pages => [@pages], } if @pages; - return @ret if @ret >= $num; + last if @ret >= $num; } + unlink($tmpfile) || error "couldn't unlink $tmpfile: $!\n"; + return @ret; } -- cgit v1.2.3