Author image Barrie Slaymaker


VCP::Plugin - A base class for VCP::Source and VCP::Dest



Some functionality is common to sources and destinations, such as cache access, Pod::Usage conversion, command-line access shortcut member, etc.



Creates an instance, see subclasses for options. The options passed are usually native command-line options for the underlying repository's client. These are usually parsed and, perhaps, checked for validity by calling the underlying command line.


This class uses the fields pragma, so you'll need to use base and possibly fields in any subclasses.


These methods are intended to support subclasses.

   $old_rev = $self->seen( $new_rev ) ;
   $old_r = $self->seen( $name ) ;

Called to register the fact that $new_rev has been seen, and to return the last request for the same resource, which refers to the previous version of the resource. If a plain scalar is passed, simply returns the last rev structure that was seen for that filename (but does not mark that filename as having been seen if it hasn't).

This is one of the few accessor methods in VCP's implementation that returns the previous value.


Deletes the last seen revision for a file. Returns nothing.


Returns TRUE if $dest->seen( $r ) has not yet been called.

   my $spec = $self->split_repo_spec( $spec ) ;

This splits a repository spec in one of the following formats:


in to the indicated fields, which are stored in $self and may be accessed and altered using "repo_scheme", "repo_user", "repo_password", "repo_server", and "repo_filespec". Some sources and destinations may add additional fields. The p4 drivers create an "repo_client" in VCP::Utils::p4, for instance, and parse the repo_user field to fill it in. See "parse_p4_repo_spec" in VCP::Utils::p4 for details.

The spec is parsed from the ends towars the middle in this order:

   1. SCHEME (up to first ':')
   2. FILESPEC  (after last ':')
   3. USER, PASSWORD (before first '@')
   4. SERVER (everything left).

This approach allows the FILESPEC string to contain '@', and the SERVER string to contain ':' and '@'. USER can contain ':'. Funky, but this works well, at least for cvs and p4.

If a section of the repo spec is not present, the corresponding entry in $hash will not exist.

The attributes repo_user, repo_password and repo_server are set automatically by this method. It does not store the SCHEME anyware since the SCHEME is usually ignored by the plugin (the plugin is selected using the scheme, so it knows the scheme implicitly), and the FILES setting often needs extra manipulation, so there's no point in storing it.

   GetOptions( ... ) or $self->usage_and_exit ;

Used by subclasses to die if unknown options are passed in.

Requires Pod::Usage when called.


Returns the temporary directory this plugin should use, usually something like "/tmp/vcp123/dest-p4".

   $full_path = $self->work_path( $filename, $rev ) ;

Returns the full path to the working copy of the local filename.

Each VCP::Plugin gets thier own hierarchy to use, usually rooted at a directory named /tmp/vcp$$/plugin-source-foo/ for a module VCP::Plugin::Source::foo. $$ is vcp's process ID.

This is typically $work_root/$filename/$rev, but this may change. $rev is put last instead of first in order to minimize the overhead of creating lots of directories.

It *must* be under $work_root in order for rm_work_path() to fully clean.

All directories will be created as needed, so you should be able to create the file easily after calling this. This is only called by subclasses, and is optional: a subclass could create it's own caching system.

Directories are created mode 0775 (rwxrwxr-x), subject to modification by umask or your local operating system. This will be modifiable in the future.

   $self->mkdir( $filename ) ;
   $self->mkdir( $filename, $mode ) ;

Makes a directory and any necessary parent directories.

The default mode is 770. Does some debug logging if any directories are created.

Returns nothing.

   $self->mkpdir( $filename ) ;
   $self->mkpdir( $filename, $mode ) ;

Makes the parent directory of a filename and all directories down to it.

The default mode is 770. Does some debug logging if any directories are created.

Returns the path of the parent directory.

   $self->rm_work_path( $filename, $rev ) ;
   $self->rm_work_path( $dirname ) ;

Removes a directory or file from the work. Also removes any and all directories that become empty as a result up to the work root (/tmp on Unix).

   $root = $self->work_root ;
   $self->work_root( $new_root ) ;
   $self->work_root( $new_root, $dir1, $dir2, .... ) ;

Gets/sets the work root. This defaults to

   File::Spec->tmpdir . "/vcp$$/" . $plugin_name

but may be altered. If set to a relative path, the current working directory is prepended. The returned value is always absolute, and will not change if you chdir(). Depending on the operating system, however, it might not be located on to the current volume. If not, it's a bug, please patch away.


Sets/gets the directory to chdir into before running the default command.

   $self->command_stderr_filter( qr/^cvs add: use 'cvs commit'.*\n/m ) ;
   $self->command_stderr_filter( sub { my $t = shift ; $$t =~ ... } ) ;

Some commands--cough*cvs*cough--just don't seem to be able to shut up on stderr. Other times we need to watch stderr for some meaningful output.

This allows you to filter out expected whinging on stderr so that the command appears to run cleanly and doesn't cause $self->cmd(...) to barf when it sees expected output on stderr.

This can also be used to filter out intermittent expected errors that aren't errors in all contexts when they aren't actually errors.

   $self->command_ok_result_codes( 0, 1 ) ;

Occasionally, a non-zero result is Ok. this method lets you set a list of acceptable result codes.

   $self->repo_scheme( $scheme_name ) ;
   $scheme_name = $self->repo_scheme ;

Sets/gets the scheme specified ("cvs", "p4", "revml", etc). This is normally superfluous, since the scheme name is peeked at in order to load the correct VCP::{Source,Dest}::* class, which then calls this.

This is usually set automatically by "parse_repo_spec".

   $self->repo_user( $user_name ) ;
   $user_name = $self->repo_user ;

Sets/gets the user name to log in to the repository with. Some plugins ignore this, like revml, while others, like p4, use it.

This is usually set automatically by "parse_repo_spec".

   $self->repo_password( $password ) ;
   $password = $self->repo_password ;

Sets/gets the password to log in to the repository with. Some plugins ignore this, like revml, while others, like p4, use it.

This is usually set automatically by "parse_repo_spec".

   $self->repo_server( $server ) ;
   $server = $self->repo_server ;

Sets/gets the repository to log in to. Some plugins ignore this, like revml, while others, like p4, use it.

This is usually set automatically by "parse_repo_spec".

   $self->repo_filespec( $filespec ) ;
   $filespec = $self->repo_filespec ;

Sets/gets the filespec.

This is usually set automatically by "parse_repo_spec".

   $self->rev_root( 'depot' ) ;
   $rr = $self->rev_root ;

The rev_root is the root of the tree being sourced. See "deduce_rev_root" for automated extraction.

Root values should have neither a leading or trailing directory separator.

'/' and '\' are recognized as directory separators and runs of these are converted to single '/' characters. Leading and trailing '/' characters are then removed.

   $self->deduce_rev_root ;
   print $self->rev_root ;

This is used in most plugins to deduce the rev_root from the filespec portion of the source or destination spec if the user did not specify a rev_root as an option.

This function sets the rev_root to be the portion of the filespec up to (but not including) the first file/directory name with a wildcard.

'/' and '\' are recognized as directory separators, and '*', '?', and '...' as wildcard sequences. Runs of '/' and '\' characters are reduced to single '/' characters.

   $fn = $self->normalize_name( $fn ) ;

Normalizes the filename by converting runs of '\' and '/' to '/', removing leading '/' characters, and removing a leading rev_root. Dies if the name does not begin with rev_root.

   $fn = $self->denormalize_name( $fn ) ;

Denormalizes the filename by prepending the rev_root. May do more in subclass overloads. For instance, does not prepend a '//' by default for instance, but p4 overloads do that.


DEPRECATED: use run_safely instead.

   $self->run( [@cmd_and_args], \$stdout, \$stderr ) ;

A wrapper around "run" in IPC::Run, which integrates debugging support and disables stdin by default.


Runs a command "safely", first chdiring in to the proper directory and then running it while examining STDERR through an optional filter and looking at the result codes to see if the command exited acceptably.

Most often called from VCP::Utils::foo methods.


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 vcp.


Barrie Slaymaker <>

1 POD Error

The following errors were encountered while parsing the POD:

Around line 89:

You forgot a '=back' before '=head1'