diff options
| author | fukachan <fukachan> | 2012-02-19 10:03:46 +0000 |
|---|---|---|
| committer | fukachan <fukachan> | 2012-02-19 10:03:46 +0000 |
| commit | aecca98663bf306c745705b12cfb7d73b818ce09 (patch) | |
| tree | a70f00457deb340dda5e202478e59fb53b8b6191 | |
| parent | b092f00c1d8739a9b5a54ae775705e132b88d3df (diff) | |
| download | fml8-aecca98663bf306c745705b12cfb7d73b818ce09.tar.gz fml8-aecca98663bf306c745705b12cfb7d73b818ce09.tar.bz2 fml8-aecca98663bf306c745705b12cfb7d73b818ce09.zip | |
remove VCS-CVS, which is not used.
| -rw-r--r-- | cpan/dist/VCS-CVS/CVS.pm | 1474 | ||||
| -rw-r--r-- | cpan/dist/VCS-CVS/Changes.txt | 29 | ||||
| -rw-r--r-- | cpan/dist/VCS-CVS/MANIFEST | 8 | ||||
| -rw-r--r-- | cpan/dist/VCS-CVS/MANIFEST.SKIP | 3 | ||||
| -rw-r--r-- | cpan/dist/VCS-CVS/Makefile.PL | 29 | ||||
| -rw-r--r-- | cpan/dist/VCS-CVS/Readme.txt | 739 | ||||
| -rw-r--r-- | cpan/dist/VCS-CVS/t/base.t | 38 | ||||
| -rwxr-xr-x | cpan/dist/VCS-CVS/test.pl | 276 | ||||
| -rw-r--r-- | cpan/lib/VCS/CVS.pm | 1474 |
9 files changed, 0 insertions, 4070 deletions
diff --git a/cpan/dist/VCS-CVS/CVS.pm b/cpan/dist/VCS-CVS/CVS.pm deleted file mode 100644 index 3204e1b3..00000000 --- a/cpan/dist/VCS-CVS/CVS.pm +++ /dev/null @@ -1,1474 +0,0 @@ -package VCS::CVS; - -# Name: -# VCS::CVS. -# -# Documentation: -# POD-style documentation is at the end. Extract it with pod2html. -# -# Tabs: -# 4 spaces || die. -# -# -------------------------------------------------------------------------- - -use strict; -no strict 'refs'; - -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); - -use Carp; -use Cwd; -use File::Find; -use File::Path; - -require Exporter; - -@ISA = qw(Exporter); - -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. - -@EXPORT = qw(); - -@EXPORT_OK = qw(); - -$VERSION = '2.00'; - -# Preloaded methods go here. -# -------------------------------------------------------------------------- -# Add an existing directory to the project. -# $dir can be a full path, or relative to the CWD. - -sub addDirectory -{ - my($self, $dir, $subDir, $message) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): \nFailure: $!"); - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - # $subDir Add this directory. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'add'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - push(@args, $subDir); - - $self -> runOrCroak(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of addDirectory. - -# -------------------------------------------------------------------------- -# Add an existing file to the project. -# $dir can be a full path, or relative to the CWD. - -sub addFile -{ - my($self, $dir, $file, $message) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): \nFailure: $!"); - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - # $file Add this file. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'add'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - push(@args, $file); - - $self -> runOrCroak(@args); - - $self -> commit($message); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of addFile. - -# -------------------------------------------------------------------------- -# Prepare & perform 'cvs checkout'. -# You call checkOut, and it calls _checkOutDontCallMe. -# $readOnly Interpretation -# 0 Check out files as read-write -# 1 Check out files as read-only -# $tag Interpretation -# Null Do not call upToDate; ie check out repository as is -# ! Null Call upToDate; Croak if repository is not up-to-date -# If you called new with $raw == 1, your tag is passed as is to CVS. -# If you called new with $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. - -sub checkOut -{ - my($self, $readOnly, $tag, $dir) = @_; - - $tag =~ s/([-a-zA-Z]+_\d\d?)\.(\d\d)/$1_$2/ if (! $self -> {'raw'}); - - $self -> _validateObject($self -> {'project'}, 'modules', 0); - $self -> _validateObject($tag, 'val-tags', 0); - - croak("Failure: Move directory $dir out of the way") if (-d $dir); - - # Ensure the repository is up-to-date. - croak("Failure: The repository is not up-to-date. Run 'cvs commit' or 'cvs update'") - if ($tag && (! $self -> upToDate() ) ); - - # Zap previous copy of work directory. - rmtree($dir, $self -> {'verbose'}); - - # Checkout a current copy of the project. - $self -> _checkOutDontCallMe($readOnly, $tag, $dir); - -} # End of checkOut. - -# -------------------------------------------------------------------------- -# Commit changes. -# Called as appropriate by addFile, removeFile and removeDirectory, -# so you don't need to call it. - -sub commit -{ - my($self, $message) = @_; - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'commit'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - $self -> runOrCroak(@args); - -} # End of commit. - -# -------------------------------------------------------------------------- -# Create a repository, using the current $CVSROOT. - -sub createRepository -{ - my($self) = @_; - - croak("Failure: Move directory $ENV{'CVSROOT'} out of the way") if (-d $ENV{'CVSROOT'}); - - # Create the repository and its files. - $self -> _mkpathOrCroak($ENV{'CVSROOT'}); - $self -> _mkpathOrCroak("$ENV{'CVSROOT'}/CVSROOT"); - - # Create the modules file. - my(@args) = (); - push(@args, "CVSROOT\t\tCVSROOT"); - push(@args, "modules\t\tCVSROOT\tmodules"); - push(@args, "$self->{'project'}\t\t$self->{'project'}"); - - my($file) = "$ENV{'CVSROOT'}/CVSROOT/modules"; - open(OUT, "> $file") || croak("Can't open($file): \nFailure: $!"); - print OUT join("\n", @args), "\n"; - close(OUT); - - $file = "$ENV{'CVSROOT'}/CVSROOT/val-tags"; - open(OUT, "> $file") || croak("Can't open($file): \nFailure: $!"); - # Write nothing. - close(OUT); - - if ($self -> {'history'}) - { - $file = "$ENV{'CVSROOT'}/CVSROOT/history"; - open(OUT, "> $file") || croak("Can't open($file): \nFailure: $!"); - # Write nothing. - close(OUT); - } - -} # End of createRepository. - -# -------------------------------------------------------------------------- -# Return a reference to a list of tags. -# See also: the $raw option to new(). - -sub getTags -{ - my($self) = @_; - - my($line) = []; - - if (-e "$ENV{'CVSROOT'}/CVSROOT/val-tags") - { - $line = $self -> _readFile("$ENV{'CVSROOT'}/CVSROOT/val-tags"); - - for (@$line) - { - $_ = (split)[0]; - - # Convert tag_1_23 into tag_1.23, if requested. - s/([-a-zA-Z]+_\d\d?)_(\d\d)/$1\.$2/ if (! $self -> {'raw'}); - } - - } - - $line; - -} # End of getTags. - -# -------------------------------------------------------------------------- -# Run cvs history [-options]. -# Return a reference to a list of lines. -# -# The default option is -c. - -sub history -{ - my($self, $optionRef) = @_; - - # Preserve the caller's current working directory. - # cvs status only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir("$ENV{'HOME'}/$self->{'project'}") || - croak("Can't chdir($ENV{'HOME'}/$self->{'project'}): $!"); - - # CVS history options: - # -c Report commits, ie -xARM. - - if (ref($optionRef) ne 'HASH') - { - $optionRef = {'-c' => ''}; - } - - my(@args) = ('cvs'); - push(@args, 'history'); - push(@args, join(' ', %$optionRef) ); - @args = `@args`; - chomp(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - \@args; - -} # End of history. - -# -------------------------------------------------------------------------- -# These are the options in the anonymous hash of parameters you pass in to 'new'. -# -# 'project' -# 'killerApp' The name of the project. No default -# -# 'history' -# 0 Do not create $CVSROOT/CVSROOT/history when createRepository() is called. Default -# 1 Create $CVSROOT/CVSROOT/history, which initiates 'cvs history' stuff -# -# 'permissions' -# 0775 Unix-specific. Default. Do not use '0775' -# -# 'raw' -# 0 Convert tags from CVS format to real format. Eg: release_1.23. Default -# 1 Set/Get tags in raw CVS format. Eg: release_1_23 -# -# 'verbose' -# 0 Run quietly -# 1 Report progress. Default - -sub new -{ - my($class, $optionRef) = @_; - $class = ref($class) || $class; - my($self) = (ref($optionRef) eq 'HASH') ? $optionRef : {}; - - my(%default) = - ( - 'history' => 0, - 'permissions' => 0775, # But not '0775'! - 'project' => '', - 'raw' => 0, - 'verbose' => 1, - ); - - my($option); - - for $option (keys(%default) ) - { - $self -> {$option} = $default{$option} if (! defined($self -> {$option}) ); - } - - $ENV{'HOME'} = '' if (! defined($ENV{'HOME'}) ); - $ENV{'CVSROOT'} = '' if (! defined($ENV{'CVSROOT'}) ); - - croak("Failure: No project name specified") if (! $self -> {'project'}); - croak("Failure: Env. var HOME not set") if (! $ENV{'HOME'}); - croak("Failure: Env. var CVSROOT not set") if (! $ENV{'CVSROOT'}); - - return bless $self, $class; - -} # End of new. - -# -------------------------------------------------------------------------- -# 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. -# If you called new with $raw == 1, $releaseTag is passed as is to CVS. -# If you called new with $raw == 0, $releaseTag is assumed to be of the -# form release_1.23, and is converted to CVS's form release_1_23. - -# $sourceDir can be a full path, or relative to the CWD. - -sub populate -{ - my($self, $sourceDir, $vendorTag, $releaseTag, $message) = @_; - - $vendorTag = 'vendorTag' if ( ($#_ < 2) || (length($_[2]) == 0) ); - $releaseTag = 'release_0_00' if ( ($#_ < 3) || (length($_[3]) == 0) ); - $message = 'Initial version' if ($#_ < 4); - - $releaseTag =~ s/([-a-zA-Z]+_\d\d?)\.(\d\d)/$1_$2/ if (! $self -> {'raw'}); - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($sourceDir) || croak("Can't chdir($sourceDir): \nFailure: $!"); - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'import'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - push(@args, $self -> {'project'}, $vendorTag, $releaseTag); - - $self -> runOrCroak(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - # Compensate for yet another CVS bug. - $self -> _fixTag($releaseTag); - -} # End of populate. - -# -------------------------------------------------------------------------- -# 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 thereof. - -sub removeDirectory -{ - my($self, $dir) = @_; - - my($cvsDir) = "$ENV{'CVSROOT'}/$dir/"; - my($workDir) = "$ENV{'HOME'}/$dir/"; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - - # Move into the work directory. - chdir($workDir) || croak("Can't chdir($workDir): \nFailure: $!"); - my($thisCwd) = cwd(); - - # Sanity check. - croak("Failure: You can't remove the current directory, or a parent") if ($cwd =~ /^$thisCwd/); - - # Ensure the repository is up-to-date. - croak("Failure: The repository is not up-to-date. Run 'cvs commit' or 'cvs update'") - if (! $self -> upToDate() ); - - # Read the CVS entries. - my($cvsEntries) = 'CVS/Entries'; - my($entry) = $self -> _readFile($cvsEntries); - - # Remove each file, using CVS. - for (@$entry) - { - next if (/^D/); - - my($file); - - $file = $1 if (/^\/(.+?)\//); - - $self -> removeFile($workDir, $file, 'Whole directory removed'); - } - - $self -> commit('Whole directory removed'); - - # Move up, and remove the directory. - chdir('..') || croak("Can't chdir('..'): \nFailure: $!"); - my($directory) = $workDir; - my($index) = rindex($directory, '/', (length($directory) - 2) ); - substr($directory, 0, ($index + 1) ) = ''; - rmtree($directory, $self -> {'verbose'}); - - # Edit the CVS entries file to remove the dir. - if (-f $cvsEntries) - { - $entry = $self -> _readFile($cvsEntries); - @$entry = grep(! /^D\/$directory\//, @$entry); - open(OUT, "> $cvsEntries") || croak("Can't open $cvsEntries: \nFailure: $!"); - print OUT join("\n", @$entry), "\n"; - close(OUT); - } - - # Remove the directory from CVS. - rmtree($cvsDir, $self -> {'verbose'}); - - # Remove the directory from the modules list. - if ($dir !~ /\//) - { - $cvsEntries = "$ENV{'CVSROOT'}/CVSROOT/modules"; - $entry = $self -> _readFile($cvsEntries); - - my($i); - - for ($i = 0; $i <= $#{$entry}; $i++) - { - my(@field) = split(/\s+/, $$entry[$i]); - splice(@$entry, $i, 1) if ($field[1] =~ /^$dir$/); - } - - open(OUT, "> $cvsEntries") || croak("Can't open $cvsEntries: \nFailure: $!"); - print OUT join("\n", @$entry), "\n"; - close(OUT); - } - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of removeDirectory. - -# -------------------------------------------------------------------------- -# 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. - -sub removeFile -{ - my($self, $dir, $file, $message) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): \nFailure: $!"); - - unlink($file) || croak("Can't unlink($file): $!"); - - # CVS options: - # -Q Really quiet. - # -f Remove the file first. - # -l Do not recurse. - # $file Checkout this module. - - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'remove', '-f', '-l', $file); - - $self -> runOrCroak(@args); - - $self -> commit($message); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of removeFile. - -# -------------------------------------------------------------------------- -# The standard way to run a system command and report on the result. - -sub runOrCroak -{ - my($self, @args) = @_; - - my($result) = 0xffff & system(@args); - - print "Command: @args\n"; - - if ($result == 0) - { - print 'Success. '; - } - elsif ($result == 0xff00) - { - print "Failure: $!. "; - } - elsif ($result > 0x80) - { - $result >>= 8; - print "Exit status: $result. "; - } - else - { - if ($result & 0x80) - { - $result &= ~0x80; - print 'Coredump from '; - } - - print "Signal $result. "; - } - - printf("Result: %#04x\n", $result); - - croak("Failure: Can't run '@args'") if ($result); - -} # End of runOrCroak. - -# -------------------------------------------------------------------------- -# Tag the repository. -# You call setTag, and it calls _setTag. -# If you called new with $raw == 1, your tag is passed as is to CVS. -# If you called new with $raw == 0, your tag is assumed to be of the -# form release_1.23, and is converted to CVS's form release_1_23. - -sub setTag -{ - my($self, $tag) = @_; - - $tag =~ s/([-a-zA-Z]+_\d\d?)\.(\d\d)/$1_$2/ if (! $self -> {'raw'}); - - $self -> _validateObject($self -> {'project'}, 'modules', 0); - $self -> _validateObject($tag, 'val-tags', 1); - - croak("Failure: The repository is not up-to-date. Run 'cvs commit' or 'cvs update'") - if ($self -> upToDate() == 0); - - $self -> _setTag($tag); - -} # End of setTag. - -# -------------------------------------------------------------------------- -# Run cvs status. -# Return a reference to a list of lines. -# Only called by upToDate(), but you may call it. - -sub status -{ - my($self) = @_; - - # Preserve the caller's current working directory. - # cvs status only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir("$ENV{'HOME'}/$self->{'project'}") || - croak("Can't chdir($ENV{'HOME'}/$self->{'project'}): $!"); - - # CVS options: - # -Q Really quiet. - - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'status'); - @args = `@args`; - chomp(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - \@args; - -} # End of status. - -# -------------------------------------------------------------------------- -# Delete all CVS directories and files from a copy of the repository. - -sub stripCVSDirs -{ - my($self, $dir) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): $!"); - - my(%dirStack); - - find - ( - sub - { - $dirStack{$File::Find::dir} = 1 if ($File::Find::dir =~ /\/CVS$/); - }, - cwd() - ); - - for (keys(%dirStack) ) - { - rmtree($_, $self -> {'verbose'}); - } - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of stripCVSDirs. - -# -------------------------------------------------------------------------- -# Run cvs -q [-n] update. -# Return a reference to a list of lines. -# Each line will start with one of [UARMC?], as per the CVS docs. -# -# Parameters Interpretation -# $n 0 -> Do not add -n to the cvs update command -# 1 -> Add -n to the command - -sub update -{ - my($self, $n) = @_; - - $n = 0 if (! defined($n) ); - - # Preserve the caller's current working directory. - # cvs status only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir("$ENV{'HOME'}/$self->{'project'}") || - croak("Can't chdir($ENV{'HOME'}/$self->{'project'}): $!"); - - # CVS options: - # -q Quiet - # -n Do not change any files - - my(@args) = ('cvs'); - push(@args, '-q') if (! $self -> {'verbose'}); - push(@args, '-n') if ($n); - push(@args, 'update'); - @args = `@args`; - chomp(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - \@args; - -} # End of update. - -# -------------------------------------------------------------------------- -# Return Interpretation -# 0 Repository not up-to-date. -# 1 Up-to-date. - -sub upToDate -{ - my($self) = @_; - - # Get the status of the repository. - my($status) = $self -> status(); - @$status = grep(/Status/ && ! /Up-to-date/, @$status); - my($result) = 1; # Up-to-date. - $result = 0 if ($#{$status} >= 0); # Not, because log contains something. - - $result; - -} # End of upToDate. - -# -------------------------------------------------------------------------- -# Checkout a current copy of the project. -# You call checkOut, and it calls this. - -sub _checkOutDontCallMe -{ - my($self, $readOnly, $tag, $dir) = @_; - - # CVS options: - # -Q Really quiet. - # -r Read-only. Make the new working files read-only. - # -d$dir Use $dir, not $project, as the directory name. - # -r <tag> Check out files tagged with <tag>. Optional. - # - # $project Checkout this module. - - # CVS bug. Remove trailing '/', if any. - $dir = $1 if ($dir =~ /^(.+)\/$/); - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, '-r') if ($readOnly); - push(@args, 'checkout', '-A', '-P', "-d$dir"); - push(@args, '-r', $tag) if ($tag); - push(@args, $self -> {'project'}); - - $self -> runOrCroak(@args); - -} # End of _checkOutDontCallMe. - -# -------------------------------------------------------------------------- -# Fix a tag CVS failed to add. -# Warning: $tag must be in CVS format. Eg: release_1_23, not release_1.23. - -sub _fixTag -{ - my($self, $tag) = @_; - - my($file) = "$ENV{'CVSROOT'}/CVSROOT/val-tags"; - - open(INX, $file) || croak("Can't open($file): \nFailure: $!"); - - my($found) = 0; - - while (<INX>) - { - $found = 1 if (/^$tag/); - } - - close(INX); - - if (! $found) - { - print "Warning: CVS bug. Tag $tag not in file $file\n" if ($self -> {'verbose'}); - print "Fixing... " if ($self -> {'verbose'}); - - open(OUT, ">> $file") || croak("Can't open(>>$file): \nFailure: $!"); - print OUT "$tag y\n"; - close(OUT); - - print "Success\n" if ($self -> {'verbose'}); - } - -} # End of _fixTag. - -# -------------------------------------------------------------------------- - -sub _mkpathOrCroak -{ - my($self, $dir) = @_; - - my($result) = mkpath($dir, $self -> {'verbose'}, $self -> {'permissions'}); - - croak("Can't mkpath($dir, $self->{'verbose'}, $self->{'permissions'}): \nFailure: $!") - if ( (! $result) && ($! !~ /No such file/) ); - -} # End of _mkpathOrCroak. - -# -------------------------------------------------------------------------- -# Return a reference to a list of lines. - -sub _readFile -{ - my($self, $file) = @_; - - open(INX, $file) || croak("Can't open($file): $!"); - my(@line) = <INX>; - close(INX); - chomp(@line); - - \@line; - -} # end of _readFile. - -# -------------------------------------------------------------------------- -# Tag the current version of the project. -# Warning: $tag must be in CVS format. Eg: release_1_23, not release_1.23. -# You call setTag and it calls this. - -sub _setTag -{ - my($self, $tag) = @_; - - # Preserve the caller's current working directory. - # cvs tag only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir($ENV{'HOME'}) || croak("Can't chdir($ENV{'HOME'}): $!"); - - # CVS options: - # -Q Really quiet. - # -r <tag> Tag files with <tag>. - # $project Tag this module. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'tag', $tag, $self -> {'project'}); - - $self -> runOrCroak(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - # Compensate for yet another CVS bug. - $self -> _fixTag($tag); - -} # End of _setTag. - -# -------------------------------------------------------------------------- -# Validate an entry in one of the CVS files 'module' or 'val-tags'. -# Warning: $tag must be in CVS format. Eg: release_1_23, not release_1.23. - -sub _validateObject -{ - my($self, $tag, $file, $mustBeAbsent) = @_; - - $file = "$ENV{'CVSROOT'}/CVSROOT/$file"; - - open(INX, $file) || croak("Can't open($file): \nFailure: $!"); - - my($found) = 0; - - while (<INX>) - { - $found = 1 if (/^$tag/); - } - - close(INX); - - croak("Failure: Tag not found: $tag in file $file") - if ( (! $found) && (! $mustBeAbsent) ); - - croak("Failure: Tag already present: $tag in file $file") - if ($found && $mustBeAbsent); - -} # End of _validateObject. - -# -------------------------------------------------------------------------- - -# Autoload methods go after =cut, and are processed by the autosplit program. - -1; - -__END__ - -=head1 NAME - -C<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: - -=over 4 - -=item * - -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. - -=item * - -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. - -=item * - -The directory in which the repository resides. This is $CVSROOT. Thus -$projectSource will be imported into $CVSROOT/$project. - -=item * - -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. - -=back - -Note: You cannot have a directory called CVS in your home directory. That's -just asking for trouble. - -=head1 SYNOPSIS - - #!/usr/gnu/bin/perl -w - - use integer; - use strict; - - use VCS::CVS; - - my($history) = 1; - my($initialMsg) = 'Initial version'; - my($noChange) = 1; - 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; - - # Note the anonymous hash in the next line, new as of V 1.10. - - my($cvs) = VCS::CVS -> new({ - 'project' => $project, - 'raw' => $raw, - 'verbose' => $verbose, - 'permissions' => $permissions, - 'history' => $history}); - - $cvs -> createRepository(); - $cvs -> populate($projectSource, $vendorTag, $releaseTag, $initialMsg); - $cvs -> checkOut($readOnly, $nullTag, $project); - - print join("\n", @{$cvs -> update($noChange)}); - print "\n"; - print join("\n", @{$cvs -> history()}); - - exit(0); - -=head1 DESCRIPTION - -The C<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. - -Stop press: CVS V 1.10 (with RCS 5.7) supports binary files. - -Subroutines whose names start with a '_' are not normally called by you. - -There is a test program included, but I have not yet worked out exactly how to -set it up for make test. Stay tuned. - -=head1 INSTALLATION - -You install C<VCS::CVS>, as you would install any perl module library, -by running these commands: - - perl Makefile.PL - make - make test - make install - -If you want to install a private copy of C<VCS::CVS> in your home -directory, then you should try to produce the initial Makefile with -something like this command: - - perl Makefile.PL LIB=~/perl - or - perl Makefile.PL LIB=C:/Perl/Site/Lib - -If, like me, you don't have permission to write man pages into unix system -directories, use: - - make pure_install - -instead of make install. This option is secreted in the middle of p 414 of the -second edition of the dromedary book. - -=head1 WARNING re CVS bugs - -The following are my ideas as to what constitutes a bug in CVS: - -=over 4 - -=item * - -The initial revision tag, supplied when populating the repository with -'cvs import', is not saved into $CVSROOT/CVSROOT/val-tags. - -=item * - -The 'cvs tag' command does not always put the tag into 'val-tags'. - -=item * - -C<'cvs checkout -dNameOfDir'> fails if NameOfDir =~ /\/$/. - -=item * - -C<'cvs checkout -d NameOfDir'> inserts a leading space into the name of -the directory it creates. - -=back - -=head1 WARNING re test environment - -This code has only been tested under Unix. Sorry. - -=head1 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: - -=over 4 - -=item * - -C<checkOut> - -=item * - -C<removeDirectory> - -=item * - -C<setTag> - -=back - -=head1 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. - -=head1 WARNING re Perl bug - -As always, be aware that these 2 lines mean the same thing, sometimes: - -=over 4 - -=item * - -$self -> {'thing'} - -=item * - -$self->{'thing'} - -=back - -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. - -=head1 addDirectory($dir, $subDir, $message) - -Add an existing directory to the project. - -$dir can be a full path, or relative to the CWD. - -=head1 addFile($dir, $file, $message) - -Add an existing file to the project. - -$dir can be a full path, or relative to the CWD. - -=head1 checkOut($readOnly, $tag, $dir) - -Prepare & perform 'cvs checkout'. - -You call checkOut, and it calls _checkOutDontCallMe. - -=over 4 - -=item * - -$readOnly == 0 -> Check out files as read-write. - -=item * - -$readOnly == 1 -> Check out files as read-only. - -=back - -=over 4 - -=item * - -$tag is Null -> Do not call upToDate; ie check out repository as is. - -=item * - -$tag is not Null -> Call upToDate; Croak if repository is not up-to-date. - -=back - -The value of $raw used in the call to new influences the handling of $tag: - -=over 4 - -=item * - -$raw == 1 -> Your tag is passed as is to CVS. - -=item * - -$raw == 0 -> Your tag is assumed to be of the form release_1.23, and is -converted to CVS's form release_1_23. - -=back - -$dir can be a full path, or relative to the CWD. - -=head1 commit($message) - -Commit changes. - -Called as appropriate by addFile, removeFile and removeDirectory, -so you don't need to call it. - -=head1 createRepository() - -Create a repository, using the current $CVSROOT. - -This involves creating these files: - -=over 4 - -=item * - -$ENV{'CVSROOT'}/CVSROOT/modules - -=item * - -$ENV{'CVSROOT'}/CVSROOT/val-tags - -=item * - -$ENV{'CVSROOT'}/CVSROOT/history - -=back - -Notes: - -=over 4 - -=item * - -The 'modules' file contains these lines: - - CVSROOT CVSROOT - modules CVSROOT modules - $self -> {'project'} $self -> {'project'} - -where $self -> {'project'} comes from the 'project' parameter to new() - -=item * - -The 'val-tags' file is initially empty - -=item * - -The 'history' file is only created if the 'history' parameter to new() is set. -The file is initially empty - -=back - -=head1 getTags() - -Return a reference to a list of tags. - -See also: the $raw option to new(). - -C<getTags> does not take a project name because tags belong to the repository -as a whole, not to a project. - -=head1 history({}) - -Report details from the history log, $CVSROOT/CVSROOT/history. - -You must have used new({'history' => 1}), or some other mechanism, to create -the history file, before CVS starts logging changes into the history file. - -The anonymous hash takes any parameters 'cvs history' takes, and joins them -with a single space. Eg: - - $cvs -> history(); - - $cvs -> history({'-e' => ''}); - - $cvs -> history({'-xARM' => ''}); - - $cvs -> history({'-u' => $ENV{'LOGNAME'}, '-x' => 'A'}); - -but not - - $cvs -> history({'-xA' => 'M'}); - -because it doesn't work. - -=head1 new({}) - -Create a new object. See the synopsis. - -The anonymous hash takes these parameters, of which 'project' is the -only required one. - -=over 4 - -=item * - -'project' => 'killerApp'. The required name of the project. No default - -=back - -=over 4 - -=item * - -'permissions' => 0775. Unix-specific stuff. Default. Do not use '0775'. - -=back - -=over 4 - -=item * - -'history' => 0. Do not create $CVSROOT/CVSROOT/history when createRepository() is called. Default - -=item * - -'history' => 1. Create $CVSROOT/CVSROOT/history, which initiates 'cvs history' stuff - -=back - -=over 4 - -=item * - -'raw' => 0. Convert tags from CVS format to real format. Eg: release_1.23. Default. - -=item * - -'raw' => 1. Return tags in raw CVS format. Eg: release_1_23. - -=back - -=over 4 - -=item * - -'verbose' => 0. Do not report on the progress of mkpath/rmtree - -=item * - -'verbose' => 1. Report on the progress of mkpath/rmtree. Default - -=back - -=head1 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: - -=over 4 - -=item * - -$raw == 1 -> Your tag is passed as is to CVS. - -=item * - -$raw == 0 -> Your tag is assumed to be of the form release_1.23, and is -converted to CVS's form release_1_23. - -=back - -=head1 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. - -=head1 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. - -=head1 runOrCroak() - -The standard way to run a system command and report on the result. - -=head1 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: - -=over 4 - -=item * - -$raw == 1 -> Your tag is passed as is to CVS. - -=item * - -$raw == 0 -> Your tag is assumed to be of the form release_1.23, and is -converted to CVS's form release_1_23. - -=back - -=head1 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: - -=over 4 - -=item * - -Entries - -=item * - -Repository - -=item * - -Root - -=back - -Zap 'em. - -=head1 status() - -Run cvs status. - -Return a reference to a list of lines. - -Only called by upToDate(), but you may call it. - -=head1 update($noChange) - -Run 'cvs C<-q> [C<-n>] update', returning a reference to a list of lines. -Each line will start with one of [UARMC?], as per the CVS docs. - -$cvs -> update(1) is a good way to get a list of uncommited changes, etc. - -=over 4 - -=item * - -$noChange == 0 -> Do not add C<-n> to the cvs command. Ie update your working copy - -=item * - -$noChange == 1 -> Add C<-n> to the cvs command. Do not change any files - -=back - -=head1 upToDate() - -=over 4 - -=item * - -return == 0 -> Repository not up-to-date. - -=item * - -return == 1 -> Up-to-date. - -=back - -=head1 _checkOutDontCallMe($readOnly, $tag, $dir) - -Checkout a current copy of the project. - -You call checkOut, and it calls this. - -=over 4 - -=item * - -$readOnly == 0 -> Check out files as read-write. - -=item * - -$readOnly == 1 -> Check out files as read-only. - -=back - -=head1 _fixTag($tag) - -Fix a tag which CVS failed to add. - -Warning: $tag must be in CVS format: release_1_23, not release_1.23. - -=head1 _mkpathOrCroak($self, $dir) - -There is no need for you to call this. - -=head1 _readFile($file) - -Return a reference to a list of lines. - -There is no need for you to call this. - -=head1 _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. - -=head1 _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. - -=head1 AUTHOR - -C<VCS::CVS> was written by Ron Savage I<E<lt>rpsavage@ozemail.com.auE<gt>> in 1998. - -=head1 LICENCE - -This program is free software; you can redistribute it and/or modify it under -the same terms as Perl itself. diff --git a/cpan/dist/VCS-CVS/Changes.txt b/cpan/dist/VCS-CVS/Changes.txt deleted file mode 100644 index 1ac65c5c..00000000 --- a/cpan/dist/VCS-CVS/Changes.txt +++ /dev/null @@ -1,29 +0,0 @@ -Revision history for Perl extension VCS::CVS.
-
-2.00 17-Jun-99
---------------
-o Change parameters to new(). It now accepts an anonymous hash
-o Add history parameter to new()
-o Add history(). It accepts an anonymous hash of 'cvs history' parameters,
- and returns a ref to a list
-o Add update(). It accepts an optional boolean to active the -n in
- 'cvs update -n', and returns a ref to a list
-o Fix 2 bugs whereby chdir() was called at the wrong time
-
-1.04 26-May-99
---------------
-o Ensure POD survives buggy pod2man
-o Ship Readme.txt, the output of pod2text
-
-1.03 19-Apr-99
---------------
-o Patch Makefile.PL to support ActivePerl's ppm.
-
-1.02 30-Mar-99
---------------
-o Original version; created by h2xs 1.18
-
-Use h2xs to create the skeleton for CVS.pm.
-
-Fix populate & _setTag so they do a chdir
-back before calling _fixTag.
diff --git a/cpan/dist/VCS-CVS/MANIFEST b/cpan/dist/VCS-CVS/MANIFEST deleted file mode 100644 index 1aeb7df0..00000000 --- a/cpan/dist/VCS-CVS/MANIFEST +++ /dev/null @@ -1,8 +0,0 @@ -Changes.txt -CVS.pm -MANIFEST -MANIFEST.SKIP -Makefile.PL -Readme.txt -test.pl -t/base.t diff --git a/cpan/dist/VCS-CVS/MANIFEST.SKIP b/cpan/dist/VCS-CVS/MANIFEST.SKIP deleted file mode 100644 index 06c7fa7b..00000000 --- a/cpan/dist/VCS-CVS/MANIFEST.SKIP +++ /dev/null @@ -1,3 +0,0 @@ -Makefile$ -^blib -^pm_to_blib diff --git a/cpan/dist/VCS-CVS/Makefile.PL b/cpan/dist/VCS-CVS/Makefile.PL deleted file mode 100644 index 87b9d0b2..00000000 --- a/cpan/dist/VCS-CVS/Makefile.PL +++ /dev/null @@ -1,29 +0,0 @@ -use ExtUtils::MakeMaker; -# See lib/ExtUtils/MakeMaker.pm for details of how to influence -# the contents of the Makefile that is written. - -WriteMakefile -( - ($] ge '5.005') ? - ( - 'AUTHOR' => 'Ron Savage (rpsavage@ozemail.com.au)', - 'ABSTRACT' => "Interface to GNU's CVS", - ) : (), -'clean' => - { - 'FILES' => 'blib/* Makefile VCS-CVS-*' - }, -'dist' => - { - 'COMPRESS' => 'gzip', - 'SUFFIX' => 'gz' - }, -'DISTNAME' => 'VCS-CVS', -'NAME' => 'VCS::CVS', -'PM' => - { - 'CVS.pm' => '$(INST_LIBDIR)/CVS.pm', - }, -'PREREQ_PM' => {}, -'VERSION_FROM' => 'CVS.pm' -); diff --git a/cpan/dist/VCS-CVS/Readme.txt b/cpan/dist/VCS-CVS/Readme.txt deleted file mode 100644 index 6ac40487..00000000 --- a/cpan/dist/VCS-CVS/Readme.txt +++ /dev/null @@ -1,739 +0,0 @@ -.rn '' }` -''' $RCSfile$$Revision$$Date$ -''' -''' $Log$ -''' -.de Sh -.br -.if t .Sp -.ne 5 -.PP -\fB\\$1\fR -.PP -.. -.de Sp -.if t .sp .5v -.if n .sp -.. -.de Ip -.br -.ie \\n(.$>=3 .ne \\$3 -.el .ne 3 -.IP "\\$1" \\$2 -.. -.de Vb -.ft CW -.nf -.ne \\$1 -.. -.de Ve -.ft R - -.fi -.. -''' -''' -''' Set up \*(-- to give an unbreakable dash; -''' string Tr holds user defined translation string. -''' Bell System Logo is used as a dummy character. -''' -.tr \(*W-|\(bv\*(Tr -.ie n \{\ -.ds -- \(*W- -.ds PI pi -.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -.ds L" "" -.ds R" "" -''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of -''' \*(L" and \*(R", except that they are used on ".xx" lines, -''' such as .IP and .SH, which do another additional levels of -''' double-quote interpretation -.ds M" """ -.ds S" """ -.ds N" """"" -.ds T" """"" -.ds L' ' -.ds R' ' -.ds M' ' -.ds S' ' -.ds N' ' -.ds T' ' -'br\} -.el\{\ -.ds -- \(em\| -.tr \*(Tr -.ds L" `` -.ds R" '' -.ds M" `` -.ds S" '' -.ds N" `` -.ds T" '' -.ds L' ` -.ds R' ' -.ds M' ` -.ds S' ' -.ds N' ` -.ds T' ' -.ds PI \(*p -'br\} -.\" If the F register is turned on, we'll generate -.\" index entries out stderr for the following things: -.\" TH Title -.\" SH Header -.\" Sh Subsection -.\" Ip Item -.\" X<> Xref (embedded -.\" Of course, you have to process the output yourself -.\" in some meaninful fashion. -.if \nF \{ -.de IX -.tm Index:\\$1\t\\n%\t"\\$2" -.. -.nr % 0 -.rr F -.\} -.TH CVS 3 "perl 5.005, patch 02" "17/Jun/99" "User Contributed Perl Documentation" -.UC -.if n .hy 0 -.if n .na -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.de CQ \" put $1 in typewriter font -.ft CW -'if n "\c -'if t \\&\\$1\c -'if n \\&\\$1\c -'if n \&" -\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 -'.ft R -.. -.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 -. \" AM - accent mark definitions -.bd B 3 -. \" fudge factors for nroff and troff -.if n \{\ -. ds #H 0 -. ds #V .8m -. ds #F .3m -. ds #[ \f1 -. ds #] \fP -.\} -.if t \{\ -. ds #H ((1u-(\\\\n(.fu%2u))*.13m) -. ds #V .6m -. ds #F 0 -. ds #[ \& -. ds #] \& -.\} -. \" simple accents for nroff and troff -.if n \{\ -. ds ' \& -. ds ` \& -. ds ^ \& -. ds , \& -. ds ~ ~ -. ds ? ? -. ds ! ! -. ds / -. ds q -.\} -.if t \{\ -. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" -. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' -. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' -. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' -. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' -. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' -. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' -. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' -. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' -.\} -. \" troff and (daisy-wheel) nroff accents -.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' -.ds 8 \h'\*(#H'\(*b\h'-\*(#H' -.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] -.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' -.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' -.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] -.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] -.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' -.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' -.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] -.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] -.ds ae a\h'-(\w'a'u*4/10)'e -.ds Ae A\h'-(\w'A'u*4/10)'E -.ds oe o\h'-(\w'o'u*4/10)'e -.ds Oe O\h'-(\w'O'u*4/10)'E -. \" corrections for vroff -.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' -.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' -. \" for low resolution devices (crt and lpr) -.if \n(.H>23 .if \n(.V>19 \ -\{\ -. ds : e -. ds 8 ss -. ds v \h'-1'\o'\(aa\(ga' -. ds _ \h'-1'^ -. ds . \h'-1'. -. ds 3 3 -. ds o a -. ds d- d\h'-1'\(ga -. ds D- D\h'-1'\(hy -. ds th \o'bp' -. ds Th \o'LP' -. ds ae ae -. ds Ae AE -. ds oe oe -. ds Oe OE -.\} -.rm #[ #] #H #V #F C -.SH "NAME" -\f(CWVCS::CVS\fR \- Provide a simple interface to CVS (the Concurrent Versions System). -.PP -You need to be clear in your mind about the 4 directories involved: -.Ip "\(bu" 4 -The directory where your source code resides before you import it into \s-1CVS\s0. -It is used only once \- during the import phase. Call this \f(CW$projectSource\fR. -.Ip "\(bu" 4 -The directory into which you check out a read-write copy of the repository, -in order to edit that copy. Call this \f(CW$project\fR. You will spend up to 100% of -your time working within this directory structure. -.Ip "\(bu" 4 -The directory in which the repository resides. This is \f(CW$CVSROOT\fR. Thus -\f(CW$projectSource\fR will be imported into \f(CW$CVSROOT\fR/$project. -.Ip "\(bu" 4 -The directory into which you get a read-only copy of the repository, in order to, -say, make and ship that copy. Call this \f(CW$someDir\fR. It must not be \f(CW$project\fR. -.PP -Note: You cannot have a directory called \s-1CVS\s0 in your home directory. That's -just asking for trouble. -.SH "SYNOPSIS" -.PP -.Vb 1 -\& #!/usr/gnu/bin/perl -w -.Ve -.Vb 2 -\& use integer; -\& use strict; -.Ve -.Vb 1 -\& use VCS::CVS; -.Ve -.Vb 12 -\& my($history) = 1; -\& my($initialMsg) = 'Initial version'; -\& my($noChange) = 1; -\& 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; -.Ve -.Vb 1 -\& # Note the anonymous hash in the next line, new as of V 1.10. -.Ve -.Vb 6 -\& my($cvs) = VCS::CVS -> new({ -\& 'project' => $project, -\& 'raw' => $raw, -\& 'verbose' => $verbose, -\& 'permissions' => $permissions, -\& 'history' => $history}); -.Ve -.Vb 3 -\& $cvs -> createRepository(); -\& $cvs -> populate($projectSource, $vendorTag, $releaseTag, $initialMsg); -\& $cvs -> checkOut($readOnly, $nullTag, $project); -.Ve -.Vb 3 -\& print join("\en", @{$cvs -> update($noChange)}); -\& print "\en"; -\& print join("\en", @{$cvs -> history()}); -.Ve -.Vb 1 -\& exit(0); -.Ve -.SH "DESCRIPTION" -The \f(CWVCS::CVS\fR module provides an OO interface to CVS. -.PP -VCS \- Version Control System \- is the prefix given to each Perl module which -deals with some sort of source code control system. -.PP -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. -.PP -Stop press: CVS V 1.10 (with RCS 5.7) supports binary files. -.PP -Subroutines whose names start with a \*(L'_\*(R' are not normally called by you. -.PP -There is a test program included, but I have not yet worked out exactly how to -set it up for make test. Stay tuned. -.SH "INSTALLATION" -You install \f(CWVCS::CVS\fR, as you would install any perl module library, -by running these commands: -.PP -.Vb 4 -\& perl Makefile.PL -\& make -\& make test -\& make install -.Ve -If you want to install a private copy of \f(CWVCS::CVS\fR in your home -directory, then you should try to produce the initial Makefile with -something like this command: -.PP -.Vb 3 -\& perl Makefile.PL LIB=~/perl -\& or -\& perl Makefile.PL LIB=C:/Perl/Site/Lib -.Ve -If, like me, you don't have permission to write man pages into unix system -directories, use: -.PP -.Vb 1 -\& make pure_install -.Ve -instead of make install. This option is secreted in the middle of p 414 of the -second edition of the dromedary book. -.SH "WARNING re CVS bugs" -The following are my ideas as to what constitutes a bug in CVS: -.Ip "\(bu" 4 -The initial revision tag, supplied when populating the repository with -\&'cvs import\*(R', is not saved into \f(CW$CVSROOT\fR/\s-1CVSROOT/\s0val-tags. -.Ip "\(bu" 4 -The \*(L'cvs tag\*(R' command does not always put the tag into \*(L'val-tags\*(R'. -.Ip "\(bu" 4 -\&\f(CW'cvs checkout -dNameOfDir'\fR fails if NameOfDir =~ /\e/$/. -.Ip "\(bu" 4 -\&\f(CW'cvs checkout -d NameOfDir'\fR inserts a leading space into the name of -the directory it creates. -.SH "WARNING re test environment" -This code has only been tested under Unix. Sorry. -.SH "WARNING re project names \*(M'v\*(S' 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 \*(L'cd \f(CW$HOME\fR/$project\*(R' before running -\&'cvs status\*(R', 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: -.Ip "\(bu" 4 -\f(CWcheckOut\fR -.Ip "\(bu" 4 -\f(CWremoveDirectory\fR -.Ip "\(bu" 4 -\f(CWsetTag\fR -.SH "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... -.PP -Actually, I think I've eliminated such cases. You hope so. -.SH "WARNING re Perl bug" -As always, be aware that these 2 lines mean the same thing, sometimes: -.Ip "\(bu" 4 -$self \-> {'thing'} -.Ip "\(bu" 4 -$self->{'thing'} -.PP -The problem is the spaces around the \->. Inside double quotes, \*(L"...\*(R", the -first space stops the dereference taking place. Outside double quotes the -scanner correctly associates the \f(CW$self\fR token with the {'thing'} token. -.PP -I regard this as a bug. -.SH "\fIaddDirectory\fR\|($dir, \f(CW$subDir\fR, \f(CW$message\fR)" -Add an existing directory to the project. -.PP -$dir can be a full path, or relative to the CWD. -.SH "\fIaddFile\fR\|($dir, \f(CW$file\fR, \f(CW$message\fR)" -Add an existing file to the project. -.PP -$dir can be a full path, or relative to the CWD. -.SH "\fIcheckOut\fR\|($readOnly, \f(CW$tag\fR, \f(CW$dir\fR)" -Prepare & perform \*(L'cvs checkout\*(R'. -.PP -You call checkOut, and it calls _checkOutDontCallMe. -.Ip "\(bu" 4 -$readOnly == 0 \-> Check out files as read-write. -.Ip "\(bu" 4 -$readOnly == 1 \-> Check out files as read-only. -.Ip "\(bu" 4 -$tag is Null \-> Do not call upToDate; ie check out repository as is. -.Ip "\(bu" 4 -$tag is not Null \-> Call upToDate; Croak if repository is not up-to-date. -.PP -The value of \f(CW$raw\fR used in the call to new influences the handling of \f(CW$tag:\fR -.Ip "\(bu" 4 -$raw == 1 \-> Your tag is passed as is to \s-1CVS\s0. -.Ip "\(bu" 4 -$raw == 0 \-> Your tag is assumed to be of the form release_1.23, and is -converted to \s-1CVS\s0's form release_1_23. -.PP -$dir can be a full path, or relative to the \s-1CWD\s0. -.SH "\fIcommit\fR\|($message)" -Commit changes. -.PP -Called as appropriate by addFile, removeFile and removeDirectory, -so you don't need to call it. -.SH "\fIcreateRepository()\fR" -Create a repository, using the current \f(CW$CVSROOT\fR. -.PP -This involves creating these files: -.Ip "\(bu" 4 -$\s-1ENV\s0{'\s-1CVSROOT\s0'}/\s-1CVSROOT/\s0modules -.Ip "\(bu" 4 -$\s-1ENV\s0{'\s-1CVSROOT\s0'}/\s-1CVSROOT/\s0val-tags -.Ip "\(bu" 4 -$\s-1ENV\s0{'\s-1CVSROOT\s0'}/\s-1CVSROOT/\s0history -.PP -Notes: -.Ip "\(bu" 4 -The \*(L'modules\*(R' file contains these lines: -.Sp -.Vb 3 -\& CVSROOT CVSROOT -\& modules CVSROOT modules -\& $self -> {'project'} $self -> {'project'} -.Ve -where \f(CW$self\fR \-> {'project'} comes from the \*(L'project\*(R' parameter to \fInew()\fR -.Ip "\(bu" 4 -The \*(L'val-tags\*(R' file is initially empty -.Ip "\(bu" 4 -The \*(L'history\*(R' file is only created if the \*(L'history\*(R' parameter to \fInew()\fR is set. -The file is initially empty -.SH "\fIgetTags()\fR" -Return a reference to a list of tags. -.PP -See also: the \f(CW$raw\fR option to \fInew()\fR. -.PP -\f(CWgetTags\fR does not take a project name because tags belong to the repository -as a whole, not to a project. -.SH "\fIhistory\fR\|({})" -Report details from the history log, \f(CW$CVSROOT\fR/CVSROOT/history. -.PP -You must have used \fInew\fR\|({'history\*(R' => 1}), or some other mechanism, to create -the history file, before CVS starts logging changes into the history file. -.PP -The anonymous hash takes any parameters \*(L'cvs history\*(R' takes, and joins them -with a single space. Eg: -.PP -.Vb 1 -\& $cvs -> history(); -.Ve -.Vb 1 -\& $cvs -> history({'-e' => ''}); -.Ve -.Vb 1 -\& $cvs -> history({'-xARM' => ''}); -.Ve -.Vb 1 -\& $cvs -> history({'-u' => $ENV{'LOGNAME'}, '-x' => 'A'}); -.Ve -but not -.PP -.Vb 1 -\& $cvs -> history({'-xA' => 'M'}); -.Ve -because it doesn't work. -.SH "\fInew\fR\|({})" -Create a new object. See the synopsis. -.PP -The anonymous hash takes these parameters, of which \*(L'project\*(R' is the -only required one. -.Ip "\(bu" 4 -\&'project\*(R' => \*(L'killerApp\*(R'. The required name of the project. No default -.Ip "\(bu" 4 -\&'permissions\*(R' => 0775. Unix-specific stuff. Default. Do not use \*(L'0775\*(R'. -.Ip "\(bu" 4 -\&'history\*(R' => 0. Do not create \f(CW$CVSROOT\fR/\s-1CVSROOT/\s0history when \fIcreateRepository()\fR is called. Default -.Ip "\(bu" 4 -\&'history\*(R' => 1. Create \f(CW$CVSROOT\fR/\s-1CVSROOT/\s0history, which initiates \*(L'cvs history\*(R' stuff -.Ip "\(bu" 4 -\&'raw\*(R' => 0. Convert tags from \s-1CVS\s0 format to real format. Eg: release_1.23. Default. -.Ip "\(bu" 4 -\&'raw\*(R' => 1. Return tags in raw \s-1CVS\s0 format. Eg: release_1_23. -.Ip "\(bu" 4 -\&'verbose\*(R' => 0. Do not report on the progress of mkpath/rmtree -.Ip "\(bu" 4 -\&'verbose\*(R' => 1. Report on the progress of mkpath/rmtree. Default -.SH "\fIpopulate\fR\|($sourceDir, \f(CW$vendorTag\fR, \f(CW$releaseTag\fR, \f(CW$message\fR)" -Import an existing directory structure. But, (sub) import is a reserved word. -.PP -Use this to populate a repository for the first time. -.PP -The value used for \f(CW$vendorTag\fR is not important; CVS discards it. -.PP -The value used to \f(CW$releaseTag\fR is important; CVS discards it (why?) but I -force it to be the first tag in \f(CW$CVSROOT\fR/CVSROOT/val-tags. Thus you -should supply a meaningful value. Thus \*(L'release_0_00\*(R' is strongly, repeat -strongly, recommended. -.PP -The value of \f(CW$raw\fR used in the call to new influences the handling of \f(CW$tag:\fR -.Ip "\(bu" 4 -$raw == 1 \-> Your tag is passed as is to \s-1CVS\s0. -.Ip "\(bu" 4 -$raw == 0 \-> Your tag is assumed to be of the form release_1.23, and is -converted to \s-1CVS\s0's form release_1_23. -.SH "\fIremoveDirectory\fR\|($dir)" -Remove a directory from the project. -.PP -This deletes the directory (and all its files) from your working copy -of the repository, as well as deleting them from the repository. -.PP -Warning: \f(CW$dir\fR will have \f(CW$CVSROOT\fR and \f(CW$HOME\fR prepended by this code. -Ie: \f(CW$dir\fR starts from \- but excludes \- your home directory -(assuming, of course, you've checked out into your home directory...). -.PP -You can't remove the current directory, or a parent. -.SH "\fIremoveFile\fR\|($dir, \f(CW$file\fR, \f(CW$message\fR)" -Remove a file from the project. -.PP -This deletes the file from your working copy of the repository, -as well as deleting it from the repository. -.PP -$dir can be a full path, or relative to the CWD. -\f(CW$file\fR is relative to \f(CW$dir\fR. -.SH "\fIrunOrCroak()\fR" -The standard way to run a system command and report on the result. -.SH "\fIsetTag\fR\|($tag)" -Tag the repository. -.PP -You call setTag, and it calls _setTag. -.PP -The value of \f(CW$raw\fR used in the call to new influences the handling of \f(CW$tag:\fR -.Ip "\(bu" 4 -$raw == 1 \-> Your tag is passed as is to \s-1CVS\s0. -.Ip "\(bu" 4 -$raw == 0 \-> Your tag is assumed to be of the form release_1.23, and is -converted to \s-1CVS\s0's form release_1_23. -.SH "\fIstripCVSDirs\fR\|($dir)" -Delete all CVS directories and files from a copy of the repository. -.PP -Each user directory contains a CVS sub-directory, which holds 3 files: -.Ip "\(bu" 4 -Entries -.Ip "\(bu" 4 -Repository -.Ip "\(bu" 4 -Root -.PP -Zap \*(L'em. -.SH "\fIstatus()\fR" -Run cvs status. -.PP -Return a reference to a list of lines. -.PP -Only called by \fIupToDate()\fR, but you may call it. -.SH "\fIupdate\fR\|($noChange)" -Run \*(L'cvs \f(CW-q\fR [\f(CW-n\fR] update\*(R', returning a reference to a list of lines. -Each line will start with one of [UARMC?], as per the CVS docs. -.PP -$cvs \-> \fIupdate\fR\|(1) is a good way to get a list of uncommited changes, etc. -.Ip "\(bu" 4 -$noChange == 0 \-> Do not add \f(CW-n\fR to the cvs command. Ie update your working copy -.Ip "\(bu" 4 -$noChange == 1 \-> Add \f(CW-n\fR to the cvs command. Do not change any files -.SH "\fIupToDate()\fR" -.Ip "\(bu" 4 -return == 0 \-> Repository not up-to-date. -.Ip "\(bu" 4 -return == 1 \-> Up-to-date. -.SH "\fI_checkOutDontCallMe\fR\|($readOnly, \f(CW$tag\fR, \f(CW$dir\fR)" -Checkout a current copy of the project. -.PP -You call checkOut, and it calls this. -.Ip "\(bu" 4 -$readOnly == 0 \-> Check out files as read-write. -.Ip "\(bu" 4 -$readOnly == 1 \-> Check out files as read-only. -.SH "\fI_fixTag\fR\|($tag)" -Fix a tag which CVS failed to add. -.PP -Warning: \f(CW$tag\fR must be in CVS format: release_1_23, not release_1.23. -.SH "\fI_mkpathOrCroak\fR\|($self, \f(CW$dir\fR)" -There is no need for you to call this. -.SH "\fI_readFile\fR\|($file)" -Return a reference to a list of lines. -.PP -There is no need for you to call this. -.SH "\fI_setTag\fR\|($tag)" -Tag the current version of the project. -.PP -Warning: \f(CW$tag\fR must be in CVS format: release_1_23, not release_1.23. -.PP -You call setTag and it calls this. -.SH "\fI_validateObject\fR\|($tag, \f(CW$file\fR, \f(CW$mustBeAbsent\fR)" -Validate an entry in one of the CVS files \*(L'module\*(R' or \*(L'val-tags\*(R'. -.PP -Warning: \f(CW$tag\fR must be in CVS format: release_1_23, not release_1.23. -.SH "AUTHOR" -\f(CWVCS::CVS\fR was written by Ron Savage \fI<rpsavage@ozemail.com.au>\fR in 1998. -.SH "LICENCE" -This program is free software; you can redistribute it and/or modify it under -the same terms as Perl itself. - -.rn }` '' -.IX Title "CVS 3" -.IX Name "C<VCS::CVS> - Provide a simple interface to CVS (the Concurrent Versions System)." - -.IX Header "NAME" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "SYNOPSIS" - -.IX Header "DESCRIPTION" - -.IX Header "INSTALLATION" - -.IX Header "WARNING re CVS bugs" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "WARNING re test environment" - -.IX Header "WARNING re project names \*(M'v\*(S' directory names" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "WARNING re shell intervention" - -.IX Header "WARNING re Perl bug" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIaddDirectory\fR\|($dir, \f(CW$subDir\fR, \f(CW$message\fR)" - -.IX Header "\fIaddFile\fR\|($dir, \f(CW$file\fR, \f(CW$message\fR)" - -.IX Header "\fIcheckOut\fR\|($readOnly, \f(CW$tag\fR, \f(CW$dir\fR)" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIcommit\fR\|($message)" - -.IX Header "\fIcreateRepository()\fR" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIgetTags()\fR" - -.IX Header "\fIhistory\fR\|({})" - -.IX Header "\fInew\fR\|({})" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIpopulate\fR\|($sourceDir, \f(CW$vendorTag\fR, \f(CW$releaseTag\fR, \f(CW$message\fR)" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIremoveDirectory\fR\|($dir)" - -.IX Header "\fIremoveFile\fR\|($dir, \f(CW$file\fR, \f(CW$message\fR)" - -.IX Header "\fIrunOrCroak()\fR" - -.IX Header "\fIsetTag\fR\|($tag)" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIstripCVSDirs\fR\|($dir)" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIstatus()\fR" - -.IX Header "\fIupdate\fR\|($noChange)" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fIupToDate()\fR" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fI_checkOutDontCallMe\fR\|($readOnly, \f(CW$tag\fR, \f(CW$dir\fR)" - -.IX Item "\(bu" - -.IX Item "\(bu" - -.IX Header "\fI_fixTag\fR\|($tag)" - -.IX Header "\fI_mkpathOrCroak\fR\|($self, \f(CW$dir\fR)" - -.IX Header "\fI_readFile\fR\|($file)" - -.IX Header "\fI_setTag\fR\|($tag)" - -.IX Header "\fI_validateObject\fR\|($tag, \f(CW$file\fR, \f(CW$mustBeAbsent\fR)" - -.IX Header "AUTHOR" - -.IX Header "LICENCE" - diff --git a/cpan/dist/VCS-CVS/t/base.t b/cpan/dist/VCS-CVS/t/base.t deleted file mode 100644 index b690dc50..00000000 --- a/cpan/dist/VCS-CVS/t/base.t +++ /dev/null @@ -1,38 +0,0 @@ -# -*- perl -*- - -use integer; -use strict; - -use vars qw($loaded); - -BEGIN -{ - $| = 1; - print "1..2\n"; -} - -END -{ - print "not ok 1\n" if (! $loaded); -} - -use VCS::CVS; - -$loaded = 1; - -print "ok 1\n"; - -my($testNum) = 1; - -sub Test($) -{ - my($result) = shift; - $testNum++; - print ( ($result ? "" : "not "), "ok $testNum\n"); - $result; -} - -$ENV{'CVSROOT'} = '.'; -my($spell) = VCS::CVS -> new({'project' => 'test'}); - -Test($spell); # or print "Error...\n"; diff --git a/cpan/dist/VCS-CVS/test.pl b/cpan/dist/VCS-CVS/test.pl deleted file mode 100755 index f88e4bf8..00000000 --- a/cpan/dist/VCS-CVS/test.pl +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/gnu/bin/perl -w -# -# Name: -# test.pl. -# -# Purpose: -# To test $PERL5LIB/VCS/CVS.pm. -# -# Warning: -# setenv CVSROOT <somethingHarmless> during this. - -use integer; -use strict; - -use Cwd; -use File::Basename; -use File::Copy; -use File::Path; -use VCS::CVS; - -#------------------------------------------------------------------ - -sub addDirectory -{ - my($cvs, $projectName, $subDirName, $fileName, $addDirMsg, - $addFileMsg, $verbose, $permissions) = @_; - - &init("$projectName/$subDirName", $fileName, $verbose, $permissions); - - &heading('addDirectory'); - $cvs -> addDirectory($projectName, $subDirName, $addDirMsg); - - print "\n"; - - # We can only add a file if we haven't used a sticky tag. - if ($projectName !~ /Strip/) - { - $fileName = fileparse($fileName, ''); - - &heading('addFile'); - $cvs -> addFile("$projectName/$subDirName", $fileName, $addFileMsg); - - print "\n"; - } - -} # End of addDirectory. - -#------------------------------------------------------------------ - -sub checkOut -{ - my($cvs, $readOnly, $dirName, $oldTag) = @_; - - &heading('checkOut'); - $cvs -> checkOut($readOnly, $oldTag, $dirName); - - &printDir($dirName); - - print "\n"; - -} # End of checkOut. - -#------------------------------------------------------------------ - -sub createRepository -{ - my($cvs, $projectSource, $vendorTag, $releaseTag, $initialMsg) = @_; - - &heading('createRepository'); - $cvs -> createRepository(); - - print "\n"; - - &heading('populate'); - $cvs -> populate($projectSource, $vendorTag, $releaseTag, $initialMsg); - - print "\n"; - -} # End of creatRepository. - -#------------------------------------------------------------------ - -sub getTags -{ - my($cvs) = @_; - - &heading('getTags'); - my($tagRef) = $cvs -> getTags(); - - print "Tags: \n"; - - for (sort(@$tagRef) ) - { - print "$_\n"; - } - -} # End of getTags. - -#------------------------------------------------------------------ - -sub heading -{ - my($heading) = @_; - - print "$heading\n"; - print '-' x (length($heading) ), "\n"; - -} # End of heading. - -#------------------------------------------------------------------ - -sub init -{ - my($projectSource, $fileName, $verbose, $permissions) = @_; - - my($destination) = "$ENV{'HOME'}/$projectSource"; - - &heading("rmtree+mkpath($destination)"); - rmtree($destination, $verbose); - mkpath($destination, $verbose, $permissions); - - copy($fileName, $destination); - - &printDir($destination); - - print "\n"; - -} # End of init. - -#------------------------------------------------------------------ - -sub printDir -{ - my($dirName) = @_; - - opendir(INX, $dirName) || die("Can't opendir($dirName): $!"); - my(@file) = readdir(INX); - closedir(INX); - - print "Directory: $dirName. Files: \n"; - - for (@file) - { - print "$_\n"; - } - -} # End of printDir. - -#------------------------------------------------------------------ - -sub setTag -{ - my($cvs, $newTag) = @_; - - # my($cvs, $dirName, $fileName, $newTag) = @_; - # - # Edit file, to cause failure of upToDate call within setTag. - # chdir($dirName) || die(Can't chdir($dirName): $!"); - # my($line) = &readFile($fileName); - # splice(@$line, 5, 2); - # &writeFile($fileName, $line); - - &heading('setTag'); - $cvs -> setTag($newTag); - - print "\n"; - - &getTags($cvs); - - print "\n"; - -} # End of setTag. - -#------------------------------------------------------------------ - -sub strip -{ - my($cvs, $dirName) = @_; - - &heading('stripCVSDirs'); - $cvs -> stripCVSDirs($dirName); - - print "\n"; - -} # End of strip. - -#------------------------------------------------------------------ - -sub upToDate -{ - my($cvs) = @_; - - &heading('status'); - my($status) = $cvs -> status(); - - print "Status: \n"; - for (@$status) - { - print "$_\n"; - } - - print "\n"; - - &heading('upToDate'); - my($upToDate) = $cvs -> upToDate(); - - print 'The repository is ', ($upToDate ? '' : 'not '), "up-to-date\n"; - print "\n"; - -} # End of upToDate. - -#------------------------------------------------------------------ - -my($addDirMsg) = 'Add directory'; -my($addFileMsg) = 'Add file'; -my($dirName) = 'project'; -my($fileName) = fileparse($0, ''); -my($history) = 1; -my($initialMsg) = 'Initial version'; -my($myself) = cwd() . "/$fileName"; -my($newTag) = 'release_0.01'; -my($noChange) = 1; -my($nullTag) = ''; -my($permissions) = 0775; # But not '0775'! -my($projectName) = 'project'; -my($projectSource) = 'projectSource'; -my($raw) = 0; -my($readOnly) = 0; -my($releaseTag) = 'release_0.00'; -my($removeFileMsg) = 'Remove file'; -my($repository) = 'repository'; -my($roDirName) = 'projectReadOnly'; -my($stripDirName) = 'projectStrip'; -my($subDirName) = 'subDir'; -my($vendorTag) = 'vendorTag'; -my($verbose) = 1; - -$ENV{'HOME'} = cwd(); - -$ENV{'CVSROOT'} = "$ENV{'HOME'}/VCS-CVS-test/$repository"; - -my($cvs) = VCS::CVS -> new({ - 'project' => $projectName, - 'raw' => $raw, - 'history' => $history, - 'permissions' => $permissions, - 'verbose' => $verbose}); - -&init($projectSource, $myself, $verbose, $permissions); - -chdir($ENV{'HOME'}) || die("Can't chdir($ENV{'HOME'}): $!"); - -&createRepository($cvs, $projectSource, $vendorTag, $releaseTag, $initialMsg); - -&checkOut($cvs, $readOnly, $projectName, $nullTag); -&checkOut($cvs, $readOnly, $stripDirName, $releaseTag); -&checkOut($cvs, (! $readOnly), $roDirName, $releaseTag); - -&addDirectory($cvs, $projectName, $subDirName, $myself, $addDirMsg, - $addFileMsg, $verbose, $permissions); -&addDirectory($cvs, $stripDirName, $subDirName, $myself, $addDirMsg, - $addFileMsg, $verbose, $permissions); - -#&setTag($cvs, $projectName, $fileName, $newTag); -&setTag($cvs, $newTag); - -&upToDate($cvs); - -print "Update returned: \n", join("\n", @{$cvs -> update($noChange)}), "\n"; -print "\n"; -print "History returned: \n", join("\n", @{$cvs -> history({'-e' => ''})}), "\n"; - -&strip($cvs, $stripDirName); - -# Success. -exit(0); diff --git a/cpan/lib/VCS/CVS.pm b/cpan/lib/VCS/CVS.pm deleted file mode 100644 index 3204e1b3..00000000 --- a/cpan/lib/VCS/CVS.pm +++ /dev/null @@ -1,1474 +0,0 @@ -package VCS::CVS; - -# Name: -# VCS::CVS. -# -# Documentation: -# POD-style documentation is at the end. Extract it with pod2html. -# -# Tabs: -# 4 spaces || die. -# -# -------------------------------------------------------------------------- - -use strict; -no strict 'refs'; - -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); - -use Carp; -use Cwd; -use File::Find; -use File::Path; - -require Exporter; - -@ISA = qw(Exporter); - -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. - -@EXPORT = qw(); - -@EXPORT_OK = qw(); - -$VERSION = '2.00'; - -# Preloaded methods go here. -# -------------------------------------------------------------------------- -# Add an existing directory to the project. -# $dir can be a full path, or relative to the CWD. - -sub addDirectory -{ - my($self, $dir, $subDir, $message) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): \nFailure: $!"); - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - # $subDir Add this directory. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'add'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - push(@args, $subDir); - - $self -> runOrCroak(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of addDirectory. - -# -------------------------------------------------------------------------- -# Add an existing file to the project. -# $dir can be a full path, or relative to the CWD. - -sub addFile -{ - my($self, $dir, $file, $message) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): \nFailure: $!"); - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - # $file Add this file. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'add'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - push(@args, $file); - - $self -> runOrCroak(@args); - - $self -> commit($message); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of addFile. - -# -------------------------------------------------------------------------- -# Prepare & perform 'cvs checkout'. -# You call checkOut, and it calls _checkOutDontCallMe. -# $readOnly Interpretation -# 0 Check out files as read-write -# 1 Check out files as read-only -# $tag Interpretation -# Null Do not call upToDate; ie check out repository as is -# ! Null Call upToDate; Croak if repository is not up-to-date -# If you called new with $raw == 1, your tag is passed as is to CVS. -# If you called new with $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. - -sub checkOut -{ - my($self, $readOnly, $tag, $dir) = @_; - - $tag =~ s/([-a-zA-Z]+_\d\d?)\.(\d\d)/$1_$2/ if (! $self -> {'raw'}); - - $self -> _validateObject($self -> {'project'}, 'modules', 0); - $self -> _validateObject($tag, 'val-tags', 0); - - croak("Failure: Move directory $dir out of the way") if (-d $dir); - - # Ensure the repository is up-to-date. - croak("Failure: The repository is not up-to-date. Run 'cvs commit' or 'cvs update'") - if ($tag && (! $self -> upToDate() ) ); - - # Zap previous copy of work directory. - rmtree($dir, $self -> {'verbose'}); - - # Checkout a current copy of the project. - $self -> _checkOutDontCallMe($readOnly, $tag, $dir); - -} # End of checkOut. - -# -------------------------------------------------------------------------- -# Commit changes. -# Called as appropriate by addFile, removeFile and removeDirectory, -# so you don't need to call it. - -sub commit -{ - my($self, $message) = @_; - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'commit'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - $self -> runOrCroak(@args); - -} # End of commit. - -# -------------------------------------------------------------------------- -# Create a repository, using the current $CVSROOT. - -sub createRepository -{ - my($self) = @_; - - croak("Failure: Move directory $ENV{'CVSROOT'} out of the way") if (-d $ENV{'CVSROOT'}); - - # Create the repository and its files. - $self -> _mkpathOrCroak($ENV{'CVSROOT'}); - $self -> _mkpathOrCroak("$ENV{'CVSROOT'}/CVSROOT"); - - # Create the modules file. - my(@args) = (); - push(@args, "CVSROOT\t\tCVSROOT"); - push(@args, "modules\t\tCVSROOT\tmodules"); - push(@args, "$self->{'project'}\t\t$self->{'project'}"); - - my($file) = "$ENV{'CVSROOT'}/CVSROOT/modules"; - open(OUT, "> $file") || croak("Can't open($file): \nFailure: $!"); - print OUT join("\n", @args), "\n"; - close(OUT); - - $file = "$ENV{'CVSROOT'}/CVSROOT/val-tags"; - open(OUT, "> $file") || croak("Can't open($file): \nFailure: $!"); - # Write nothing. - close(OUT); - - if ($self -> {'history'}) - { - $file = "$ENV{'CVSROOT'}/CVSROOT/history"; - open(OUT, "> $file") || croak("Can't open($file): \nFailure: $!"); - # Write nothing. - close(OUT); - } - -} # End of createRepository. - -# -------------------------------------------------------------------------- -# Return a reference to a list of tags. -# See also: the $raw option to new(). - -sub getTags -{ - my($self) = @_; - - my($line) = []; - - if (-e "$ENV{'CVSROOT'}/CVSROOT/val-tags") - { - $line = $self -> _readFile("$ENV{'CVSROOT'}/CVSROOT/val-tags"); - - for (@$line) - { - $_ = (split)[0]; - - # Convert tag_1_23 into tag_1.23, if requested. - s/([-a-zA-Z]+_\d\d?)_(\d\d)/$1\.$2/ if (! $self -> {'raw'}); - } - - } - - $line; - -} # End of getTags. - -# -------------------------------------------------------------------------- -# Run cvs history [-options]. -# Return a reference to a list of lines. -# -# The default option is -c. - -sub history -{ - my($self, $optionRef) = @_; - - # Preserve the caller's current working directory. - # cvs status only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir("$ENV{'HOME'}/$self->{'project'}") || - croak("Can't chdir($ENV{'HOME'}/$self->{'project'}): $!"); - - # CVS history options: - # -c Report commits, ie -xARM. - - if (ref($optionRef) ne 'HASH') - { - $optionRef = {'-c' => ''}; - } - - my(@args) = ('cvs'); - push(@args, 'history'); - push(@args, join(' ', %$optionRef) ); - @args = `@args`; - chomp(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - \@args; - -} # End of history. - -# -------------------------------------------------------------------------- -# These are the options in the anonymous hash of parameters you pass in to 'new'. -# -# 'project' -# 'killerApp' The name of the project. No default -# -# 'history' -# 0 Do not create $CVSROOT/CVSROOT/history when createRepository() is called. Default -# 1 Create $CVSROOT/CVSROOT/history, which initiates 'cvs history' stuff -# -# 'permissions' -# 0775 Unix-specific. Default. Do not use '0775' -# -# 'raw' -# 0 Convert tags from CVS format to real format. Eg: release_1.23. Default -# 1 Set/Get tags in raw CVS format. Eg: release_1_23 -# -# 'verbose' -# 0 Run quietly -# 1 Report progress. Default - -sub new -{ - my($class, $optionRef) = @_; - $class = ref($class) || $class; - my($self) = (ref($optionRef) eq 'HASH') ? $optionRef : {}; - - my(%default) = - ( - 'history' => 0, - 'permissions' => 0775, # But not '0775'! - 'project' => '', - 'raw' => 0, - 'verbose' => 1, - ); - - my($option); - - for $option (keys(%default) ) - { - $self -> {$option} = $default{$option} if (! defined($self -> {$option}) ); - } - - $ENV{'HOME'} = '' if (! defined($ENV{'HOME'}) ); - $ENV{'CVSROOT'} = '' if (! defined($ENV{'CVSROOT'}) ); - - croak("Failure: No project name specified") if (! $self -> {'project'}); - croak("Failure: Env. var HOME not set") if (! $ENV{'HOME'}); - croak("Failure: Env. var CVSROOT not set") if (! $ENV{'CVSROOT'}); - - return bless $self, $class; - -} # End of new. - -# -------------------------------------------------------------------------- -# 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. -# If you called new with $raw == 1, $releaseTag is passed as is to CVS. -# If you called new with $raw == 0, $releaseTag is assumed to be of the -# form release_1.23, and is converted to CVS's form release_1_23. - -# $sourceDir can be a full path, or relative to the CWD. - -sub populate -{ - my($self, $sourceDir, $vendorTag, $releaseTag, $message) = @_; - - $vendorTag = 'vendorTag' if ( ($#_ < 2) || (length($_[2]) == 0) ); - $releaseTag = 'release_0_00' if ( ($#_ < 3) || (length($_[3]) == 0) ); - $message = 'Initial version' if ($#_ < 4); - - $releaseTag =~ s/([-a-zA-Z]+_\d\d?)\.(\d\d)/$1_$2/ if (! $self -> {'raw'}); - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($sourceDir) || croak("Can't chdir($sourceDir): \nFailure: $!"); - - # CVS options: - # -Q Really quiet. - # -m message Use this log message. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'import'); - - if ($message) - { - $message = '"' . $message . '"' if ($message !~ /^".*"$/); - push(@args, '-m', $message); - } - - push(@args, $self -> {'project'}, $vendorTag, $releaseTag); - - $self -> runOrCroak(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - # Compensate for yet another CVS bug. - $self -> _fixTag($releaseTag); - -} # End of populate. - -# -------------------------------------------------------------------------- -# 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 thereof. - -sub removeDirectory -{ - my($self, $dir) = @_; - - my($cvsDir) = "$ENV{'CVSROOT'}/$dir/"; - my($workDir) = "$ENV{'HOME'}/$dir/"; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - - # Move into the work directory. - chdir($workDir) || croak("Can't chdir($workDir): \nFailure: $!"); - my($thisCwd) = cwd(); - - # Sanity check. - croak("Failure: You can't remove the current directory, or a parent") if ($cwd =~ /^$thisCwd/); - - # Ensure the repository is up-to-date. - croak("Failure: The repository is not up-to-date. Run 'cvs commit' or 'cvs update'") - if (! $self -> upToDate() ); - - # Read the CVS entries. - my($cvsEntries) = 'CVS/Entries'; - my($entry) = $self -> _readFile($cvsEntries); - - # Remove each file, using CVS. - for (@$entry) - { - next if (/^D/); - - my($file); - - $file = $1 if (/^\/(.+?)\//); - - $self -> removeFile($workDir, $file, 'Whole directory removed'); - } - - $self -> commit('Whole directory removed'); - - # Move up, and remove the directory. - chdir('..') || croak("Can't chdir('..'): \nFailure: $!"); - my($directory) = $workDir; - my($index) = rindex($directory, '/', (length($directory) - 2) ); - substr($directory, 0, ($index + 1) ) = ''; - rmtree($directory, $self -> {'verbose'}); - - # Edit the CVS entries file to remove the dir. - if (-f $cvsEntries) - { - $entry = $self -> _readFile($cvsEntries); - @$entry = grep(! /^D\/$directory\//, @$entry); - open(OUT, "> $cvsEntries") || croak("Can't open $cvsEntries: \nFailure: $!"); - print OUT join("\n", @$entry), "\n"; - close(OUT); - } - - # Remove the directory from CVS. - rmtree($cvsDir, $self -> {'verbose'}); - - # Remove the directory from the modules list. - if ($dir !~ /\//) - { - $cvsEntries = "$ENV{'CVSROOT'}/CVSROOT/modules"; - $entry = $self -> _readFile($cvsEntries); - - my($i); - - for ($i = 0; $i <= $#{$entry}; $i++) - { - my(@field) = split(/\s+/, $$entry[$i]); - splice(@$entry, $i, 1) if ($field[1] =~ /^$dir$/); - } - - open(OUT, "> $cvsEntries") || croak("Can't open $cvsEntries: \nFailure: $!"); - print OUT join("\n", @$entry), "\n"; - close(OUT); - } - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of removeDirectory. - -# -------------------------------------------------------------------------- -# 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. - -sub removeFile -{ - my($self, $dir, $file, $message) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): \nFailure: $!"); - - unlink($file) || croak("Can't unlink($file): $!"); - - # CVS options: - # -Q Really quiet. - # -f Remove the file first. - # -l Do not recurse. - # $file Checkout this module. - - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'remove', '-f', '-l', $file); - - $self -> runOrCroak(@args); - - $self -> commit($message); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of removeFile. - -# -------------------------------------------------------------------------- -# The standard way to run a system command and report on the result. - -sub runOrCroak -{ - my($self, @args) = @_; - - my($result) = 0xffff & system(@args); - - print "Command: @args\n"; - - if ($result == 0) - { - print 'Success. '; - } - elsif ($result == 0xff00) - { - print "Failure: $!. "; - } - elsif ($result > 0x80) - { - $result >>= 8; - print "Exit status: $result. "; - } - else - { - if ($result & 0x80) - { - $result &= ~0x80; - print 'Coredump from '; - } - - print "Signal $result. "; - } - - printf("Result: %#04x\n", $result); - - croak("Failure: Can't run '@args'") if ($result); - -} # End of runOrCroak. - -# -------------------------------------------------------------------------- -# Tag the repository. -# You call setTag, and it calls _setTag. -# If you called new with $raw == 1, your tag is passed as is to CVS. -# If you called new with $raw == 0, your tag is assumed to be of the -# form release_1.23, and is converted to CVS's form release_1_23. - -sub setTag -{ - my($self, $tag) = @_; - - $tag =~ s/([-a-zA-Z]+_\d\d?)\.(\d\d)/$1_$2/ if (! $self -> {'raw'}); - - $self -> _validateObject($self -> {'project'}, 'modules', 0); - $self -> _validateObject($tag, 'val-tags', 1); - - croak("Failure: The repository is not up-to-date. Run 'cvs commit' or 'cvs update'") - if ($self -> upToDate() == 0); - - $self -> _setTag($tag); - -} # End of setTag. - -# -------------------------------------------------------------------------- -# Run cvs status. -# Return a reference to a list of lines. -# Only called by upToDate(), but you may call it. - -sub status -{ - my($self) = @_; - - # Preserve the caller's current working directory. - # cvs status only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir("$ENV{'HOME'}/$self->{'project'}") || - croak("Can't chdir($ENV{'HOME'}/$self->{'project'}): $!"); - - # CVS options: - # -Q Really quiet. - - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'status'); - @args = `@args`; - chomp(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - \@args; - -} # End of status. - -# -------------------------------------------------------------------------- -# Delete all CVS directories and files from a copy of the repository. - -sub stripCVSDirs -{ - my($self, $dir) = @_; - - # Preserve the caller's current working directory. - my($cwd) = cwd(); - chdir($dir) || croak("Can't chdir($dir): $!"); - - my(%dirStack); - - find - ( - sub - { - $dirStack{$File::Find::dir} = 1 if ($File::Find::dir =~ /\/CVS$/); - }, - cwd() - ); - - for (keys(%dirStack) ) - { - rmtree($_, $self -> {'verbose'}); - } - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - -} # End of stripCVSDirs. - -# -------------------------------------------------------------------------- -# Run cvs -q [-n] update. -# Return a reference to a list of lines. -# Each line will start with one of [UARMC?], as per the CVS docs. -# -# Parameters Interpretation -# $n 0 -> Do not add -n to the cvs update command -# 1 -> Add -n to the command - -sub update -{ - my($self, $n) = @_; - - $n = 0 if (! defined($n) ); - - # Preserve the caller's current working directory. - # cvs status only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir("$ENV{'HOME'}/$self->{'project'}") || - croak("Can't chdir($ENV{'HOME'}/$self->{'project'}): $!"); - - # CVS options: - # -q Quiet - # -n Do not change any files - - my(@args) = ('cvs'); - push(@args, '-q') if (! $self -> {'verbose'}); - push(@args, '-n') if ($n); - push(@args, 'update'); - @args = `@args`; - chomp(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - \@args; - -} # End of update. - -# -------------------------------------------------------------------------- -# Return Interpretation -# 0 Repository not up-to-date. -# 1 Up-to-date. - -sub upToDate -{ - my($self) = @_; - - # Get the status of the repository. - my($status) = $self -> status(); - @$status = grep(/Status/ && ! /Up-to-date/, @$status); - my($result) = 1; # Up-to-date. - $result = 0 if ($#{$status} >= 0); # Not, because log contains something. - - $result; - -} # End of upToDate. - -# -------------------------------------------------------------------------- -# Checkout a current copy of the project. -# You call checkOut, and it calls this. - -sub _checkOutDontCallMe -{ - my($self, $readOnly, $tag, $dir) = @_; - - # CVS options: - # -Q Really quiet. - # -r Read-only. Make the new working files read-only. - # -d$dir Use $dir, not $project, as the directory name. - # -r <tag> Check out files tagged with <tag>. Optional. - # - # $project Checkout this module. - - # CVS bug. Remove trailing '/', if any. - $dir = $1 if ($dir =~ /^(.+)\/$/); - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, '-r') if ($readOnly); - push(@args, 'checkout', '-A', '-P', "-d$dir"); - push(@args, '-r', $tag) if ($tag); - push(@args, $self -> {'project'}); - - $self -> runOrCroak(@args); - -} # End of _checkOutDontCallMe. - -# -------------------------------------------------------------------------- -# Fix a tag CVS failed to add. -# Warning: $tag must be in CVS format. Eg: release_1_23, not release_1.23. - -sub _fixTag -{ - my($self, $tag) = @_; - - my($file) = "$ENV{'CVSROOT'}/CVSROOT/val-tags"; - - open(INX, $file) || croak("Can't open($file): \nFailure: $!"); - - my($found) = 0; - - while (<INX>) - { - $found = 1 if (/^$tag/); - } - - close(INX); - - if (! $found) - { - print "Warning: CVS bug. Tag $tag not in file $file\n" if ($self -> {'verbose'}); - print "Fixing... " if ($self -> {'verbose'}); - - open(OUT, ">> $file") || croak("Can't open(>>$file): \nFailure: $!"); - print OUT "$tag y\n"; - close(OUT); - - print "Success\n" if ($self -> {'verbose'}); - } - -} # End of _fixTag. - -# -------------------------------------------------------------------------- - -sub _mkpathOrCroak -{ - my($self, $dir) = @_; - - my($result) = mkpath($dir, $self -> {'verbose'}, $self -> {'permissions'}); - - croak("Can't mkpath($dir, $self->{'verbose'}, $self->{'permissions'}): \nFailure: $!") - if ( (! $result) && ($! !~ /No such file/) ); - -} # End of _mkpathOrCroak. - -# -------------------------------------------------------------------------- -# Return a reference to a list of lines. - -sub _readFile -{ - my($self, $file) = @_; - - open(INX, $file) || croak("Can't open($file): $!"); - my(@line) = <INX>; - close(INX); - chomp(@line); - - \@line; - -} # end of _readFile. - -# -------------------------------------------------------------------------- -# Tag the current version of the project. -# Warning: $tag must be in CVS format. Eg: release_1_23, not release_1.23. -# You call setTag and it calls this. - -sub _setTag -{ - my($self, $tag) = @_; - - # Preserve the caller's current working directory. - # cvs tag only works on the whole repository when run from your project dir - # (assuming, of course, you've checked out into your home directory...). - my($cwd) = cwd(); - chdir($ENV{'HOME'}) || croak("Can't chdir($ENV{'HOME'}): $!"); - - # CVS options: - # -Q Really quiet. - # -r <tag> Tag files with <tag>. - # $project Tag this module. - - # Warning: Do not try to combine these lines under any circumstances... - # Perl can't handle null list elements in a call to system. - my(@args) = ('cvs'); - push(@args, '-Q') if (! $self -> {'verbose'}); - push(@args, 'tag', $tag, $self -> {'project'}); - - $self -> runOrCroak(@args); - - chdir($cwd) || croak("Can't chdir($cwd): $!"); - - # Compensate for yet another CVS bug. - $self -> _fixTag($tag); - -} # End of _setTag. - -# -------------------------------------------------------------------------- -# Validate an entry in one of the CVS files 'module' or 'val-tags'. -# Warning: $tag must be in CVS format. Eg: release_1_23, not release_1.23. - -sub _validateObject -{ - my($self, $tag, $file, $mustBeAbsent) = @_; - - $file = "$ENV{'CVSROOT'}/CVSROOT/$file"; - - open(INX, $file) || croak("Can't open($file): \nFailure: $!"); - - my($found) = 0; - - while (<INX>) - { - $found = 1 if (/^$tag/); - } - - close(INX); - - croak("Failure: Tag not found: $tag in file $file") - if ( (! $found) && (! $mustBeAbsent) ); - - croak("Failure: Tag already present: $tag in file $file") - if ($found && $mustBeAbsent); - -} # End of _validateObject. - -# -------------------------------------------------------------------------- - -# Autoload methods go after =cut, and are processed by the autosplit program. - -1; - -__END__ - -=head1 NAME - -C<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: - -=over 4 - -=item * - -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. - -=item * - -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. - -=item * - -The directory in which the repository resides. This is $CVSROOT. Thus -$projectSource will be imported into $CVSROOT/$project. - -=item * - -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. - -=back - -Note: You cannot have a directory called CVS in your home directory. That's -just asking for trouble. - -=head1 SYNOPSIS - - #!/usr/gnu/bin/perl -w - - use integer; - use strict; - - use VCS::CVS; - - my($history) = 1; - my($initialMsg) = 'Initial version'; - my($noChange) = 1; - 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; - - # Note the anonymous hash in the next line, new as of V 1.10. - - my($cvs) = VCS::CVS -> new({ - 'project' => $project, - 'raw' => $raw, - 'verbose' => $verbose, - 'permissions' => $permissions, - 'history' => $history}); - - $cvs -> createRepository(); - $cvs -> populate($projectSource, $vendorTag, $releaseTag, $initialMsg); - $cvs -> checkOut($readOnly, $nullTag, $project); - - print join("\n", @{$cvs -> update($noChange)}); - print "\n"; - print join("\n", @{$cvs -> history()}); - - exit(0); - -=head1 DESCRIPTION - -The C<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. - -Stop press: CVS V 1.10 (with RCS 5.7) supports binary files. - -Subroutines whose names start with a '_' are not normally called by you. - -There is a test program included, but I have not yet worked out exactly how to -set it up for make test. Stay tuned. - -=head1 INSTALLATION - -You install C<VCS::CVS>, as you would install any perl module library, -by running these commands: - - perl Makefile.PL - make - make test - make install - -If you want to install a private copy of C<VCS::CVS> in your home -directory, then you should try to produce the initial Makefile with -something like this command: - - perl Makefile.PL LIB=~/perl - or - perl Makefile.PL LIB=C:/Perl/Site/Lib - -If, like me, you don't have permission to write man pages into unix system -directories, use: - - make pure_install - -instead of make install. This option is secreted in the middle of p 414 of the -second edition of the dromedary book. - -=head1 WARNING re CVS bugs - -The following are my ideas as to what constitutes a bug in CVS: - -=over 4 - -=item * - -The initial revision tag, supplied when populating the repository with -'cvs import', is not saved into $CVSROOT/CVSROOT/val-tags. - -=item * - -The 'cvs tag' command does not always put the tag into 'val-tags'. - -=item * - -C<'cvs checkout -dNameOfDir'> fails if NameOfDir =~ /\/$/. - -=item * - -C<'cvs checkout -d NameOfDir'> inserts a leading space into the name of -the directory it creates. - -=back - -=head1 WARNING re test environment - -This code has only been tested under Unix. Sorry. - -=head1 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: - -=over 4 - -=item * - -C<checkOut> - -=item * - -C<removeDirectory> - -=item * - -C<setTag> - -=back - -=head1 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. - -=head1 WARNING re Perl bug - -As always, be aware that these 2 lines mean the same thing, sometimes: - -=over 4 - -=item * - -$self -> {'thing'} - -=item * - -$self->{'thing'} - -=back - -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. - -=head1 addDirectory($dir, $subDir, $message) - -Add an existing directory to the project. - -$dir can be a full path, or relative to the CWD. - -=head1 addFile($dir, $file, $message) - -Add an existing file to the project. - -$dir can be a full path, or relative to the CWD. - -=head1 checkOut($readOnly, $tag, $dir) - -Prepare & perform 'cvs checkout'. - -You call checkOut, and it calls _checkOutDontCallMe. - -=over 4 - -=item * - -$readOnly == 0 -> Check out files as read-write. - -=item * - -$readOnly == 1 -> Check out files as read-only. - -=back - -=over 4 - -=item * - -$tag is Null -> Do not call upToDate; ie check out repository as is. - -=item * - -$tag is not Null -> Call upToDate; Croak if repository is not up-to-date. - -=back - -The value of $raw used in the call to new influences the handling of $tag: - -=over 4 - -=item * - -$raw == 1 -> Your tag is passed as is to CVS. - -=item * - -$raw == 0 -> Your tag is assumed to be of the form release_1.23, and is -converted to CVS's form release_1_23. - -=back - -$dir can be a full path, or relative to the CWD. - -=head1 commit($message) - -Commit changes. - -Called as appropriate by addFile, removeFile and removeDirectory, -so you don't need to call it. - -=head1 createRepository() - -Create a repository, using the current $CVSROOT. - -This involves creating these files: - -=over 4 - -=item * - -$ENV{'CVSROOT'}/CVSROOT/modules - -=item * - -$ENV{'CVSROOT'}/CVSROOT/val-tags - -=item * - -$ENV{'CVSROOT'}/CVSROOT/history - -=back - -Notes: - -=over 4 - -=item * - -The 'modules' file contains these lines: - - CVSROOT CVSROOT - modules CVSROOT modules - $self -> {'project'} $self -> {'project'} - -where $self -> {'project'} comes from the 'project' parameter to new() - -=item * - -The 'val-tags' file is initially empty - -=item * - -The 'history' file is only created if the 'history' parameter to new() is set. -The file is initially empty - -=back - -=head1 getTags() - -Return a reference to a list of tags. - -See also: the $raw option to new(). - -C<getTags> does not take a project name because tags belong to the repository -as a whole, not to a project. - -=head1 history({}) - -Report details from the history log, $CVSROOT/CVSROOT/history. - -You must have used new({'history' => 1}), or some other mechanism, to create -the history file, before CVS starts logging changes into the history file. - -The anonymous hash takes any parameters 'cvs history' takes, and joins them -with a single space. Eg: - - $cvs -> history(); - - $cvs -> history({'-e' => ''}); - - $cvs -> history({'-xARM' => ''}); - - $cvs -> history({'-u' => $ENV{'LOGNAME'}, '-x' => 'A'}); - -but not - - $cvs -> history({'-xA' => 'M'}); - -because it doesn't work. - -=head1 new({}) - -Create a new object. See the synopsis. - -The anonymous hash takes these parameters, of which 'project' is the -only required one. - -=over 4 - -=item * - -'project' => 'killerApp'. The required name of the project. No default - -=back - -=over 4 - -=item * - -'permissions' => 0775. Unix-specific stuff. Default. Do not use '0775'. - -=back - -=over 4 - -=item * - -'history' => 0. Do not create $CVSROOT/CVSROOT/history when createRepository() is called. Default - -=item * - -'history' => 1. Create $CVSROOT/CVSROOT/history, which initiates 'cvs history' stuff - -=back - -=over 4 - -=item * - -'raw' => 0. Convert tags from CVS format to real format. Eg: release_1.23. Default. - -=item * - -'raw' => 1. Return tags in raw CVS format. Eg: release_1_23. - -=back - -=over 4 - -=item * - -'verbose' => 0. Do not report on the progress of mkpath/rmtree - -=item * - -'verbose' => 1. Report on the progress of mkpath/rmtree. Default - -=back - -=head1 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: - -=over 4 - -=item * - -$raw == 1 -> Your tag is passed as is to CVS. - -=item * - -$raw == 0 -> Your tag is assumed to be of the form release_1.23, and is -converted to CVS's form release_1_23. - -=back - -=head1 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. - -=head1 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. - -=head1 runOrCroak() - -The standard way to run a system command and report on the result. - -=head1 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: - -=over 4 - -=item * - -$raw == 1 -> Your tag is passed as is to CVS. - -=item * - -$raw == 0 -> Your tag is assumed to be of the form release_1.23, and is -converted to CVS's form release_1_23. - -=back - -=head1 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: - -=over 4 - -=item * - -Entries - -=item * - -Repository - -=item * - -Root - -=back - -Zap 'em. - -=head1 status() - -Run cvs status. - -Return a reference to a list of lines. - -Only called by upToDate(), but you may call it. - -=head1 update($noChange) - -Run 'cvs C<-q> [C<-n>] update', returning a reference to a list of lines. -Each line will start with one of [UARMC?], as per the CVS docs. - -$cvs -> update(1) is a good way to get a list of uncommited changes, etc. - -=over 4 - -=item * - -$noChange == 0 -> Do not add C<-n> to the cvs command. Ie update your working copy - -=item * - -$noChange == 1 -> Add C<-n> to the cvs command. Do not change any files - -=back - -=head1 upToDate() - -=over 4 - -=item * - -return == 0 -> Repository not up-to-date. - -=item * - -return == 1 -> Up-to-date. - -=back - -=head1 _checkOutDontCallMe($readOnly, $tag, $dir) - -Checkout a current copy of the project. - -You call checkOut, and it calls this. - -=over 4 - -=item * - -$readOnly == 0 -> Check out files as read-write. - -=item * - -$readOnly == 1 -> Check out files as read-only. - -=back - -=head1 _fixTag($tag) - -Fix a tag which CVS failed to add. - -Warning: $tag must be in CVS format: release_1_23, not release_1.23. - -=head1 _mkpathOrCroak($self, $dir) - -There is no need for you to call this. - -=head1 _readFile($file) - -Return a reference to a list of lines. - -There is no need for you to call this. - -=head1 _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. - -=head1 _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. - -=head1 AUTHOR - -C<VCS::CVS> was written by Ron Savage I<E<lt>rpsavage@ozemail.com.auE<gt>> in 1998. - -=head1 LICENCE - -This program is free software; you can redistribute it and/or modify it under -the same terms as Perl itself. |
