Permalink
Browse files

Item14368: reinstated RcsWrap to handler tests, fixed the problems th…

…at showed up (none serious), added tests for edge cases of getRevision. Still not sure what causes the corrupt histories in RcsLite, but closer to an understanding.
  • Loading branch information...
cdot authored and gac410 committed Apr 3, 2017
1 parent b081dd9 commit ee3a5bd1da3f9fd82e555fce6886615e423acaf3
@@ -253,8 +253,8 @@ sub _ensureRead {
$downToVersion ||= 0; # just in case
# If we only need tha latest and we already have the head, that's our rev
$downToVersion = $this->{head} if !$downToVersion && $this->{head};
# If we only need the latest and we already have the head, that's our rev
$downToVersion = $this->{head} if ( !$downToVersion && $this->{head} );
$downToVersion = 1 if $downToVersion < 0; # read everything
@@ -286,22 +286,26 @@ sub _ensureRead {
#print STDERR "Reading ".($historyOnly?'history':'everything')." to $downToVersion\n";
# We *will* end up re-reading the history if we previously only read the history; there is
# no way to restart the parse mid-stream (though an ftell and fseek would do it if we saved
# the rest of the state)
# We *will* end up re-reading the history if we previously only
# read the history; there is no way to restart the parse mid-stream
# (though an ftell and fseek would do it if we saved the rest of the
# state)
while (1) {
( $_, $string ) = _readTo( $fh, $term );
last if ( !$_ );
#print STDERR "expecting $state: seeing $_\n";
if ( $state eq 'admin.head' ) {
if (/^head\s+([0-9]+)\.([0-9]+);$/o) {
if (/^head\s+([0-9]+)\.([0-9]+);$/) {
ASSERT( $1 eq 1 ) if DEBUG;
$headNum = $2;
# If $downToVersion is 0, we now know what version to ready up to
$downToVersion = $headNum unless $downToVersion;
# If $downToVersion is 0, we now know what version to read up to
$downToVersion = $headNum
if $downToVersion <= 0
|| $downToVersion > $headNum;
$state = 'admin.access'; # Don't support branches
}
else {
@@ -533,8 +537,11 @@ sub ci {
}
my $head = $this->{head} || 0;
if ($head) {
my $lNew = _split($data);
my $lOld = _split( $this->{revs}[$head]->{text} );
my $lNew = _split($data);
# The top of the revisions array contains the plain text of
# the topic in it's latest incarnation, with no differences.
my $lOld = _split( $this->{revs}[$head]->{text} );
my $delta = _diff( $lNew, $lOld );
$this->{revs}[$head]->{text} = $delta;
}
@@ -678,22 +685,28 @@ sub _patch {
my $length = $3;
if ( $act eq 'd' ) {
my $start = $offset + $adj - 1;
# If the splice fails, it's almost certainly a problem in the
# later revision
my @removed = splice( @$text, $start, $length );
$adj -= $length;
$pos++;
}
elsif ( $act eq 'a' ) {
my @toAdd = @$delta[ $pos + 1 .. $pos + $length ];
# Fix for Item2957
# Check if the last element of what is to be added contains
# a valid marker. If it does, the chances are very high that
# this topic was saved using a broken version of RcsLite, and
# a line ending has been lost.
# Fixes for twikibug Item2957
# Check if the last element of what is to be
# added contains a valid marker. If it does, the chances
# are very high that this topic was saved using a broken
# version of RcsLite, and a line ending has been lost.
# As soon as a topic containing this problem is re-saved
# using this code, the need for this hack should go away,
# as the line endings will now be correct.
if ( scalar(@toAdd)
# If the first element contains a valid marker this is
# also indicative of a problem, but it's unclear how to
# resolve that as the cause is unknown.
if (scalar(@toAdd)
&& $toAdd[$#toAdd] =~ /^([ad])(\d+)\s(\d+)$/
&& $2 > $pos )
{
@@ -726,6 +739,7 @@ sub getRevision {
return $this->SUPER::getRevision($version);
}
$version = 0 if $version < 0;
$this->_ensureRead( $version, 0 );
return $this->SUPER::getRevision($version)
@@ -734,12 +748,11 @@ sub getRevision {
my $head = $this->{head};
return $this->SUPER::getRevision($version) unless $head;
if ( $version == $head ) {
return ( $this->{revs}[$version]->{text}, 1 );
}
$version = $head if $version > $head;
my $headText = $this->{revs}[$head]->{text};
my $text = _split($headText);
if ( $version <= 0 || $version >= $head ) {
return ( $headText, 1 );
}
my $text = _split($headText);
return ( _patchN( $this, $text, $head - 1, $version ), 0 );
}
@@ -129,6 +129,8 @@ sub ci {
$comment = 'none' unless $comment;
undef $this->{numRevisions};
my ( $cmd, $rcsOutput, $exit, $stderr );
if ( defined($date) ) {
require Foswiki::Time;
@@ -187,6 +189,7 @@ sub repRev {
$date = Foswiki::Time::formatTime( $date, '$rcs', 'gmtime' );
_lock($this);
undef $this->{numRevisions};
my ( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{ciDateCmd},
DATE => $date,
@@ -213,17 +216,17 @@ sub _deleteRevision {
my ( $this, $rev ) = @_;
# delete latest revision (unlock (may not be needed), delete revision)
my ( $rcsOut, $exit ) =
my ( $rcsOut, $exit, $stderr ) =
Foswiki::Sandbox->sysCommand( $Foswiki::cfg{RCS}{unlockCmd},
FILENAME => _encode( $this->{file}, 1 ) );
if ($exit) {
throw Error::Simple(
$Foswiki::cfg{RCS}{unlockCmd} . ' failed: ' . $rcsOut );
"$Foswiki::cfg{RCS}{unlockCmd} failed: $rcsOut $stderr");
}
chmod( $Foswiki::cfg{Store}{filePermission}, _encode( $this->{file}, 1 ) );
( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
( $rcsOut, $exit, $stderr ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{delRevCmd},
REVISION => '1.' . $rev,
FILENAME => _encode( $this->{file}, 1 )
@@ -232,13 +235,13 @@ sub _deleteRevision {
if ($exit) {
throw Error::Simple( $Foswiki::cfg{RCS}{delRevCmd} . ' of '
. $this->hidePath( $this->{file} )
. ' failed: '
. $rcsOut );
. " failed: $rcsOut $stderr" );
}
# Update the checkout
undef $this->{numRevisions};
$rev--;
( $rcsOut, $exit ) = Foswiki::Sandbox->sysCommand(
( $rcsOut, $exit, $stderr ) = Foswiki::Sandbox->sysCommand(
$Foswiki::cfg{RCS}{coCmd},
REVISION => '1.' . $rev,
FILENAME => _encode( $this->{file}, 1 )
@@ -247,8 +250,7 @@ sub _deleteRevision {
if ($exit) {
throw Error::Simple( $Foswiki::cfg{RCS}{coCmd} . ' of '
. $this->hidePath( $this->{file} )
. ' failed: '
. $rcsOut );
. " failed: $rcsOut $stderr" );
}
$this->saveFile( $this->{file}, $rcsOut );
}
@@ -265,17 +267,13 @@ sub getRevision {
{
# Get the latest rev from the cache
return ( $this->SUPER::getRevision($version) );
return ( $this->SUPER::getRevision($version), 1 );
}
# We've been asked for an explicit rev. The rev might be outside the
# range of revs in RCS. RCS will return the latest, though it reports
# the rev retrieved to STDERR (no use to us, as we have no access
# to STDERR)
# SMELL: we need to determine if the rev we are returning is the latest.
# co prints the retrieved revision, but unfortunately it prints it
# to STDERR, which the Sandbox can't retrieve.
# the rev retrieved to STDERR
$version = 2 ^ 31 if $version <= 0;
my $tmpfile;
my $tmpRevFile;
@@ -313,7 +311,16 @@ sub getRevision {
if ( defined $stderr
&& $stderr =~ /revision 1\.(\d+)/s )
{
$isLatest = ( $version >= $1 );
if ( $version > $1 ) {
$this->{numRevisions} = $1;
$isLatest = 1;
}
elsif ( defined $this->{numRevisions} ) {
$isLatest = ( $1 == $this->{numRevisions} );
}
else {
$isLatest = ( $1 == $this->_numRevisions() );
}
}
# otherwise we will have to resort to numRevisions to tell if
@@ -376,11 +383,12 @@ sub getInfo {
sub _numRevisions {
my $this = shift;
return $this->{numRevisions} if defined $this->{numRevisions};
unless ( $this->revisionHistoryExists() ) {
# If there is no history, there can only be one.
return 1 if $this->storedDataExists();
return 0;
return $this->{numRevisions} = $this->storedDataExists() ? 1 : 0;
}
my ( $rcsOutput, $exit ) =
@@ -394,12 +402,12 @@ sub _numRevisions {
. $rcsOutput );
}
if ( $rcsOutput =~ /head:\s+\d+\.(\d+)\n/ ) {
return $1;
return $this->{numRevisions} = $1;
}
if ( $rcsOutput =~ /total revisions: (\d+)\n/ ) {
return $1;
return $this->{numRevisions} = $1;
}
return 1;
return $this->{numRevisions} = 1;
}
# implements Rcs::Handler
@@ -66,7 +66,8 @@ sub fixture_groups {
my $groups = [];
push( @$groups, 'RcsLite' );
return ($groups);
# return ($groups);
if ( FoswikiStoreTestCase::rcs_is_installed() ) {
push( @$groups, 'RcsWrap' );
@@ -910,19 +911,37 @@ HERE
$rcs->addRevisionFromText( $rev2, "more", "idiot", $time );
$rcs = $class->new( new StoreStub, $testWeb, 'Item2957', '' );
$rcs->addRevisionFromText( $rev3, "more", "idiot", $time );
$rcs = $class->new( new StoreStub, $testWeb, 'Item2957', '' );
my ($text) = $rcs->getRevision(1);
if ( $Foswiki::cfg{OS} eq 'WINDOWS' ) {
$text =~ s/\r\n/\n/sg;
}
$this->assert_equals( $rev1, $text );
my $isl;
$rcs = $class->new( new StoreStub, $testWeb, 'Item2957', '' );
($text) = $rcs->getRevision(2);
( $text, $isl ) = $rcs->getRevision(1);
$this->assert_equals( $rev1, $text );
$this->assert( !$isl );
$rcs = $class->new( new StoreStub, $testWeb, 'Item2957', '' );
( $text, $isl ) = $rcs->getRevision(2);
$this->assert( !$isl );
$this->assert_equals( $rev2, $text );
$rcs = $class->new( new StoreStub, $testWeb, 'Item2957', '' );
($text) = $rcs->getRevision(3);
( $text, $isl ) = $rcs->getRevision(3);
$this->assert($isl);
$this->assert_equals( $rev3, $text );
$rcs = $class->new( new StoreStub, $testWeb, 'Item2957', '' );
( $text, $isl ) = $rcs->getRevision(4);
$this->assert($isl);
$this->assert_equals( $rev3, $text );
( $text, $isl ) = $rcs->getRevision(0);
$this->assert($isl);
$this->assert_equals( $rev3, $text );
( $text, $isl ) = $rcs->getRevision(-1);
$this->assert_equals( $rev3, $text );
$this->assert($isl);
}
sub verify_Item3122 {

0 comments on commit ee3a5bd

Please sign in to comment.