#!/bin/sh
#-*-tcl-*-
# aegis - project change supervisor
# Copyright (C) 2000, 2001 Scott Finneran
# Copyright (C) 2007, 2008 Peter Miller
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# .
#
# Makes use of tkdiff by by John M. Klassa.
# TkDiff Home Page: http://www.ede.com/free/tkdiff
#
# @configure_input@
#
# comments wrap in Tcl, but not in sh \
exec wish $0 -- ${1+"$@"}
set bindir @bindir@
set libdir @libdir@
set datadir @datadir@
set datarootdir @datarootdir@
wm title . tkaer
wm iconname . tkaer
wm iconbitmap . @$datadir/aegis.icon
wm iconmask . @$datadir/aegis.mask
proc read_pipe { command errok } {
set data ""
set fd [open $command r]
if { $fd != "" } {
set data [read $fd]
set codevar ""
catch { close $fd } codevar
if { $codevar != "" && !$errok } {
puts [format "Command \"%s\"\nreturned \"%s\"" \
$command $codevar]
exit 1
}
}
return [string trim $data]
}
proc handle_exit { widgetname } {
destroy $widgetname
}
proc list_selected { widgetname } {
# default return value.
set item ""
set i [$widgetname curselection]
if { $i != "" } {
set item [$widgetname get $i]
}
return "$item"
}
proc display_list {group_name file_list label_text} {
# List of files newly created by this change:
frame $group_name
label $group_name.label -text $label_text
pack $group_name.label -side top -expand y
listbox $group_name.listbox -relief raised -borderwidth 2 \
-yscrollcommand "$group_name.scroll set"
pack $group_name.listbox -side left -expand y
scrollbar $group_name.scroll \
-command "$group_name.listbox yview"
pack $group_name.scroll -side right -fill y -expand y
# Implement a complex search algorithm for finding
# the longest filename :-)
set longest_filename_length 0; # just to get the ball rolling
foreach i $file_list {
$group_name.listbox insert end $i
if {[string length $i] > $longest_filename_length} {
set longest_filename_length [string length $i]
}
}
# and update the width of the listboxes to suit.
$group_name.listbox configure -width $longest_filename_length
pack $group_name -side left -expand y
}
proc diff_review_file {old_filename} {
global change1_development_directory
global change1_files_list_oldname
global change1_files_list_newname
global change2_development_directory
global change2_files_list_oldname
global change2_files_list_newname
global diff_command
# ok, we know the (common) old name, so first determine the new name
# and then diff the mongrels.
set c1_index [lsearch -exact $change1_files_list_oldname $old_filename]
set c1_file [format "%s/%s" $change1_development_directory \
[lindex $change1_files_list_newname $c1_index]]
set c2_index [lsearch -exact $change2_files_list_oldname $old_filename]
set c2_file [format "%s/%s" $change2_development_directory \
[lindex $change2_files_list_newname $c2_index]]
eval "exec \"$diff_command\" $c1_file $c2_file &"
}
proc process_command_line {} {
global argc argv argv0
global project_name1
global project_name2
global change_number1
global change_number2
set argindex 0
set project_name1 ""
set project_name2 ""
set p_count 1
set change_number1 ""
set change_number2 ""
set c_count 1
# Loop through argv seeing and try to guess at what the user wants to do.
while {$argindex < $argc} {
set arg [lindex $argv $argindex]
switch -regexp -- $arg {
"^-p$" {
incr argindex
set project_name$p_count [lindex $argv $argindex]
incr p_count
}
"^-p.*" {
set project_name$p_count [string range $arg 2 end]
incr p_count
}
"^-c$" {
incr argindex
set change_number$c_count [lindex $argv $argindex]
incr c_count
}
"^-c.*" {
set change_number$c_count [string range $arg 2 end]
incr c_count
}
default {
set change_number$c_count [lindex $argv $argindex]
incr c_count
}
}
incr argindex
}
# now as the counts were post-incremented, adjust the values.
incr c_count -1
incr p_count -1
# ok now we have the info provided by the user, so let's try
# to fill in the gaps.
if { $project_name1 == "" } {
# Set the project_name1 variable. We need to ask Aegis for this,
# so that we get what *aegis* thinks is the default project name.
set project_name1 [read_pipe "|aegis -list default_project" 1]
if { $project_name1 == "" } {
puts [format "\n%s couldn't determine the project name\n" $argv0]
exit 1
}
}
if { $project_name2 == "" } {
# if project_name2 was not specified then assume that the 2 changes
# exist in the one project (not all that unreasonable really).
set project_name2 $project_name1
}
# The bare minimum we need to proceed is a single change number.
if { $change_number2 == "" } {
if { $c_count < 1 } {
puts "\nUsage: aecomp \[Project Name\] \[Change Number\] \
\[Project Name\] \[Change Number\]\n"
# can't do much more....
exit 1
}
# well the user didn't specify the second change number so ask aegis
# for help.
set change_number2 [read_pipe "|aegis -list default_change" 1]
if { $change_number1 == "" } {
puts [format "%s couldn't determine the change number\n" $argv0]
exit 1
}
}
}
# AND BEGIN....
# Firstly, lets figure out what to do.
process_command_line
# Get the change_list etc. variables from the report for change 1.
eval [read_pipe [format "|aereport -f %s/wish/aecomp.rpt -unf \
-pw=1000 -project=%s -change=%s" \
$datadir $project_name1 $change_number1] 0]
if { [llength $change_files_list_newname] != 0 } {
set change1_files_list_newname $change_files_list_newname
} else {
puts "Change $change_number1 contains no new/modified/moved files"
exit 1
}
if { [llength $change_files_list_oldname] != 0 } {
set change1_files_list_oldname $change_files_list_oldname
}
set change1_development_directory $development_directory
if { [llength $removed_files_list] != 0 } {
set change1_removed_files_list $removed_files_list
}
# Get the change_list etc. variables from the report for change 2.
# First clear out the lists as the report performs "lappend"'s
set change_files_list_newname ""
set change_files_list_oldname ""
eval [read_pipe [format "|aereport -f %s/wish/aecomp.rpt -unf \
-pw=1000 -project=%s -change=%s" \
$datadir $project_name2 $change_number2] 0]
if { [llength $change_files_list_newname] != 0 } {
set change2_files_list_newname $change_files_list_newname
} else {
puts "Change $change_number2 contains no new/modified/moved files"
exit 1
}
if { [llength $change_files_list_oldname] != 0 } {
set change2_files_list_oldname $change_files_list_oldname
}
set change2_development_directory $development_directory
if { [llength $removed_files_list] != 0 } {
set change2_removed_files_list $removed_files_list
}
if { $development_directory == "" } {
puts [format \
"%s couldn't find the development directory for change %s\n" \
$argv0 $change_number]
exit 1
}
# OK now that we (should) have all the facts....
wm title . [format \
"aecomp - \"%s\" - Change \"%d\" vs. \"%s\" - Change \"%d\"" \
$project_name1 $change_number1 $project_name2 $change_number2 ]
wm iconname . aecomp
# define the review commands.
set diff_command [format "%s/tkdiff" $bindir]
#
# Now create the widget heirarchy
#
frame .toplevel
frame .toplevel.files
# List of files common to both changes (that are not being removed).
# note: we consider them common if they have the same "old" name
# ie. in one or both of the changes, the file may have been aemv'ed
# run through the change 1 files and look for corresponding names in change 2
set num_common_files 0
foreach i $change1_files_list_oldname {
if { [lsearch -exact $change2_files_list_oldname $i] != -1 } {
lappend common_files_list $i
incr num_common_files
}
}
if {$num_common_files == 1} {
set list_title [concat $num_common_files " Common File:"]
} else {
set list_title [concat $num_common_files " Common Files:"]
}
display_list .toplevel.files.created $common_files_list $list_title
bind .toplevel.files.created.listbox {
diff_review_file [list_selected .toplevel.files.created.listbox]
}
pack .toplevel.files -expand y
# And get a finished button.
frame .toplevel.buttons
button .toplevel.buttons.finished -text "Finished" -command {exit 0}
pack .toplevel.buttons.finished -side bottom -expand y
pack .toplevel.buttons -expand y
pack .toplevel -expand y
set errorCode 0