Subversion Repositories DevTools

Rev

Rev 5710 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#! perl
########################################################################
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
#
# Module name   : jats.sh
# Module type   : Makefile system
# Compiler(s)   : n/a
# Environment(s): jats
#
# Description   : Locate naughty ClearCase views that have not been torn down
#                 Remove the views if they are older than specified days.
#
# Usage:
#
# Version   Who      Date        Description
#
#......................................................................#

require 5.006_001;
use strict;
use warnings;
#use Data::Dumper;
use Cwd;
use JatsError;
use Time::Local;
use Pod::Usage;                             # required for help support
use Getopt::Long;

my $VERSION = "1.0.0";                      # Update this
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
my $opt_help = 0;
my $opt_delete;
my $opt_age = 1;
my $opt_user;
my $opt_buildadm = 0;
my $opt_region = '';

my @vlist;
my $now = time;

#-------------------------------------------------------------------------------
# Function        : Mainline Entry Point
#
# Description     :
#
# Inputs          :
#
my $result = GetOptions (
            "help|h:+"          => \$opt_help,
            "manual:3"          => \$opt_help,
            "verbose|v:+"       => \$opt_verbose,
            "delete"            => \$opt_delete,
            "age=i"             => \$opt_age,
            "user=s"            => \$opt_user,
            "buildviews"        => \$opt_buildadm,
            "region=s"          => \$opt_region,

            );

            #
            #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
            #

#
#   Process help and manual options
#
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
pod2usage(-verbose => 1) if ($opt_help == 2 );
pod2usage(-verbose => 2) if ($opt_help > 2);
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV >= 0 );

#
#   Configure the error reporting process now that we have the user options
#
ErrorConfig( 'name'    =>'CC_TEARDOWN',
             'verbose' => $opt_verbose,
            );

Error ("-user and -buildviews are mutually exclusive")
    if ( $opt_user && $opt_buildadm );

#
#   Determine a search filter
#
if ( $opt_user )
{
    $opt_user = '^' . $opt_user;
}
else
{
    $opt_user = $ENV{USER} || '.*';
    $opt_user = '^' . $opt_user;
}

if ( $opt_buildadm )
{
    $opt_user = '_[0-9]{10,}_';
}

if ($opt_region)
{
    $opt_region = ' -region ' . $opt_region;
}

