overlaps.rb #1

  • //
  • guest/
  • matt_attaway/
  • Overlaps/
  • overlaps.rb
  • View
  • Commits
  • Open Download .zip Download (4 KB)
#!/usr/local/bin/ruby

# == Synopsis
# 
# overlaps: graph files that are edited by multiple users per day using a stem and leaf plot
# 
# == Usage
# 
# overlaps [ -p port ] [ -u user ] ( [ -s date ] | [ -w weeks ] | [ -d date ] ) [ -e date ] [ -v ] [ -m minimum ] <Perforce path>
#
# Flagged files may be candidates for splitting into multiple files or refactoring
#
# * -s Start date. Incompatible with -w. One week before end date by default.
# * -e End date. Today by default.
# * -w Number of weeks before end date to go examine.
# * -v Show detailed list of overlapping files.
# * -d Date. Gives overlaps for a single day. Overrides all other date related flags.
# * -m Minimum number of overlaps required to be flagged. 2 by default.

$:.unshift File.join( File.dirname( $0 ), "p4ruby", RUBY_PLATFORM )
require 'date'
require 'P4'
require 'getoptlong'
require 'rdoc/usage'


def getOverLappingChanges( date, showDetails = false )

	today = date
	tomorrow = date + 1

	fileDict = {}
	
	# get the changes for the day
	changes = $p4.run( "changes", 
	                   "-s", "submitted", 
					   $path + '@>' + today.strftime( "%Y/%m/%d" ) + ',@<' + tomorrow.strftime( "%Y/%m/%d" ) )
	
	# run 'describe' on each change to get the list of files and user
	changes.each do | c |
		files = $p4.run( "describe", c["change"] );
		
		if( files[0]["depotFile"] == nil )
			next
		end
					
		# lazily rely on hashes to determine uniquenss of file path and users
		files[0]["depotFile"].each do |f|
		
			if( !fileDict.has_key?( f ) )
				fileDict[ f ] = {}
			end
		
			fileDict[ f ].merge!( { c["user"] => 1 } )
		end
	end

	# start building up our plot string
	result = today.strftime( '%Y/%m/%d' ) + "\t"
	
	# sort by count for stem and leaf plot so that large overlaps
	# don't get lost in the forest of numbers
	oc = fileDict.sort {|x,y| y[1].keys.length<=>x[1].keys.length}
	oc.each{ |f|
		if( f[1].keys.length >= $min )
			result += f[1].keys.length.to_s()
		end
	} 
	puts result
	
	# sort detailed output by path so that related files are adjacent
	oc = fileDict.sort {|x,y| x[0] <=> y[0]}
	if( showDetails )
		oc.each{ |f|
			if( f[1].keys.length >= $min )
				puts f[1].keys.length.to_s() + "\t\t" + f[0]
			end
	    } 
	end
end


begin
	# unreasonable defaults
	port = ""
	user = ""
	weeks = 1
	$min = 2
	details = false

	last = start = Date.today
	
	$path = "//..."

	# get the command line options if any, overriding the defaults
	opts = GetoptLong.new(
		  [ '--help',    '-h', GetoptLong::NO_ARGUMENT ],
		  [ '--user',    '-u', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--port',    '-p', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--date',    '-d', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--weeks',   '-w', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--min',     '-m', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--start',   '-s', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--end',     '-e', GetoptLong::REQUIRED_ARGUMENT ],
		  [ '--details', '-v', GetoptLong::NO_ARGUMENT ]
		)

	optDict = {}
	opts.each{ | opt, arg |
	    optDict[ opt ] = arg
	}

	optDict.each do |opt, arg|
		  case opt
			  when '--help'
				RDoc::usage
			  when '--user'
				user = arg
			  when '--port'
				port = arg
			  when '--date'
			    last = start = Date.parse( arg )
			  when '--weeks'
			    weeks = arg.to_i()
			  when '--min'
			    $min = arg.to_i()
			  when '--details'
			    details = true
			  when '--start'
			    start = Date.parse( arg )
			  when '--end'
			    last = Date.parse( arg )
		  end
	end
	
	if( !optDict.has_key?( '--start' )  &&  !optDict.has_key?( '--date' ) )
		start = last - 7 * weeks
	end
	
	if( ARGV.length == 1 )
		$path = ARGV[0]
	end

	# time to get the party started
	$p4 = P4.new()
	$p4.prog = "overlaps"
	
	# override environment variables if needs be
	if( port != "" )
		$p4.port = port
	end
	
	if( user != "" )
		$p4.user = user
	end
	
	$p4.connect()
	
	start.upto( last ) { |d|
		getOverLappingChanges( d, details )
	}

	$p4.disconnect
end
# Change User Description Committed
#1 8311 Matt Attaway Move the overlaps tool out into its own project
//guest/matt_attaway/scripts/overlaps.rb
#1 7329 Matt Attaway Add new overlapping changes detection script.
See wiki for details