# PANT::Cvs - Provide support for CVS operations package PANT::Cvs; use 5.008; use strict; use warnings; use Carp; use Cwd; use XML::Writer; use Exporter; our @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. # This allows declaration use PANT ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw() ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '0.02'; sub new { my($clsname, $writer, @rest) =@_; my $self = { writer=>$writer, @rest, }; bless $self, $clsname; return $self; } sub Run { my($self, $cmd, %args) = @_; my $writer = $self->{writer}; my $cdir = "."; if ($args{directory}) { $cdir = getcwd; chdir($args{directory}) || Abort("Can't change to directory $args{directory}"); } $writer->startTag('li'); $writer->characters("Run $cmd\n"); my $output; my $retval; if ($self->{dryrun}) { $output = "Output of the command $cmd would be here"; $retval = 1; } else { $writer->startTag('pre'); $cmd .= " 2>&1"; # collect stderr too $self->{lines} = []; if (open(PIPE, "$cmd |")) { while(my $line = ) { $writer->characters($line); push(@ {$self->{lines} }, $line); } close(PIPE); $retval = $? == 0; } else { $retval = 0; } $writer->endTag('pre'); } $writer->characters("$cmd failed: $!") if ($retval == 0); $writer->endTag('li'); do { chdir($cdir) || Abort("Can't change back to $cdir: $!"); } if ($args{directory}); return $retval; } sub HasUpdate { my $self = shift; foreach my $line (@{ $self->{lines} }) { if ($line =~ /^\s*[UP]\s+/) { # Its a change, one out, all out. return 1; } } return 0; } sub HasLocalMod { my $self = shift; foreach my $line (@{ $self->{lines} }) { if ($line =~ /^\s*[MA]\s+/) { # Its a change, one out, all out. return 1; } } return 0; } sub HasConflict { my $self = shift; foreach my $line (@{ $self->{lines} }) { if ($line =~ /^\s*[C]\s+/) { # Its a conflict return 1; } } return 0; } 1; __END__ =head1 NAME PANT::Cvs - PANT support for cvs operations =head1 SYNOPSIS use PANT; $cvs = Cvs(); $cvs->Run("cvs update"); if ($cvs->HasUpdates()) { # increment version # run a build etc. } =head1 ABSTRACT This is part of a module to help construct automated build environments. This part is for help processing Cvs operations. =head1 DESCRIPTION This module is part of a set to help run automated builds of a project and to produce a build log. This part is designed to provide support for cvs. Most cvs operations can be simply run as Command's from the main module, but occasionally you want to know if something has changed. For instance you may not want to run an auto build if nothing has changed since last time. =head1 EXPORTS None =head1 METHODS =head2 new($xml); Constructor for a test object. Requires an XML::Writer object, which it will use for subsequent log construction. The PANT function Cvs calls this constructor with the current xml stream. So normally you would call it via the accessor. =head2 Run(command) This command will run the given cvs command, and will collect the output, pass it to the log stream, and analyse it too. =head2 HasUpdate() This is a boolean function that tells you if the last Run command detected any updates to the archive. =head2 HasLocalMod() This is a boolean function that tells you if the last Run command detected any local uncommitted updates to the the archive. =head2 HasConflict() This is a boolean function that tells you if the last Run command detected any conflicts. =head1 SEE ALSO Makes use of XML::Writer to construct the build log. =head1 AUTHOR Julian Onions, Ejulianonions@yahoo.nospam-co.ukE =head1 COPYRIGHT AND LICENSE Copyright 2005 by Julian Onions This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut