File Coverage

blib/lib/Kwiki/Archive/Cvs.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Kwiki::Archive::Cvs;
2              
3 1     1   26597 use strict;
  1         3  
  1         45  
4 1     1   7 use warnings;
  1         2  
  1         44  
5 1     1   1776 use Kwiki::Archive -Base;
  0            
  0            
6              
7             our $VERSION = '0.104';
8              
9             # It will try to add files to CVS every time they're changed; this
10             # fails silently when they're already present.
11              
12             # Misinteractions:
13             # Kwiki::Revisions tries to show the previous revision for single-revision pages.
14             # Kwiki::Pages trips up on the CVS directory; change the line to
15             # map {chomp; $_} `ls -1t $path | fgrep -xv CVS`;
16             # for a quick-and-dirty fix.
17              
18              
19             # These should be read once and cached.
20              
21             sub cvsSetting {
22             my $page = shift;
23             my $setting = shift;
24              
25             my $l = io($page->database_directory."/CVS/$setting")->getline or die "Unable to read CVS/$setting: $!";
26              
27             local ($/);
28             $/ = "\n";
29             chomp($l);
30             $l;
31             }
32              
33             sub cvsRoot {
34             my $page = shift;
35             $self->cvsSetting($page, 'Root');
36             }
37              
38             sub cvsRepository {
39             my $page = shift;
40             $self->cvsSetting($page, 'Repository');
41             }
42              
43             # Take responsibility for initialising this manually.
44             sub empty {
45             0;
46             }
47              
48             sub commit {
49             my $page = shift;
50             my $props = $self->page_properties($page);
51              
52             # Unconditionally add (this command will fail once the file is added)
53             system('cvs', '-Q', '-d', $self->cvsRoot($page), 'add', $page->io);
54              
55             my $msg = join ',',
56             $self->uri_escape($props->{edit_by}),
57             $props->{edit_time},
58             $props->{edit_unixtime};
59              
60             # my $msg = join ',', map {
61             # $_ . ":" . $props->{$_}
62             # } sort keys %$props;
63              
64             $self->cvs($page, 'commit', '-m', $msg, $page->io);
65             }
66              
67             sub revision_numbers {
68             my $page = shift;
69             [map $_->{revision_id}, @{$self->history($page)}];
70             }
71              
72             sub fetch_metadata {
73             my $page = shift;
74             my $rev = shift;
75              
76             my $rlog = io("cvs -Q -d ".$self->cvsRoot($page)." log -r1.$rev ".$page->io." |") or die $!;
77              
78             $rlog->utf8 if $self->has_utf8;
79             $self->parse_metadata($rlog->all);
80             }
81              
82             sub parse_metadata {
83             my $log = shift;
84             $log =~ /
85             ^revision\s+(\S+).*?
86             ^date:\s+(.+?);.*?\n
87             (.*)
88             /xms or die "Couldn't parse rlog:\n$log";
89              
90             my $revision_id = $1;
91             # my $archive_date = $2;
92             my $msg = $3;
93             chomp $msg;
94              
95             $msg =~ s/"//g; # Get rid of quote marks from old CVS commit messages
96             my ($edit_by, $edit_time, $edit_unixtime) = split ',', $msg;
97             $edit_time ||= $2;
98             $edit_unixtime ||= 0;
99             $revision_id =~ s/^1\.//;
100              
101             return {
102             revision_id => $revision_id,
103             edit_by => $self->uri_unescape($edit_by),
104             edit_time => $edit_time,
105             edit_unixtime => $edit_unixtime,
106             };
107             }
108              
109             sub history {
110             my $page = shift;
111              
112             my $rlog = io("cvs -Q -d ".$self->cvsRoot($page)." log ".$page->io." |") or die $!;
113              
114             $rlog->utf8 if $self->has_utf8;
115              
116             my $input = $rlog->all;
117             $input =~ s/
118             \n=+$
119             .*\Z
120             //msx;
121             my @rlog = split /^-+\n/m, $input;
122             shift(@rlog);
123              
124             return [
125             map $self->parse_metadata($_), @rlog
126             ];
127             }
128              
129             sub fetch {
130             my $page = shift;
131             my $revision_id = shift;
132             my $revision = "1.$revision_id";
133             local($/, *CO);
134             open CO, "cvs -Q -d ".$self->cvsRoot($page)." checkout -r$revision -p ".$self->cvsRepository($page)."/".$page->id." |"
135             or die $!;
136             binmode(CO, ':utf8') if $self->has_utf8;
137             scalar ;
138             }
139              
140             sub shell {
141             use Cwd;
142             $! = undef;
143             system(@_) == 0
144             or die "@_ failed:\n$?\nin " . Cwd::cwd();
145             }
146              
147             sub cvs {
148             my $page = shift;
149             $self->shell('cvs', '-Q', '-d', $self->cvsRoot($page), @_);
150             }
151              
152             1;
153              
154             __DATA__