—————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 ;
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