File Coverage

blib/lib/ClearCase/Attache.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package ClearCase::Attache;
2            
3 1     1   677 use strict;
  1         2  
  1         33  
4            
5 1     1   4 use Carp;
  1         2  
  1         97  
6 1     1   693 use Symbol;
  1         839  
  1         54  
7 1     1   6556 use Win32;
  0            
  0            
8             use vars qw ($VERSION $ATTCMD $AUTOLOAD);
9             #
10             $VERSION = '0.01';
11             #
12             $ATTCMD="C:\\Program Files\\Rational\\Attache\\bin\\attcmd.exe";
13             $ATTCMD=((-x $ATTCMD )? $ATTCMD: pathfind('attcmd.exe'));
14            
15             #============
16             #==METHODS===
17             #============
18             # Constructor
19             sub new {
20             my($pkg,$ws,$attache)=(@_);
21             my $self = {};
22             #
23             carp( "Workspace needed") unless $ws;
24             $self->{_WS_}=$ws;
25             #
26             if ($attache) {
27             carp("no $attache or not executable")
28             unless -x $attache;
29             } else {
30             carp("ATTACHE not specified and no default exists")
31             unless -x $ATTCMD;
32             $attache=$ATTCMD;
33             }
34             $self->{_ATTCMD_}=Win32::GetShortPathName($attache);
35             #
36             bless $self,$pkg;
37             }
38             # If we want to use a log file.
39             sub setlog {
40             my($self,$logfile,$append)=(@_);
41             if($logfile) {
42             my $h=gensym();
43             open($h,($append? '>>' : '>'),$logfile)
44             or (carp("Opening $logfile: $!"),return);
45             $self->{_LOG_}=$logfile;
46             print $h "***Start logging at:", scalar(localtime()),"\n";
47             close $h; # Needed on windoze to preserve the log file.
48             } else {
49             delete $self->{_LOG_};
50             }
51             $logfile;
52             }
53             # maps workspace to physical location
54             sub vault {
55             my($self)=(@_);
56             my $ws=$self->{_WS_};
57             $self->lsws();
58            
59             foreach my $l ($self->lastoutput()) {
60             next if ($l=~/^Workspace name/);
61             $l=~s/^\s+//;
62             $l=~s/^\*\s*//;
63             my ($ows,$locdir,$host)=(split(/\s+/,$l));
64             return $locdir if ($ows eq $ws);
65             }
66             return;
67             }
68             # result of the latest command
69             sub lastoutput {
70             my($self)=(@_);
71             @{ $self->{_OUT_} };
72             }
73             # workspace accessors
74             sub getWs {
75             $_[0]->{_WS_};
76             }
77            
78             sub setWs {
79             $_[0]->{_WS_}=$_[1];
80             }
81            
82             # error flag
83             sub hasErrors {
84             $_[0]->{_HASERRORS_}? 1: 0;
85             }
86             # error messages
87             sub errors {
88             @{$_[0]->{_ERR_}};
89             }
90             # warning flags
91             sub hasWarnings {
92             $_[0]->{_HASWARNINGS_}? 1: 0;
93             }
94             #warning content
95             sub warnings {
96             @{$_[0]->{_WARN_}};
97             }
98             # run an arbitrary attache command
99             sub runcmd {
100             my($self,$args)=(@_);
101             my($ws)=($self->{_WS_});
102            
103             my($h)=(gensym()); #from Symbol
104             my $cmd="$self->{_ATTCMD_} -ws $ws $args"; #No quotes, we used getshort..
105             # get logfile
106             my $log=gensym();
107             if (exists $self->{_LOG_}) {
108             my $logfile=$self->{_LOG_};
109             open($log,'>>',$logfile)
110             or (carp("Opening $logfile: $!"),$log=undef());
111             }
112             $log && (print $log "$cmd\n");
113             open($h,"-|",$cmd) or
114             (carp("$! while invoking: $cmd"),return);
115             #
116             my($out,$err,$warn);
117             $out=[];
118             $err=[];
119             $warn=[];
120             $self->{_ERR_} =undef;
121             $self->{_WARN_}=undef;
122             $self->{_HASERRORS_} =0;
123             $self->{_HASWARNINGS_}=0;
124             $self->{_OUT_} =undef;
125             #
126             while(<$h>) {
127             next if /^Ready/;
128             next if /^Setting workspace to/;
129             chomp;
130             substr($_,-1)=undef if(substr($_,-1) eq "\r");
131             $log && (print $log '# ',$_,"\n");
132             if (/Error:/) {
133             push @{$err},$_ ;
134             $self->{_HASERRORS_}++;
135             } elsif(/Warning:/) {
136             push @{$warn},$_ ;
137             $self->{_HASWARNINGS_}++;
138             } else {
139             push @{$out},$_;
140             }
141             }
142             close $h;
143             $log && close $log;
144            
145             $self->{_ERR_}=$err if {$#{$err}>= 0};
146             $self->{_WARN_}=$warn if {$#{$warn}>=0};
147             $self->{_OUT_}=$out;
148             1;
149             }
150             # Delegates everything to runcmd
151             sub AUTOLOAD {
152             my($self,$args)=(@_);
153             my($cmd);
154            
155             ($cmd=$AUTOLOAD)=~s/.*:://;
156             $self->runcmd("$cmd $args");
157             }
158            
159             sub DESTROY {} #avoids AUTOLOAD on destroy
160             #=============
161             #==UTILITIES==
162             #=============
163            
164             sub pathfind {
165             my($f)=(@_);
166             my($sep)=(($^O=~/mswin/i)?';':':');
167             foreach my $dir (split($sep,$ENV{PATH})) {
168             return "$dir/$f" if (-x "$dir/$f" );
169             }
170             return
171             }
172            
173             #========
174             #==OVER==
175             #========
176             1;
177             __END__