#! /usr/bin/env python
# $Id: //guest/thomas_quinot/perforce/utils/metrics/treemetrics.py#1 $
##
## Written by Scott Pasnikowski around the time of 4/22/99
## @symantec corp. Home of the Norton utilities
##
## Under duress of pesky QA people...
##
## This comes with no guarantee whatsoever... on any level.
##
## Consider this to be under the linux type liscense thingy
## ( Don't recall what its called GNU or copyleft or whatever )
## and if anyone complains my manager du jour said I could give it away.
## ( he really did )
##
import sys, os, string, re
def extract_metrics_counts_file( depot_root, label_one, label_two ):
# Does a p4 changes depot_root@label_one depot_root@label_two
# depot_root is used to limit the diff range to a single "project"
# or some subset even smaller..
# we then parse the output and add up the totals
command = 'p4 diff2 ' + depot_root + label_one + ' ' + depot_root + label_two
debug = 0
files_added = 0
files_deleted = 0
files_typechange = 0
files_changed = 0
revisions_added = 0
file_count1 = 0
file_count2 = 0
# fyi
sys.stdout.write('Start point ' + label_one + ' End Point ' + label_two + '\n' )
sys.stdout.write('Depot Range ' + depot_root + '\n\n' )
# Only process the lines that list filespec1 - filespec2
expMain = re.compile( r'^====' )
# If the first file is missing it will show up as the following
expMissingFirst = re.compile( r'< none >' )
# If the second file is missing is will show up as ( notice missing spaces)
expMissingSecond = re.compile( r'<none>' )
# special case of no second file
exp1 = re.compile( r' - <' )
# in all other cases this is the separator
exp2 = re.compile( r' - //' )
# We will use the # to split the file spec from the revision number
exp3 = re.compile( r'#' )
spaceExp = re.compile( r' ' )
for line in os.popen( command,'r').readlines():
# only for lines listing file specs
mMain = expMain.search( line )
if mMain:
if debug:
sys.stdout.write( line )
# Preventive cleanup
file1_section1 = file1_section2 = file2_section1 = file2_section2 = ''
file1_revnum = file2_revnum = file1_type =file2_type = delimiter = compare_status = ''
temp = 0
mMissingFirst = expMissingFirst.search( line )
mMissingSecond = expMissingSecond.search( line )
# lets start off thinking that each file has 1 rev then
# later we will break the "real" rev number out of each filespec
# and place it in one of these
#
rev_number1 = 1
rev_number2 = 1
# String splitting for first file
#
if mMissingFirst:
# First file is empty so this is an added file
if debug:
sys.stdout.write( 'Added!!!!\n' )
files_added = files_added + 1
rev_number1 = 0
else:
# break the line up into each of its file parts
# we must check here if we are missing the second filespec because
# then the delimiter changes from "- //' to "- <"
# We cant use plain "-" because it may be in a filename
if mMissingSecond:
( section1, section2 ) = exp1.split( line )
else:
( section1, section2 ) = exp2.split( line )
if debug:
sys.stdout.write( 'section1->' + section1 + '\n' )
sys.stdout.write( 'section2->' + section2 + '\n' )
# main count files in first @label
file_count1 = file_count1 + 1
# now split the path from the rev number
( file1_section1, file1_section2 ) = exp3.split( section1 )
if debug:
sys.stdout.write( 'file1_section1->' + file1_section1 + '\n' )
sys.stdout.write( 'file1_section2->' + file1_section2 + '\n' )
if mMissingSecond:
# If your missing second file there will be no file type to
# split off
rev_number1 = int( file1_section2 )
if debug:
sys.stdout.write( 'file1 rev number->' + file1_section2 + '\n' )
else:
( file1_revnum, file1_type ) = re.split( ' ', file1_section2, 2 )
rev_number1 = int( file1_revnum )
if debug:
sys.stdout.write( 'file1 rev number->' + file1_revnum + '\n' )
sys.stdout.write( 'file1 type->' + file1_type + '\n' )
# String splitting for second file
#
if mMissingSecond:
# Second file is empty so this is a deleted file
files_deleted = files_deleted + 1
rev_number2 = 0
if debug:
sys.stdout.write( 'Deleted!!!!\n' )
else:
# We dont need to test here for second filespec missing
( section1, section2 ) = exp2.split( line )
if debug:
sys.stdout.write( 'section1->' + section1 + '\n' )
sys.stdout.write( 'section2->' + section2 + '\n' )
# main count of files in second @label
file_count2 = file_count2 + 1
( file2_section1, file2_section2 ) = exp3.split( section2 )
if debug:
sys.stdout.write( 'file2_section2->' + file2_section2 + '\n' )
if mMissingFirst:
# This is a file that has been added
#
( file2_revnum, compare_status ) = re.split( ' ', file2_section2, 2 )
if debug:
sys.stdout.write( 'file2 rev number->' + file2_revnum + '\n\n' )
revisions_added = revisions_added + int( file2_revnum )
#sys.stdout.write( 'Added,//' + file2_section1 )
#sys.stdout.write( ',' + `int( file2_revnum)` + '\n' )
else:
( file2_revnum, file2_type, delimiter, compare_status ) = re.split( ' ', file2_section2, 4 )
if debug:
sys.stdout.write( 'file2 rev number->' + file2_revnum + '\n' )
sys.stdout.write( 'file2 type->' + file2_type + '\n' )
sys.stdout.write( 'file compare status->' + compare_status + '\n' )
rev_number2 = int( file2_revnum )
temp = rev_number2 - rev_number1
revisions_added = revisions_added + temp
if rev_number1 != rev_number2:
#sys.stdout.write( 'Changed,//' + file2_section1 )
#sys.stdout.write( ',' + `temp` + '\n' )
files_changed = files_changed + 1
if file1_type != file2_type:
files_typechange = files_typechange + 1
return files_added, files_deleted, files_typechange, files_changed, revisions_added, file_count1, file_count2
#
# This script takes a depot path and two labels (like @jakcalope.20 )
# OR two date-time combos (like @1999/02/02 )
#
# The output then gives you the counts of files changed deleted or added
# an various counts. (metrics)
#
# Main body of program
#
#
depot_location = sys.argv[1]
diff_label1 = sys.argv[2]
diff_label2 = sys.argv[3]
sys.stdout.write( 'Starting processing tree data....\n\n' )
#call the diff with the RCS flags
#
#
adds = changes = deletes = 0
( added, deleted, typechange, changed, revs_added, count1, count2 ) = \
extract_metrics_counts_file( depot_location, diff_label1, diff_label2 )
sys.stdout.write( 'Count of files at start point--> ' + `count1` + '\n' )
sys.stdout.write( 'Count of files at end point--> ' + `count2` + '\n' )
sys.stdout.write( 'Count of files added--> ' + `added` + '\n' )
sys.stdout.write( 'Count of files removed--> ' + `deleted` + '\n' )
sys.stdout.write( 'Count of files that changed type--> ' + `typechange` + '\n' )
sys.stdout.write( 'Count of files that changed--> ' + `changed` + '\n' )
sys.stdout.write( 'Total number of revisions added--> ' + `revs_added` + '\n' )