1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
package VCP ;
=head1 NAME
VCP - Versioned Copy, copying hierarchies of versioned files
=head1 SYNOPSIS
see the vcp command line.
=head1 DESCRIPTION
This module copies hierarchies of versioned files between repositories, and
between repositories and RevML (.revml) files.
Stay tuned for more documentation.
=head1 METHODS
=over
=for test_scripts t/10vcp.t t/50revml.t
=cut
$VERSION = 0.9 ;
$CHANGE_ID = ( q$Change: 4232 $ =~ /(\d+)/ )[0];
$DATE = ( q$Date: 2004/03/18 $ =~ /(\d[\d[:punct:]]+\d)/ )[0];
use strict ;
use VCP::Logger qw( lg pr );
require VCP::Plugin;
require VCP::Source;
require VCP::Dest;
#use fields (
# 'PLUGINS', # The VCP::Source to pull data from
#) ;
=item new
$ex = VCP->new( $source, $dest ) ;
where
$source is an instance of VCP::Source
$dest is an instance of VCP::Dest
=cut
sub new {
my $class = shift;
my $self = bless {}, $class;
my $w = length $#_;
for ( my $i = 0; $i <= $#_; ++$i ) {
lg sprintf "plugin %${w}d is %s", $i, ref $_[$i];
}
$self->{PLUGINS} = [ @_ ];
## Make sure that plugins are DESTROY-able and can clean up any mess
## they make even if the VCP object is still referred to somewhere,
## like a global variable or a plugin.
$self->{PLUGIN_CLEANUP} = sub { @{$self->{PLUGINS}} = () };
VCP::Plugin->queue_END_sub( $self->{PLUGIN_CLEANUP} );
return $self ;
}
sub DESTROY {
my $self = shift;
VCP::Plugin->cancel_END_sub( $self->{PLUGIN_CLEANUP} );
}
=item insert_required_sort_filter
Called if a sorting filter must be inserted.
Does nothing if there's already a sort filter in place.
=cut
sub insert_required_sort_filter {
my $self = shift ;
my @sort_keys;
for ( @{$self->{PLUGINS}}[ 1 .. $#{$self->{PLUGINS}} - 1 ] ) {
@sort_keys = $_->sort_keys( @sort_keys );
}
my @sort_filters = $self->{PLUGINS}->[-1]->sort_filters( @sort_keys );
if ( @sort_filters ) {
pr "appending required ",
join( ", ", map $_->filter_name, @sort_filters ),
@sort_filters == 1 ? " filter" : " filters";
splice @{$self->{PLUGINS}}, -1, 0, @sort_filters;
}
}
=item copy_all
$vcp->copy_all( $header, $footer ) ;
Calls $source->handle_header, $source->copy_revs, and $source->handle_footer.
=cut
sub copy_all {
my $self = shift ;
my ( $header, $footer ) = @_ ;
lg "Plugins: ",
join ", ",
map $_->isa( "VCP::Filter" ) ? $_->filter_name : ref $_,
@{$self->{PLUGINS}};
{
my $dest = $self->{PLUGINS}->[-1];
for ( reverse @{$self->{PLUGINS}}[0..$#{$self->{PLUGINS}} -1] ) {
$_->dest( $dest );
$dest = $_;
}
}
local $VCP::vcp = $self; ## for debugging dumps
my $s = $self->{PLUGINS}->[0];
my $ok = eval {
$s->handle_header( $header ) ;
$s->copy_revs() ;
$s->handle_footer( $footer ) ;
1;
};
if ( ! $ok ) {
my $x = $@;
VCP::Logger::_interrupt_progress();
die $x;
}
## Removing this link allows the dest to be cleaned up earlier by perl,
## which keeps VCP::RefCountedFile from complaining about undeleted revs.
$s->dest( undef ) ;
return ;
}
=back
=head1 COPYRIGHT
Copyright 2000, Perforce Software, Inc. All Rights Reserved.
This module and the VCP package are licensed according to the terms given in
the file LICENSE accompanying this distribution, a copy of which is included in
L<vcp>.
=head1 AUTHOR
Barrie Slaymaker <barries@slaysys.com>
=cut
1
|