Removed /usr/local from CDPATH
[clearscm.git] / test / testclearcase.pl
1 #!/usr/bin/env cqperl
2
3 =pod
4
5 =head1 NAME $RCSfile: testclearcase.pl,v $
6
7 Test Clearcase
8
9 =head1 VERSION
10
11 =over
12
13 =item Author
14
15 Andrew DeFaria <Andrew@ClearSCM.com>
16
17 =item Revision
18
19 $Revision: 2.1 $
20
21 =item Created:
22
23 Tue Apr 10 13:14:15 CDT 2007
24
25 =item Modified:
26
27 $Date: 2011/01/09 01:01:32 $
28
29 =back
30
31 =head1 SYNOPSIS
32
33  Usage: testclearcase.pl: [-us|age] [-ve|rbose]
34                           [-c|onfig <file>] [-b|ase] [-uc|m]
35
36  Where:
37    -v|erbose:       Display progress output
38    -d|ebug:         Display debug info
39    -us|age:         Display usage
40
41    -c|onfig <file>: Config file (Default: testclearcase.conf)
42    -[no]b|ase:      Perform base Clearcase tests (Default: base)
43    -[no]uc|m:       Perform UCM Clearcase tests (Default: noucm)
44    -[no]clean:      Cleanup after yourself (Default: clean)
45
46 =head1 DESCRIPTION  
47
48 Clearcase smoke tests. Perform simple Clearcase operations to validate that
49 Clearcase minimally works.
50
51 If -ucm is specified then additional UCM related tests are performed.
52
53 =cut
54
55 use strict;
56 use warnings;
57
58 use Cwd;
59 use FindBin;
60 use Getopt::Long;
61 #use Term::ANSIColor qw(:constants);
62
63 use lib "$FindBin::Bin/../lib";
64
65 use Clearcase;
66 use Clearcase::Element;
67 use Clearcase::View;
68 use Clearcase::Views;
69 use Clearcase::Vob;
70 use Clearcase::Vobs;
71
72 use Clearcase::UCM;
73 use Clearcase::UCM::Activity;
74 use Clearcase::UCM::Baseline;
75 use Clearcase::UCM::Component;
76 use Clearcase::UCM::Folder;
77 use Clearcase::UCM::Project;
78 use Clearcase::UCM::Pvob;
79 use Clearcase::UCM::Stream;
80
81 use DateUtils;
82 use Display;
83 use GetConfig;
84 use Logger;
85 use OSDep;
86 use TimeUtils;
87 use Utils;
88
89 # Globals
90 my $VERSION = '2.1';
91
92 my (
93   $test_vob,
94   $test_view,
95   $test_pvob,
96   $test_folder,
97   $test_project,
98   $test_activity,
99   $test_baseline,
100   $test_component,,
101   $test_devstream,
102   $test_intstream,
103   $test_devview,
104   $test_intview,
105 );
106
107 my (%default_opts, %opts);
108
109 my ($script) = ($FindBin::Script =~ /^(.*)\.pl/);
110
111 my $log = Logger->new;
112
113 # LogOpts: Log the %opts has to the log file so we can tell the options used for
114 # this run.
115 sub LogOpts() {
116   $log->msg(
117     "$script v$VERSION run at " 
118   . YMDHM
119   . ' with the following options:'
120   );
121
122   for (sort keys %opts) {
123     if (ref $opts{$_} eq 'ARRAY') {
124       my $name = $_;
125       $log->msg("$name:\t$_") for @{$opts{$_}};
126     } else {
127       $log->msg("$_:\t$opts{$_}");
128     }  # if
129   } # for
130
131   return;
132 } # LogOpts
133
134 sub CreateVob($) {
135   my ($tag) = @_;
136
137   my $vobname = Clearcase::vobname $tag;
138
139   $log->msg ("Creating vob $tag");
140
141   my $newvob = Clearcase::Vob->new($tag);
142
143   my ($status, @output) = $newvob->create($opts{vobhost}, "$opts{vobstore}/$vobname.vbs");
144
145   $log->log($_) for @output;
146
147   return ($status, $newvob);
148 } # CreateVob
149
150 sub CreatePvob($) {
151   my ($tag) = @_;
152
153   my $vobname = Clearcase::vobname $tag;
154
155   my $pvob = Clearcase::UCM::Pvob->new($tag);
156
157   #my ($status, @output) = $pvob->create($opts{vobhost}, "$opts{vobstore}/$vobname.vbs", 'A test Pvob');
158   my ($status, @output) = $pvob->create($opts{vobhost}, "$opts{vobstore}/$vobname.vbs");
159
160   $log->log($_) for @output;
161
162   return ($status, $pvob);
163 } # CreatePvob
164
165 sub MountVob($) {
166   my ($vob) = @_;
167
168   $log->msg('Mounting vob ' . $vob->tag);
169
170   # Create mount directory
171   my ($status, @output);
172
173   ($status, @output) = Execute 'mkdir -p ' . $vob->tag . ' 2>&1' unless -d $vob->tag;
174
175   $log->log($_) for @output;
176
177   ($status, @output) = $vob->mount;
178
179   $log->log($_) for @output;
180
181   return $status;
182 } # MountVob
183
184 sub DestroyVob($) {
185   my ($vob) = @_;
186
187   my ($status, @output);
188
189   ($status, @output) = $Clearcase::CC->execute('cd');
190
191   $log->msg('Unmounting vob ' . $vob->tag);
192
193   ($status, @output) = $vob->umount;
194
195   $log->msg('Removing vob ' . $vob->tag);
196
197   ($status, @output) = $vob->remove;
198
199   $log->log($_) for @output;
200
201   return $status;
202 } # DestroyVob
203
204 sub CreateView($) {
205   my ($tag) = @_;
206
207   $log->msg("Creating view $tag");
208
209   my $view = Clearcase::View->new($tag);
210
211   my ($status, @output) = $view->create($opts{viewhost}, "$opts{viewstore}/$tag.vws");
212
213   $log->log($_) for @output;
214
215   return ($status, $view);
216 } # CreateView
217
218 sub SetView($) {
219   my ($view) = @_;
220
221   $log->msg('Setting view ' . $view->tag);
222
223   my ($status, @output) = $view->set;
224
225   $log->log($_) for @output;
226
227   return $status;
228 } # SetView
229
230 sub DestroyView($) {
231   my ($view) = @_;
232
233   $log->msg('Removing view ' . $view->tag);
234
235   my ($status, @output) = $Clearcase::CC->execute('cd');
236
237   $log->log($_) for @output;
238
239   chdir $ENV{HOME}
240     or $log->err("Unable to chdir $ENV{HOME}", 1);
241
242   ($status, @output) = $view->remove;
243
244   $log->log($_) for @output;
245
246   return $status;
247 } # DestroyView
248
249 sub CreateViewPrivateFiles(@) {
250   my (@elements) = @_;
251
252   $log->msg('Creating test files');
253
254   for (@elements) {
255     my $file;
256
257     $log->msg("Creating $_");
258
259     open $file, '>>', $_
260       or $log->err("Unable to open $_ for writing - $!", 1);
261
262     print $file "This is file $_\n";
263
264     close $file;
265   } # for
266
267   return;
268 } # CreateViewPrivateFiles
269
270 sub CheckOut($) {
271   my ($element) = @_;
272
273   my ($status, @output);
274
275   if (ref $element eq 'ARRAY') {
276     for (@{$element}) {
277       $log->msg("Checking out $_");
278
279       my $newElement = Clearcase::Element->new($_);
280
281       ($status, @output) = $newElement->checkout;
282
283       $log->log($_) for @output;
284
285       $log->err("Unable to check out $_", $status) if $status;
286     } # for
287   } else {
288     $log->msg("Checking out $element");
289
290     my $newElement = Clearcase::Element->new($element);
291
292     ($status, @output) = $newElement->checkout;
293
294     $log->log($_) for @output;
295
296     $log->err("Unable to check out $element", $status) if $status;
297   } # if
298
299   return;
300 } # CheckOut
301
302 sub CheckIn($) {
303   my ($element) = @_;
304
305   my ($status, @output);
306
307   if (ref $element eq 'ARRAY') {
308     for (@{$element}) {
309       $log->msg("Checking in $_");
310
311       my $newElement = Clearcase::Element->new($_);
312
313       ($status, @output) = $newElement->checkin;
314
315       $log->log($_) for @output;
316
317       $log->err("Unable to check in $_", $status) if $status;
318     } # for
319   } else {
320     $log->msg("Checking in $element");
321
322     my $newElement = Clearcase::Element->new($element);
323
324     ($status, @output) = $newElement->checkin;
325
326     $log->log($_) for @output;
327
328     $log->err("Unable to check in $element", $status) if $status;
329   } # if
330
331   return;
332 } # CheckIn
333
334 sub ComparingFiles(@) {
335   my (@elements) = @_;
336
337   for (@elements) {
338     my @lines = ReadFile $_;
339
340     $log->err("Element $_ should contain only two lines", 2) if scalar @lines != 2;
341   } # for
342
343   return;
344 } # ComparingFiles
345
346 sub MakeElements(@) {
347   my (@elements) = @_;
348
349   for (@elements) {
350     $log->msg("Mkelem $_");
351
352     my $newElement = Clearcase::Element->new($_);
353
354     my ($status, @output) = $newElement->mkelem;
355
356     $log->log($_) for @output;
357
358     $log->err("Unable to make $_ an element", $status) if $status;
359   } # for
360
361   return;
362 } # MakeElements
363
364 sub RunTests() {
365   # Simple tests:
366   #
367   #   . Create a few elements
368   #   . Check them in
369   #   . Check them out
370   #   . Modify them
371   #   . Check them in
372   #
373   # Assumptions:
374   #
375   #   . $vob_tag is already created
376   #   . $view_tag is already created
377   #   . View is set and we are in the vob
378   #   . There are no vob elements for @elements
379   my @elements = (
380     'cctest.h',
381     'ccsetup.c',
382     'cctest.c',
383     'Makefile',
384   );
385
386   $log->msg("$script: Start Base Clearcase Tests");
387   $log->msg('Removing test files');
388
389   unlink $_ for @elements;
390
391   $log->msg('Creating view private files');
392
393   CreateViewPrivateFiles @elements;
394
395   $log->msg('Making elements');
396
397   CheckOut      '.';
398   MakeElements  @elements;
399   CheckIn       \@elements;
400   CheckIn       '.';
401
402   $log->msg('Checking out files');
403
404   CheckOut \@elements;
405
406   $log->msg('Modifying files');
407
408   CreateViewPrivateFiles @elements;
409
410   $log->msg('Checking in files');
411
412   CheckIn \@elements;
413
414   $log->msg('Comparing files');
415
416   ComparingFiles @elements;
417
418   $log->msg("$script: End Base Clearcase Tests");
419
420   return 0;
421 } # RunTests
422
423 sub Cleanup(;$$$) {
424   my ($view, $vob) = @_;
425
426   my $status = 0;
427
428   $log->msg('Cleaning up');
429
430   if ($view && $view->exists) {
431     $status += DestroyView($view);
432   } # if
433
434   if ($vob && $vob->exists) {
435     $status += DestroyVob($vob);
436   } # if
437
438   return $status;
439 } # Cleanup
440
441 sub CleanupUCM() {
442   my ($rc, $status, @output);
443
444   $log->msg('Removing ' . $test_activity->name);
445
446   ($rc, @output) = $test_activity->remove;
447
448   $status += $rc;
449   
450   $log->log($_) for @output;
451
452   # Need to remove baselines from streams first using rebase (Devstream)
453   $log->msg('Rebasing ' . $test_devstream->name . ' to remove baseline');
454
455   $status += RebaseStream(
456     $test_devstream,
457     ' -dbaseline ' . $test_baseline->name . '@' . $test_baseline->pvob->tag .
458     ' -view '      . $test_devview->name  . ' -complete',
459   );
460
461   # Change intstream to not have a recommended baseline
462   $log->msg('Changing ' . $test_intstream->name . ' to remove recommended baseline');
463
464   ($rc, @output) = $test_intstream->nrecommended;
465
466   $status += $rc;
467
468   $log->log($_) for @output;
469
470   $status += DestroyView($test_devview);
471
472   $log->msg('Removing ' . $test_baseline->name);
473
474   ($rc, @output) = $test_baseline->remove;
475
476   $status += $rc;
477
478   $log->log($_) for @output;
479
480   $log->msg('Rebasing ' . $test_intstream->name . ' to remove INITIAL baseline');
481
482   $status += RebaseStream(
483     $test_intstream,
484     ' -dbaseline tc.component_INITIAL' . '@' . $test_intstream->pvob->tag .
485     ' -view ' . $test_intview->name    . ' -complete',
486   );
487
488   $log->msg('Removing ' . $test_component->name . ' from ' . $test_project->name);
489
490   ($rc, @output) = $test_project->change(
491     '-dmodcomp ' . $test_component->name . '@' . $test_project->pvob->tag
492   );
493
494   $status += $rc;
495
496   $log->log($_) for @output;
497
498   $log->msg('Removing ' . $test_component->name);
499
500   ($rc, @output) = $test_component->remove;
501
502   $status += $rc;
503
504   $log->log($_) for @output;
505
506   $status += DestroyView($test_intview);
507   
508   $log->msg('Removing '. $test_devstream->name);
509
510   ($rc, @output) = $test_devstream->remove;
511
512   $status += $rc;
513
514   $log->log($_) for @output;
515
516   $log->msg('Removing ' . $test_intstream->name);
517
518   ($rc, @output) = $test_intstream->remove;
519
520   $status += $rc;
521
522   $log->log($_) for @output;
523
524   $log->msg('Removing ' . $test_project->name);
525
526   ($rc, @output) = $test_project->remove;
527
528   $status += $rc;
529
530   $log->log($_) for @output;
531
532   $log->msg('Removing ' . $test_folder->name);
533
534   ($rc, @output) = $test_folder->remove;
535
536   $status += $rc;
537
538   $log->log($_) for @output;
539
540   $log->msg('Removing ' . $test_pvob->name);
541
542   ($rc, @output) = DestroyVob($test_pvob);
543
544   $log->log($_) for @output;
545
546   return $status;
547 } # CleanupUCM
548
549 sub SetupTest($$) {
550   my ($vob_tag, $view_tag) = @_;
551
552   my ($status, @output);
553
554   $log->msg('Setup test environment');
555
556   my $view = Clearcase::View->new($view_tag);
557
558   if ($view->exists) {
559     $log->msg('Removing old view ' . $view_tag);
560
561     ($status, @output) = $view->remove;
562
563     $log->err('Unable to remove old view ' . $view->tag, $status) if $status;
564   } # if
565
566   ($status, $test_view) = CreateView($view_tag);
567
568   return $status if $status != 0;
569
570   $status = $test_view->start;
571
572   my $vob = Clearcase::Vob->new($vob_tag);
573
574   if ($vob->exists) {
575     $log->msg('Removing old vob ' . $vob_tag);
576
577     ($status, @output) = DestroyVob($vob);
578
579     $log->err('Unable to remove old vob '. $vob->tag, $status) if $status;
580   } # if
581
582   ($status, $test_vob) = CreateVob($vob_tag);
583
584   return $status if $status != 0;
585
586   $status = MountVob($test_vob);
587
588   return $status if $status != 0;
589
590   my $dir = $Clearcase::VIEWTAG_PREFIX . '/' . $test_view->tag . $test_vob->tag;
591
592   chdir $dir
593     or $log->err("Unable to chdir to $dir", ++$status);
594
595   ($status, @output) = $Clearcase::CC->execute("cd $dir");
596
597   if ($status != 0) {
598     $log->log($_) for @output;
599   } # if
600
601   return $status;
602 } # SetupTest
603
604 sub SetupUCMTest() {
605   my $status;
606
607   $log->msg("Creating UCM Pvob $Clearcase::VOBTAG_PREFIX/tc.pvob");
608
609   ($status, $test_pvob) = CreatePvob("$Clearcase::VOBTAG_PREFIX/tc.pvob"); 
610
611   return $status;
612 } # SetupUCMTest
613
614 sub CreateUCMProject() {
615   # Get the root folder to put this project into (may create folders later)
616   $test_folder = Clearcase::UCM::Folder->new('tc.folder', $test_pvob);
617
618   $test_project = Clearcase::UCM::Project->new('tc.project', $test_folder, $test_pvob);
619
620   $test_project->remove if $test_project->exists;
621  
622   $log->msg('Creating UCM Project tc.project');
623
624   my ($status, @output) = $test_project->create;
625
626   $log->log($_) for @output;
627
628   return $status;
629 } # CreateUCMProject
630
631 sub CreateUCMIntStream() {
632   $test_intstream = Clearcase::UCM::Stream->new('tc.intstream', $test_pvob);
633
634   $log->msg('Creating UCM Stream tc.intstream');
635
636   my ($status, @output) = $test_intstream->create($test_project, '-integration');
637
638   $log->log($_) for @output;
639
640   return $status;
641 } # CreateUCMIntStream
642
643 sub CreateUCMDevStream() {
644   $test_devstream = Clearcase::UCM::Stream->new('tc.devstream', $test_pvob);
645
646   $log->msg('Creating UCM Stream tc.devstream');
647
648   my ($status, @output) = $test_devstream->create($test_project);
649
650   $log->log($_) for @output;
651
652   return $status;
653 } # CreateUCMDevStream
654
655 sub CreateUCMComponent() {
656   $test_component = Clearcase::UCM::Component->new('tc.component', $test_pvob);
657
658   $log->msg('Creating UCM Component tc.component');
659
660   my ($status, @output) = $test_component->create(
661     "$Clearcase::VIEWTAG_PREFIX/" . $test_intview->tag . $test_vob->tag
662   );
663
664   $log->log($_) for @output;
665
666   return $status;
667 } # CreateUCMComponent
668
669 sub AddModifiableComponent() {
670   my ($status, @output) = $Clearcase::CC->execute(
671     'chproj -nc -amodcomp ' . $test_component->name . '@' . $test_pvob->tag .
672     ' '                     . $test_project->name   . '@' . $test_pvob->tag
673   );
674
675   $log->log($_) for @output;
676
677   return $status;
678 } # AddModifiableCOmponent
679
680 sub CreateUCMIntView() {
681   $log->msg("Creating UCM Int View tc.intview");
682
683   $test_intview = Clearcase::View->new('tc.intview');
684
685   my ($status, @output) = $test_intview->create(
686     $opts{viewhost}, "$opts{viewstore}/tc.intview.vws",
687     '-stream ' . $test_intstream->name . '@' . $test_pvob->tag
688   );
689
690   $log->log($_) for @output;
691
692   $test_intview->start unless $status;
693
694   return $status;
695 } # CreateUCMIntView
696
697 sub CreateUCMDevView() {
698   $log->msg("Creating UCM Dev View tc.devview");
699
700   $test_devview = Clearcase::View->new('tc.devview');
701
702   my ($status, @output) = $test_devview->create(
703     $opts{viewhost}, "$opts{viewstore}/tc.devview.vws",
704     '-stream ' . $test_devstream->name . '@' . $test_pvob->tag
705   );
706
707   $log->log($_) for @output;
708
709   $test_devview->start unless $status;
710
711   return $status;
712 } # CreateUCMDevView
713
714 sub CreateUCMBaseline() {
715   $test_baseline = Clearcase::UCM::Baseline->new('tc.baseline', $test_pvob);
716
717   $log->msg('Creating UCM Baseline tc.baseline');
718
719   my ($status, @output) = $test_baseline->create($test_intview, undef, '-identical');
720
721   $log->log($_) for @output;
722
723   return $status;
724 } # CreateUCMBaseline
725
726 sub CreateUCMActivity() {
727   $test_activity = Clearcase::UCM::Activity->new('tc.activity', $test_pvob);
728
729   $log->msg('Creating UCM Activity tc.activity');
730
731   my ($status, @output) = $test_activity->create($test_devstream, 'A UCM Test Activity');
732
733   $log->log($_) for @output;
734
735   return $status;
736 } # CreateUCMActivity
737
738 sub RebaseStream($$) {
739   my ($stream, $opts) = @_;
740
741   my ($status, @output) = $stream->rebase($opts);
742
743   $log->log($_) for @output;
744
745   return $status;
746 } # RebaseStream
747
748 sub RecommendBaseline($$) {
749   my ($stream, $baseline) = @_;
750
751   my ($status, @output) = $stream->recommend($baseline);
752
753   $log->log($_) for @output;
754
755   return $status;
756 } # RecommentBaseline
757
758 sub RunUCMTests() {
759   my $status = 0;
760
761   $log->msg("$script: Start UCM Clearcase Tests");
762
763   $status += CreateUCMProject;
764   $status += CreateUCMIntStream;
765   $status += CreateUCMDevStream;
766   $status += CreateUCMIntView;
767   $status += CreateUCMDevView;
768   $status += CreateUCMComponent;
769   $status += AddModifiableComponent;
770   $status += RebaseStream($test_intstream, '-baseline tc.component_INITIAL -complete');
771   $status += RecommendBaseline($test_intstream, 'tc.component_INITIAL');
772   $status += CreateUCMBaseline;
773   $status += RebaseStream($test_devstream, '-baseline tc.baseline -complete');
774   $status += RecommendBaseline($test_devstream, 'tc.baseline');
775   $status += CreateUCMActivity;
776
777   $log->msg("$script: End UCM Clearcase Tests");
778
779   return $status;
780 } # RunUCMTests
781
782 ## Main
783 my $startTime = time;
784 my $conf_file = "$FindBin::Bin/$script.conf";
785 my $status    = 0;
786
787 $opts{base}  = 1;
788 $opts{clean} = 1;
789
790 GetOptions(
791   \%opts,
792   'verbose' => sub { set_verbose },
793   'debug'   => sub { set_debug },
794   'usage'   => sub { Usage },
795   'config=s',
796   'base!',
797   'ucm!',
798   'clean!',
799 ) or Usage;
800
801 # Read the config file
802 if (-f $conf_file) {
803   %default_opts = GetConfig $conf_file;
804 } else {
805   $log->err("Unable to find config file $conf_file", 1);
806 } # if
807
808 # Overlay default opts if not specified
809 for (keys %default_opts) {
810   $opts{$_} = $default_opts{$_} if !$opts{$_};
811 } # for
812
813 $log->msg("$script: Start");
814
815 LogOpts;
816
817 # Since we are creating private vobs (to avoid complications with having to
818 # know and code the registry password when making public vobs), we'll simply
819 # change $Clearcase::VOBTAG_PREFIX
820 $Clearcase::VOBTAG_PREFIX = $ENV{TMP} || '/tmp';
821
822 if ($opts{base}) {
823   $status = SetupTest "$Clearcase::VOBTAG_PREFIX/tc.vob", 'tc.view';
824
825   if ($status == 0) {
826     $status += RunTests;
827   } else {
828     $log->err('Tests not run. Failure occurred in SetupTest - check logfile');
829   } # if
830
831   # Note if we are doing UCM tests then we need the view and vob here...
832   $status += Cleanup($test_view, $test_vob) if $opts{clean} and !$opts{ucm};
833
834   if ($status != 0) {
835     $log->err("$script: Failed (Base Clearcase)");
836   } else {
837     $log->msg("$script: Passed (Base Clearcase)");
838   } # if
839 } # if
840
841 if ($opts{ucm}) {
842   $status = SetupUCMTest;
843
844   if ($status == 0) {
845     $status += RunUCMTests;
846   } else {
847     $log->err('UCM Tests not run. Failure occurred in SetupUCMTest - check logfile');
848   } # if
849
850   if ($opts{clean}) {
851     $status += CleanupUCM;
852     $status += Cleanup($test_view, $test_vob);
853   } # if
854
855   if ($status != 0) {
856     $log->err("$script: Failed (UCM Clearcase)");
857   } else {
858     $log->msg("$script: Passed (UCM Clearcase)");
859   } # if
860 } # if
861
862 display_duration $startTime, $log;
863
864 $log->msg("$script: End");
865
866 exit $status;
867
868 =pod
869
870 =head1 CONFIGURATION AND ENVIRONMENT
871
872 DEBUG: If set then $debug is set to this level.
873
874 VERBOSE: If set then $verbose is set to this level.
875
876 TRACE: If set then $trace is set to this level.
877
878 =head1 DEPENDENCIES
879
880 =head2 Perl Modules
881
882 L<Cwd>
883
884 L<FindBin>
885
886 L<Getopt::Long|Getopt::Long>
887
888 L<Term::ANSIColor|Term::ANSIColor>
889
890 =head2 ClearSCM Perl Modules
891
892 =begin man 
893
894  Clearcase
895  Clearcase::Element
896  Clearcase::View
897  Clearcase::Views
898  Clearcase::Vob
899  Clearcase::Vobs
900  DateUtils
901  Display
902  GetConfig
903  Logger
904  OSDep
905  Utils
906
907 =end man
908
909 =begin html
910
911 <blockquote>
912 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase.pm">Clearcase</a><br>
913 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/Element.pm">Element</a><br>
914 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/View.pm">View</a><br>
915 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/Views.pm">Views</a><br>
916 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/Vob.pm">Vob</a><br>
917 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/Vobs.pm">Vobs</a><br>
918 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM.pm">UCM</a><br>
919 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM/Activity.pm">Activity</a><br>
920 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM/Baseline.pm">Baseline</a><br>
921 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM/Component.pm">Component</a><br>
922 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM/Project.pm">Project</a><br>
923 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM/Pvob.pm">Pvob</a><br>
924 <a href="http://clearscm.com/php/scm_man.php?file=lib/Clearcase/UCM/Stream.pm">Stream</a><br>
925 <a href="http://clearscm.com/php/scm_man.php?file=lib/DateUtils.pm">DateUtils</a><br>
926 <a href="http://clearscm.com/php/scm_man.php?file=lib/Display.pm">Display</a><br>
927 <a href="http://clearscm.com/php/scm_man.php?file=lib/GetConfig.pm">GetConfig</a><br>
928 <a href="http://clearscm.com/php/scm_man.php?file=lib/Logger.pm">Logger</a><br>
929 <a href="http://clearscm.com/php/scm_man.php?file=lib/OSDep.pm">OSDep</a><br>
930 <a href="http://clearscm.com/php/scm_man.php?file=lib/Utils.pm">Utils</a><br>
931 </blockquote>
932
933 =end html
934
935 =head1 BUGS AND LIMITATIONS
936
937 There are no known bugs in this script
938
939 Please report problems to Andrew DeFaria <Andrew@ClearSCM.com>.
940
941 =head1 LICENSE AND COPYRIGHT
942
943 Copyright (c) 2010, ClearSCM, Inc. All rights reserved.
944
945 =cut