########################################### # CVSUtil.pm -- Utility functions for CVS # Mike Schilli, 2002 (m@perlmeister.com) ########################################### package CVSUtil; our $VERSION = "1.01"; our $CVSVERSION = '$Revision: 1.4 $'; our @ISA = qw(Exporter); our $CVS_COMMAND = "cvs"; use warnings; use strict; use File::Basename; ########################################### sub cvs_command { ########################################### $CVS_COMMAND = $_[0] if defined $_[0]; return $CVS_COMMAND; } ########################################### sub open_revision { ########################################### my ($path, $revision) = @_; my $cmd; my $cvsroot = cvsroot(); if(!defined $revision) { # Get latest CVS version $revision = get_latest_revision($cvsroot, $path); } $path = get_cvs_path($path); # Get file $cmd = "$CVS_COMMAND -Q -d " . "$cvsroot co -r $revision -p $path |"; open my $fh, "$cmd" or die "Cannot open '$cmd'"; return $fh; } ########################################### sub get_latest_revision { ########################################### my ($cvsroot, $path) = @_; my $cmd = "$CVS_COMMAND -Q -d " . "$cvsroot status $path" . " 2>/dev/null"; open PIPE, "$cmd |" or die "Cannot open pipe"; my $data = join '', ; close PIPE or die "$cmd failed"; $data =~ /Repository revision:\s*([\d\.]+)/; return $1; } ########################################### sub get_cvs_path { ########################################### my ($file) = @_; # Get path within CVS/working path my $rep = File::Basename::dirname($file) . "/CVS/Repository"; open FILE, "<$rep" or die "Cannot open $rep"; chomp(my $rpath = ); $rpath .= "/" . File::Basename::basename($file); close FILE; return $rpath; } ########################################### sub cvsroot { ########################################### open CVSROOT, "CVS/Root" or die "Cannot open CVS/Root"; my $path = join '', ; chomp $path; close CVSROOT; return $path; } ########################################### sub module { ########################################### open MODULE, "CVS/Repository" or die "Cannot open CVS/Repository"; my $module = join '', ; chomp $module; close MODULE; return $module; } 1; __END__ =head1 NAME CVSUtil -- Utility functions for CVS =head1 DOWNLOAD _SRC_HERE_ =head1 SYNOPSIS use CVSUtil; # NOTE: All of the following functions assume # That you've chdir()'d to some CVS working # directory where the files specified reside. # Get a file handle to the latest checked-in # revision of test.c my $fh = CVSUtil::open_revision("test.c"); while(<$fh>) { print $_; } close $fh; # Get a file handle to revision 1.1 of test.c my $fh = CVSUtil::open_revision("test.c", "1.1"); while(<$fh>) { print $_; } close $fh; # Give the relative path (starting from the CVS # root) to a file in CVS. my $path = CVSUtil::get_cvs_path("test.c"); # => 'modulename/dir1/dir2/test.c' # Get the revision number of the latest checked-in # version of a file. my $rev = CVSUtil::get_latest_revision("test.c"); # => '1.12' # Set the path to the 'cvs' program for # subsequent calls to CVSUtil functions CVSUtil::cvs_command("/tools/bin/cvs"); =head1 DESCRIPTION A developer's CVS working directory often contains locally modified copies of checked-in versions of files. While the C command compares checked-in and local versions conveniently, there's no easy way to the checked-in version itself. C tries to bridge this gap by providing an easy-to-use programming interface to figure out which version of a file has been checked into CVS last and, upon request, opens this revision and provides a reading file handle to it. It uses cvs' local C and C directories to find out about the CVSROOT of the current project and the relative location of the current subdirectory within the project. =head2 Functions =over 4 =item CVSUtil::cvs_command( $path_to_cvs ); If your system doesn't have the C command in your C<$PATH> variable (i.e. if you can't type C in your shell to call it), you need to tell C first, where it's located, before you start using any of the commands listed below. The function returns the new setting of the path to the cvs command. If called without parameters, it returns the current setting. =item my $fh = CVSUtil::open_revision($filename, [$rev]); Opens revision C<$rev> of C<$filename> and returns a read-only file handle to it. Note that you need to chdir() into a CVS working directory containing the file C<$filename>, first. If C<$rev> is not specified, C will use C to determine the most recently checked-in version and provide a file handle to it. =item my $rev = CVSUtil::get_latest_revision($filename); Figures out the revision number of the most recently checked-in version of the file $filename. Note that you need to chdir() into a CVS working directory containing the file C<$filename>, first. Returns the revision number as a string (e.g. C<"1.12">) and C in case of an error. =item my $path = CVSUtil::get_cvs_path($filename); Determines the relative path to C<$filename>, starting from the CVS's root directory. Note that you need to chdir() into a CVS working directory containing the file C<$filename>, first. E.g., if you're in C and you call C, you'll get C<"projectname/dir1/dir2/test.c"> back, even if your local working directory is not C but something like C. =item my $module = CVSUtil::module(); Returns the name of the current module (project), which the current working directory belongs to. =back =head1 LEGALESE Copyright 2002 by Mike Schilli, all rights reserved. This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR 2002, Mike Schilli