Blame | Last modification | View Log | RSS feed
################################################################################ CLASS Clearcase::LsCmd# This class inherits from the CCCmpdProc and executes the cleartool command# "ls" with args "-recurse -long" to list all files in cwd.## It overrider the CCProcess member to process the resultant output from the ls# command and store information about all files/dirs in and below the pwd.## It uses the CCIgnore class to determine if a file should be ignored or included# in the processing of the cmd output.## It stores as a result of the command for each file/dir# NAME = The full path of the file (as defined by CCCmdProc)# STATE = File NAME State (CHECKEDOUT, CHECKIN, PRIVATE)# VERSION = If state=CHECKEDIN Then current version of NAME in view# If state=CHECKEDOUT Then version of NAME that the checkout was from# ANNOTATION= Any Special Annotations returned by ls on NAME###############################################################################package Clearcase::LsCmd;use strict;use Cwd qw/ abs_path /;use DeployUtils::Logger;use Clearcase::IgnoreList;use Clearcase::CmdProc;use vars qw( @ISA );@ISA = qw( Clearcase::CmdProc );# Globally defined statesour $StateCheckedIn = "CHECKEDIN";our $StateCheckedOut = "CHECKEDOUT";our $StatePrivate = "PRIVATE";#==============================================================================# Constructor#==============================================================================sub new{my $obclass = shift;my $class = ref($obclass) || $obclass;my $dir = shift;LogDebug("Clearcase::LsCmd::new Instantiating new object of class $class");# if no dir of dir is "." the get full absolute path, abs_path returns path with "/" regardless of platform$dir = abs_path(".") if ( ! defined($dir) || $dir eq "." );# however if passed in make sure we change \ to /$dir =~ s|\\|/|g;# Call base class's constructormy $self = $class->SUPER::new();# Add this class's data to the class object$self->{_FINDDIR} = $dir;$self->{_IGNOREFILES} = 1;$self->{_IGNORECOUNT} = 0;#indexes used# State index is a hash of hashes of arrays. The contents of _STATE are hashes keyed on global states# These hashes contain an array of element numbers into the FILEINFO array# The branch & annotation are similar but keyed on branches and annotations$self->{_STATE} = {};$self->{_BRANCH} = {};$self->{_ANNOTATION} = {};bless($self, $class);# set Clearcase command and arg$self->CCcmd("ls");$self->CCargs("-long");return $self;} # new#==============================================================================# ignoreFiles# Sets & returns the ignore files variable that determines whether to use the# IgnoreFiles class for files to ignore#==============================================================================sub ignoreFiles{my $self = shift;if ( @_ ){$self->{_IGNOREFILES} = shift;LogDebug("ClearCase::LsCmd::ignoreFiles Set to $self->{_IGNOREFILES}");}return $self->{_IGNOREFILES};} # ignoreFiles#==============================================================================# CCexecute# simply adds dir to args and runs base class CCexecute#==============================================================================sub CCexecute{my $self = shift;my $args = $self->CCargs();# search directory first$self->CCargs("$args -directory $self->{_FINDDIR}");$self->SUPER::CCexecute();# now serach the contents$self->CCargs("$args -recurse $self->{_FINDDIR}");$self->SUPER::CCexecute();} # CCexecute#==============================================================================# CCprocess overrides base class's CCProcess to process result#==============================================================================sub CCprocess{my $self = shift;my $line;my ($name, $state, $version, $branch, $annotation ) = ( "", "", "", "", "" );my $index;my $dirRE = $self->{_FINDDIR};# Change the search RE for the findDir so that all occurances of "/" in path are changed to "[/\\]"# to match either type of path separator$dirRE =~ s|/|\[/\\\\\]|g;NEXTLINE:while ( $line = $self->getline() ){chomp $line;$line =~ s/\r//g; # remove carraige returns# ignore blank lines or lines with directory ".*" with quotesnext NEXTLINE if ( $line =~ /^\s*$/ || $line =~ /directory\s*\".*\":/ );if ( $line =~ /^view private object\s*(.*)\s*$/ ){$name = $1;$state = $StatePrivate;$version = "";$branch = "";$annotation = "";if ( $self->{_IGNOREFILES} && Clearcase::IgnoreList->ignoreFile($name) ){LogDebug("Clearcase::LsCmd::CCProcess Ignoring Private file $name");$self->{_IGNORECOUNT}++;next NEXTLINE;}}elsif ( $line =~ /^(?:directory |)version\s*(.*)\@\@(.*)$/ ){# got the file name, & rest of line$name = $1;$line = $2;# remove the Rule: from the end of the line as we dont need it$line =~ s/\s*Rule: .*$//;# Check for annotations & store, removing from line$line =~ s/\s*\[(.*)\]\s*$//;if ( defined($1) ){ $annotation = $1; }else{ $annotation = ""; }# See if Checked out stateif ( $line =~ /^.*CHECKEDOUT from (.*)$/ ){$state = $StateCheckedOut;$version = $1; # version is version checked out from}else{$state = $StateCheckedIn;$version = $line;}$branch = $version;# remove version number and dir separator from version to get branch$branch =~ s|[/\\]\d*$||;}else{LogError("-x", "Clearcase::LsCmd::CCprocess Unknown Input Line as follows");LogError("$line");}# Remove findDir from path if find dir is same as pwd, makes it less clutered$name =~ s|$dirRE|\.| if ( $self->CCcwd() =~ m|^$dirRE| );# Add name to file list and set it as current element$index = $self->addToFileList($name);# now add other elements, the index is remembered in the base class$self->updateCurrentFile("STATE", $state, "VERSION", $version, "ANNOTATION", $annotation);# update indexespush(@{$self->{_STATE}{$state}}, $index);push(@{$self->{_BRANCH}{$branch}}, $index) if ( $branch ne "" );push(@{$self->{_ANNOTATION}{$annotation}}, $index) if ( $annotation ne "" );}} # process#==============================================================================# getNumByState - Returns the number of items found by state#==============================================================================sub getNumByState{my $self = shift;my $state = shift;my $retval;if ( $state eq $StateCheckedIn ){$retval = $#{$self->{_STATE}{$StateCheckedIn}} + 1;}elsif ( $state eq $StateCheckedOut ){$retval = $#{$self->{_STATE}{$StateCheckedOut}} + 1;}elsif ( $state eq $StatePrivate ){$retval = $#{$self->{_STATE}{$StatePrivate}} + 1;}else{LogError("Clearcase::LsCmd::getNumByState Invalid State supplied");}return $retval;} # getNumByState#==============================================================================# getListByState - Returns a reference to an array of files by state#==============================================================================sub getListByState{my $self = shift;my $state = shift;my @retval;if ( $state eq $StateCheckedIn ){foreach my $index ( @{$self->{_STATE}{$StateCheckedIn}} ){push(@retval, $self->getElement($index)->{NAME});}}elsif ( $state eq $StateCheckedOut ){foreach my $index ( @{$self->{_STATE}{$StateCheckedOut}} ){push(@retval, $self->getElement($index)->{NAME});}}elsif ( $state eq $StatePrivate ){foreach my $index ( @{$self->{_STATE}{$StatePrivate}} ){push(@retval, $self->getElement($index)->{NAME});}}else{LogError("Clearcase::LsCmd::getListByState Invalid State supplied");}return \@retval;} # getListByState#==============================================================================# getNumBranches - Returns number of branches found#==============================================================================sub getNumBranches{my $self = shift;return scalar keys %{$self->{_BRANCH}};} # getNumBranches#==============================================================================# getListBranches - Returns a reference to an array of branches found#==============================================================================sub getListBranches{my $self = shift;my @retval;@retval = keys %{$self->{_BRANCH}};return \@retval;} # getListBranches#==============================================================================# getNumFilesByBranch - Returns the number of files associated to the supplied branch#==============================================================================sub getNumFilesByBranch{my $self = shift;my $branch = shift;my $retval = undef;if ( defined($branch) && defined($self->{_BRANCH}{$branch}) ){$retval = $#{$self->{_BRANCH}{$branch}} + 1;}return $retval;} # getNumFilesByBranch#==============================================================================# getListFilesByBranch - Returns a reference to an array of files found in the# supplied branch#==============================================================================sub getListFilesByBranch{my $self = shift;my $branch = shift;my @retval;if ( defined($branch) && defined($self->{_BRANCH}{$branch}) ){foreach my $index ( @{$self->{_BRANCH}{$branch}} ){push(@retval, $self->getElement($index)->{NAME});}}return \@retval;} # getListFilesByBranch#==============================================================================# getNumAnnotations - Returns number of Annotations found#==============================================================================sub getNumAnnotations{my $self = shift;return scalar keys %{$self->{_ANNOTATION}};} # getNumAnnotations#==============================================================================# getListAnnotations - Returns a reference to an array of Annotations found#==============================================================================sub getListAnnotations{my $self = shift;my @retval;@retval = keys %{$self->{_ANNOTATION}};return \@retval;} # getListAnnotations#==============================================================================# getNumFilesByAnnotation - Returns the number of files associated to the supplied Annotation# If supplied is all then it returns the total number of files with annotations#==============================================================================sub getNumFilesByAnnotation{my $self = shift;my $annotation = shift;my $retval = undef;if ( defined($annotation) ){if ( $annotation =~ /all/i ){$retval = 0;foreach my $annot ( keys %{$self->{_ANNOTATION}} ){$retval += $#{$self->{_ANNOTATION}{$annot}} + 1}}if ( defined($self->{_ANNOTATION}{$annotation}) ){$retval = $#{$self->{_ANNOTATION}{$annotation}} + 1;}}return $retval;} # getNumFilesByAnnotation#==============================================================================# getListFilesByAnnotation - Returns a reference to an array of files found# with the supplied Annotation#==============================================================================sub getListFilesByAnnotation{my $self = shift;my $annotation = shift;my @retval;if ( defined($annotation) && defined($self->{_ANNOTATION}{$annotation}) ){foreach my $index ( @{$self->{_ANNOTATION}{$annotation}} ){push(@retval, $self->getElement($index)->{NAME});}}return \@retval;} # getListFilesByAnnotation#==============================================================================# getNumIgnored# Returns the number of files ignored.#==============================================================================sub getNumIgnored{my $self = shift;return $self->{_IGNORECOUNT};} # getNumIgnored1;