NAME

VCS::CVS - Provide a simple interface to CVS (the Concurrent Versions System).

You need to be clear in your mind about the 4 directories involved:

  • The directory where your source code resides before you import it into CVS. It is used only once - during the import phase. Call this $projectSource.

  • The directory into which you check out a read-write copy of the repository, in order to edit that copy. Call this $project. You will spend up to 100% of your time working within this directory structure.

  • The directory in which the repository resides. This is $CVSROOT. Thus $projectSource will be imported into $CVSROOT/$project.

  • The directory into which you get a read-only copy of the repository, in order to, say, make and ship that copy. Call this $someDir. It must not be $project.

Note: You cannot have a directory called CVS in your home directory. That's just asking for trouble.

SYNOPSIS

#!/usr/gnu/bin/perl -w

use integer;
use strict;

use VCS::CVS;

my($initialMsg)     = 'Initial version';
my($nullTag)		= '';
my($permissions)    = 0775;	# But not '0775'!
my($project)        = 'project';
my($projectSource)  = 'projectSource';
my($raw)            = 0;
my($readOnly)       = 0;
my($releaseTag)     = 'release_0.00';
my($vendorTag)      = 'vendorTag';
my($verbose)        = 1;
my($cvs)            = VCS::CVS -> new($project, $raw, $verbose, $permissions);

$cvs -> createRepository();
$cvs -> populate($projectSource, $vendorTag, $releaseTag, $initialMsg);
$cvs -> checkOut($readOnly, $nullTag, $project);

exit(0);

DESCRIPTION

The VCS::CVS module provides an OO interface to CVS.

VCS - Version Control System - is the prefix given to each Perl module which deals with some sort of source code control system.

I have seen CVS corrupt binary files, even when run with CVS's binary option -kb. So, since CVS doesn't support binary files, neither does VCS::CVS.

Subroutines whose names start with a '_' are not normally called by you.

Install VCS::CVS.pm in the usual fashion:

perl Makefile.PL LIB=$PERL5LIB
make
make install

This installs it into $PERL5LIB/VCS/CVS.pm.

There is a test program included, but I have not yet worked out exactly how to set it up for make test. Stay tuned.

If, like me, you don't have permission to write doc files into system directories, use:

make pure_install

instead of make install. This option is secreted in the middle of p 414 of the dromedary book.

WARNING re CVS bugs

The following are my ideas as to what constitutes a bug in CVS:

  • Binary files are corrupted, even when using the -kb option.

  • The initial revision tag, supplied when populating the repository with 'cvs import', is not saved into $CVSROOT/CVSROOT/val-tags.

  • The 'cvs tag' command does not always put the tag into 'val-tags'.

  • 'cvs checkout -dNameOfDir' fails if NameOfDir =~ /\/$/.

  • 'cvs checkout -d NameOfDir' inserts a leading space into the name of the directory it creates.

I'm using CVS V 1.9 and RCS V 5.6, but some of these bugs were found last year, perhaps with earlier versions, and have not been tested for in the current version. The 2 tag problems are still present as of 10-Jul-98.

WARNING re test environment

This code has only been tested under Unix. Sorry.

WARNING re project names 'v' directory names

I assume your copy of the repository was checked out into a directory with the same name as the project, since I do a 'cd $HOME/$project' before running 'cvs status', to see if your copy is up-to-date. This is because some activity is forbibben unless your copy is up-to-date. Typical cases of this include:

  • checkOut

  • removeDirectory

  • setTag

WARNING re shell intervention

Some commands cause the shell to become involved, which, under Unix, will read your .cshrc or whatever, which in turn may set CVSROOT to something other than what you set it to before running your script. If this happens, panic...

Actually, I think I've eliminated such cases. You hope so.

WARNING re Perl bug

As always, be aware that these 2 lines mean the same thing, sometimes:

  • $self -> {'thing'}

  • $self->{'thing'}

The problem is the spaces around the ->. Inside double quotes, "...", the first space stops the dereference taking place. Outside double quotes the scanner correctly associates the $self token with the {'thing'} token.

I regard this as a bug.

addDirectory($dir, $subDir, $message)

Add an existing directory to the project.

$dir can be a full path, or relative to the CWD.

addFile($dir, $file, $message)

Add an existing file to the project.

$dir can be a full path, or relative to the CWD.

checkOut($readOnly, $tag, $dir)

Prepare & perform 'cvs checkout'.

