############################################################################### # # bugSlope.eagle -- # # Extensible Adaptable Generalized Logic Engine (Eagle) # Bug Slope Calculation Tool # # Copyright (c) 2007-2010 by Joe Mistachkin. All rights reserved. # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. # # RCS: @(#) $Id: $ # ############################################################################### proc usage { error } { if {[string length $error] > 0} then {puts stdout $error} puts stdout "usage: [file tail [info nameofexecutable]]\ [file tail [info script]] " } if {[llength $argv] == 1} then { # # NOTE: Get the file name to read. # set fileName [lindex $argv 0] # # NOTE: Read all the data out of the text file. # set data [readFile $fileName] # # NOTE: Normalize to Unix line-endings. # set data [string map [list \r\n \n] $data]; # Unix. # # NOTE: Split the data into lines. # set lines [split $data \n] # # NOTE: A bunch of literal asterisk characters. # set stars {\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*} # # NOTE: Match against this pattern in the "ChangeLog" # file (this pattern is fairly strict to prevent # false-positives). # set pattern "(?:$stars Beta )(.*?)(?: RELEASE $stars)" # # NOTE: Get the epoch used when calculating daily build # numbers. # set epoch [object invoke -alias -flags +NonPublic \ Eagle._Components.Private.TimeOps BuildEpoch] # # NOTE: We need to process each line so we can detect # the build number transitions in the ChangeLog. # foreach line $lines { set line [string trim $line] if {[string length $line] > 0} then { # # NOTE: Extract the patch level from the line. # if {[regexp -- $pattern $line dummy patchLevel]} then { # # NOTE: Break the patch level into major, minor, # build, and revision. # set version [split $patchLevel .] # # NOTE: Make sure all the components are there. # if {[llength $version] == 4} then { # # NOTE: The build number portion is the number # of days since the epoch. # set days [lindex $version end-1] # # NOTE: If it is not an integer, it must be the # latest (unreleased) build. # if {![string is integer -strict $days]} then { set days [clock days -epoch [$epoch ToString]] } # # NOTE: The revision number is the number of # seconds since midnight for the day of # the build. # set seconds [lindex $version end] # # NOTE: If it is not an integer, it must be the # latest (unreleased) build. # if {![string is integer -strict $seconds]} then { set seconds [clock seconds \ [object invoke -tostring DateTime.UtcNow Date]] } set date [$epoch -alias AddDays $days] set date [$date -alias AddSeconds $seconds] set builds(bug,[$date ToString]) 0 set builds(refactor,[$date ToString]) 0 set builds(feature,[$date ToString]) 0 } else { puts stdout [appendArgs "build line \"" $line "\" is malformed"] } } elseif {[regexp -- "^BUGFIX: " $line]} then { if {[info exists date]} then { # # NOTE: Another bug fixed for this build... # incr builds(bug,[$date ToString]) } else { # # NOTE: Orphan line? # puts stdout [appendArgs "bugfix line \"" $line "\" has no build"] } } elseif {[regexp -- "^REFACTOR: " $line]} then { if {[info exists date]} then { # # NOTE: More refactoring for this build... # incr builds(refactor,[$date ToString]) } else { # # NOTE: Orphan line? # puts stdout [appendArgs "refactor line \"" $line "\" has no build"] } } elseif {[regexp -- "^FEATURE: " $line]} then { if {[info exists date]} then { # # NOTE: Another feature added for this build... # incr builds(feature,[$date ToString]) } else { # # NOTE: Orphan line? # puts stdout [appendArgs "feature line \"" $line "\" has no build"] } } } } foreach name [array names builds] { set value $builds($name) puts stdout [appendArgs [join [split $name ,] \t] \t $value] } } else { usage }