#
#   Scan for views
#
my $cmd = "cleartool lsview $opt_region";
Verbose2($cmd);
Verbose2("User: $opt_user");
open(SHOWCMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
while (<SHOWCMD>)
{
    #
    #   Filter output from the user
    #
    chomp;
    s~^\*~~;
    s~^\s+~~;
#    Verbose2 ("Data: $_");
#    next unless ( m~[0-9]{10}~ );
     next unless ( m~$opt_user~ );
#    next unless ( m~jzhou1_~ );
#    next unless ( m~_build_~ );
#    next unless ( m~buildadm_AUPERA~ );

    my @data = split (' ' );
    Verbose ("View: '$data[0]'");
    push @vlist, $data[0];
}
close(SHOWCMD);

#
#   Process views and determine information
#
foreach my $view ( @vlist )
{

    Verbose ("Process View: $view");
    my $uuid;
    my $view_tag_uuid;
    my $cmd = "cleartool lsview -age $opt_region $view";
    Verbose2($cmd);
    open(SHOWCMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
    my @text = <SHOWCMD>;
    close(SHOWCMD);

    chomp $text[1];

    my ($when, $who, $age);
    if ($text[1] =~ m~accessed ([^ ]+) by (.*)~)
    {
        $when = $1;
        $who = $2;
    }

    if ( $when )
    {
        $age =  age($when);
    }
    else
    {
        $age = 999999;
        $who = 'unknown';
        $when = 'unknown';
    }
    printf "%-20s(%3d) %50s, %s\n", $when, $age, $view, $who;

    if ( $opt_delete )
    {
        if ( $age < $opt_age )
        {
            print "Skip view. Too new\n";
        }
        else
        {
           ClearTool ("rmview -force -tag \"$view\"");

            #
            #   If the view tag still exists then delete the view the hard way
            #   Use 'lsview' to locate the views uuid
            #
            Verbose("Look for View Tag");
            my $cmd = "cleartool lsview -long \"$view\"";
            open(CMD, "$cmd 2>&1 |") || Error( "can't run command: $!");
            while (<CMD>)
            {
                #
                #   Filter output from the user
                #
                chomp;
                Verbose("lsview: $_");
                $uuid = $1 if ( m~^View uuid:\s+(.*)~ );
                $view_tag_uuid = $1 if ( m~View tag uuid(.*)~ );
            }
            close(CMD);

            if ( $uuid )
            {
                Warning ("Deleting view - the hard way");
                ClearTool( "--Quiet", "rmview -force -all -uuid $uuid" );
                ClearTool( "--Quiet", "unregister -view -uuid $uuid" );
                ClearTool( "--Quiet", "rmtag -view -all \"$view\"" );
            }
            elsif ($view_tag_uuid)
            {
                ClearTool( "--Quiet", "rmtag -view -all \"$view\"" );
            }
        }
    }
}

#-------------------------------------------------------------------------------
# Function        : ClearTool
#
# Description     : Issue a cleartool command
#                   Filter out many of the stupid messages
#
# Inputs          : Options and Command line
#                   Options:
#                       --Quiet     - Supress all command output
#
# Returns         : Error code
#
sub ClearTool
{
    my $quiet;

    #
    #   Scan for initial options
    #       --Quiet
    #
    if ( $_[0] eq '--Quiet' )
    {
        $quiet = 1;
        shift;
    }

    my $cmd = "cleartool @_";

    Verbose ("ClearTool: $cmd");
    open(CMD, "$cmd 2>&1 |") || Error "can't run command: $!";
    while (<CMD>)
    {
        #
        #   Filter output from the user
        #
        next if ( $quiet );
        unless ( $opt_verbose )
        {
            next if ( m~Making dir~ );
            next if ( m~End dir~ );
            next if ( m~Processing dir~ );
            next if ( m~Error~ );
        }
        print $_;
    }
    close(CMD);

    Verbose2 "ClearTool Exit Status: $?";
    return $? / 256;
}


#-------------------------------------------------------------------------------
# Function        : age
#
# Description     : Convert a clearcase date into an age. Days ago
#
# Inputs          : $when           - CC date
#
# Returns         : Days ago
#

sub age
{
    my ($when) = @_;

    $when =~ m~(\d+)-(\d+)-(\d+)~;
    my $mday = $3;
    my $mon = $2 - 1;
    my $year = $1;

    my $age = timelocal(0,0,0,$mday,$mon,$year);
    my $delta = int( ($now - $age) / ( 60 * 60 * 24 ));

#    my $rev = localtime( $age );

    return $delta;
}

#-------------------------------------------------------------------------------
#   Documentation
#

=pod

=head1 NAME

jats cc_tear_down - Tear down old clearcase views

=head1 SYNOPSIS

  jats etool cc_tear_down [options]

 Options:
    -help[=n]           - brief help message
    -help -help         - Detailed help message
    -man[=n]            - Full documentation
    -verbose[=n]        - Verbose operation
    -delete             - Delete the views. Default is to list.
    -age=nn             - Only older than nn days (default1 1)
    -user=text          - Only a users views. default current user
    -buildviews         - Only views created by the build daemon
    -region=region      - Specify ClearCase Region

=head1 OPTIONS

=over 8

=item B<-help[=n]>

Print a brief help message and exits.

The verbosity of the help text can be controlled by setting the help level to a
number in the range of 1 to 3, or by invoking the option multiple times.

=item B<-man[=n]>

Without a numeric argument this is the same as -help=3. Full help will be
displayed.

With a numeric argument, this option is the same as -help=n.

=item B<-verbose[=n]>

This option will increase the level of verbosity of the utility.

If an argument is provided, then it will be used to set the level, otherwise the
existing level will be incremented. This option may be specified multiple times.

=item B<-delete>

This optio will cause the listed views to be deleted.

By default the views are not deleted.

=item B<-age=nn>

Only consider views that are older than 'nn' days.

=item B<-user=text>

Only consider views for a specified user. The default value is to use the
name of the current user. It does assume that the views are in the form
created by JATS.

The text is an anchored regular expression. It can be used in many ways to limit
the views listed.

JATS will create views in a well defined form that contains:

=over 8

=item * The user name

=item * The name of the computer on which the view is created

=item * The package name and version on which the view is based

=item * The type of view.

If a sandbox view, then then name of then sandbox is also used.

=back

ie: SomeUser_auperawsXXX_sandbox.SandBoxName_PackageName_PackageVersion

Examples

=over 8

=item * -user=SomeUser_

List views that were created by 'SomeUser'.

=item * -user=SomeUser_auperawsXXX

List views that were created by 'SomeUser' on the machine 'auperawsXXX'.

=back

=item B<-buildviews>

This option will limit the utility to views created by various build tools.
These have a special 10 digit number sequence in the name.

=back

=head1 DESCRIPTION

This utility is used to locate and tear down old Clear Case views. You may need
to be the VOB owner to do this.

=cut