You call checkOut, and it calls _checkOutDontCallMe.

  • $readOnly == 0 -> Check out files as read-write.

  • $readOnly == 1 -> Check out files as read-only.

  • $tag is Null -> Do not call upToDate; ie check out repository as is.

  • $tag is not Null -> Call upToDate; Croak if repository is not up-to-date.

The value of $raw used in the call to new influences the handling of $tag:

  • $raw == 1 -> Your tag is passed as is to CVS.

  • $raw == 0 -> Your tag is assumed to be of the form release_1.23, and is converted to CVS's form release_1_23.

$dir can be a full path, or relative to the CWD.

commit($message)

Commit changes.

Called as appropriate by addFile, removeFile and removeDirectory, so you don't need to call it.

createRepository()

Create a repository, using the current $CVSROOT.

getTags()

Return a reference to a list of tags.

See also: the $raw option to new().

getTags does not take a project name because tags belong to the repository as a whole, not to a project.

new($project, $raw, $verbose, $permissions)

Create a new object. See the synopsis.

  • $raw == 0 -> Convert tags from CVS format to real format. Eg: release_1.23. Default.

  • $raw == 1 -> Return tags in raw CVS format. Eg: release_1_23.

  • $verbose == 0 -> Do not report on the progress of mkpath/rmtree. Default.

  • $verbose == 1 -> Report on the progress of mkpath/rmtree.

The default directory permissions is 0775. Do not use '0775'!

populate($sourceDir, $vendorTag, $releaseTag, $message)

Import an existing directory structure. But, (sub) import is a reserved word.

Use this to populate a repository for the first time.

The value used for $vendorTag is not important; CVS discards it.

The value used to $releaseTag is important; CVS discards it (why?) but I force it to be the first tag in $CVSROOT/CVSROOT/val-tags. Thus you should supply a meaningful value. Thus 'release_0_00' is strongly, repeat strongly, recommended.

The value of $raw used in the call to new influences the handling of $tag:

  • $raw == 1 -> Your tag is passed as is to CVS.

  • $raw == 0 -> Your tag is assumed to be of the form release_1.23, and is converted to CVS's form release_1_23.

removeDirectory($dir)

Remove a directory from the project.

This deletes the directory (and all its files) from your working copy of the repository, as well as deleting them from the repository.

Warning: $dir will have $CVSROOT and $HOME prepended by this code. Ie: $dir starts from - but excludes - your home directory (assuming, of course, you've checked out into your home directory...).

You can't remove the current directory, or a parent.

removeFile($dir, $file, $message)

Remove a file from the project.

This deletes the file from your working copy of the repository, as well as deleting it from the repository.

$dir can be a full path, or relative to the CWD. $file is relative to $dir.

runOrCroak

The standard way to run a system command and report on the result.

setTag($tag)

Tag the repository.

You call setTag, and it calls _setTag.

The value of $raw used in the call to new influences the handling of $tag:

  • $raw == 1 -> Your tag is passed as is to CVS.

  • $raw == 0 -> Your tag is assumed to be of the form release_1.23, and is converted to CVS's form release_1_23.

stripCVSDirs($dir)

Delete all CVS directories and files from a copy of the repository.

Each user directory contains a CVS sub-directory, which holds 3 files:

  • Entries

  • Repository

  • Root

Zap 'em.

status()

Run cvs status.

Return a reference to a list of lines.

Only called by upToDate(), but you may call it.

upToDate()

  • return == 0 -> Repository not up-to-date.

  • return == 1 -> Up-to-date.

_checkOutDontCallMe($readOnly, $tag, $dir)

Checkout a current copy of the project.

You call checkOut, and it calls this.

  • $readOnly == 0 -> Check out files as read-write.

  • $readOnly == 1 -> Check out files as read-only.

_fixTag($tag)

Fix a tag which CVS failed to add.

Warning: $tag must be in CVS format: release_1_23, not release_1.23.

_mkpathOrCroak($self, $dir)

There is no need for you to call this.

_readFile($file)

Return a reference to a list of lines.

There is no need for you to call this.

_setTag($tag)

Tag the current version of the project.

Warning: $tag must be in CVS format: release_1_23, not release_1.23.

You call setTag and it calls this.

_validateObject($tag, $file, $mustBeAbsent)

Validate an entry in one of the CVS files 'module' or 'val-tags'.

Warning: $tag must be in CVS format: release_1_23, not release_1.23.

AUTHOR

VCS::CVS was written by Ron Savage <rpsavage@ozemail.com.au> in 1998.

LICENCE

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.