diff --git a/src/bootsupport/modules/punkcheck-0.1.0.tm b/src/bootsupport/modules/punkcheck-0.1.0.tm index e147b4d1..59fd14c7 100644 --- a/src/bootsupport/modules/punkcheck-0.1.0.tm +++ b/src/bootsupport/modules/punkcheck-0.1.0.tm @@ -539,6 +539,8 @@ namespace eval punkcheck { set o_targetroot "" set o_rel_sourceroot "" set o_rel_targetroot "" + set o_record_list [list] + #todo - validate punkcheck file location further?? set punkcheck_folder [file dirname $o_checkfile] if {![file isdirectory $punkcheck_folder]} { @@ -546,6 +548,47 @@ namespace eval punkcheck { } my load_all_records + if {![llength $o_record_list]} { + puts stderr "\x1b\[32mNo existing records found in punkcheck file '$o_checkfile' for installer '$installername'. Starting with empty record list.\x1b\[m" + } else { + #verify no duplicate installer records for this installer. + #JMN + set sanity_dict [dict create] + set insane "" + foreach rec $o_record_list { + if {[dict get $rec tag] eq "INSTALLER"} { + set name [dict get $rec -name] + if {[dict exists $sanity_dict $name]} { + #todo - warn - duplicate record for same targetlist - shouldn't happen as we should be using get_file_record to find existing records + puts stderr "\x1b\[31mpunkcheck::recordlist::records_as_target_dict - multiple records with same targetlist '$tgtlist'\x1b\[m" + set insane "$name" + break + } + dict set sanity_dict $name {} + } + } + if {$insane ne ""} { + set msg "Sanity check: punkcheck file '$o_checkfile' contains multiple records for INSTALLER -name '$insane'." + append msg \n "This may indicate a problem such as multiple concurrent installtrack instances using the same punkcheck file," + append msg \n " or a previous installtrack instance that did not complete properly." + append msg \n " Please verify that this is expected and safe to proceed before confirming with 'yes'." + set answer [punk::lib::askuser $msg] + if {$answer ne "yes"} { + error "Aborting due to sanity check failure. User did not confirm with 'yes'." + } + if {[file exists $o_checkfile] && [file isfile $o_checkfile]} { + file delete $o_checkfile + } + if {[file exists $o_checkfile]} { + error "Failed to delete punkcheck file '$o_checkfile' after sanity check failure. Please investigate and resolve the issue before proceeding." + } + set o_record_list [list] + } else { + puts stderr "\x1b\[32mSanity check passed: no duplicate INSTALLER records found for installer '$installername' in punkcheck file '$o_checkfile'.\x1b\[m" + } + unset sanity_dict + } + set resultinfo [punkcheck::recordlist::get_installer_record $o_name $o_record_list] set existing_header_posn [dict get $resultinfo position] if {$existing_header_posn == -1} { @@ -2164,10 +2207,10 @@ namespace eval punkcheck { return [dict create changed $changed unchanged $unchanged] } - #assume only one for name - use first encountered + #assume only one for name - use first encountered? proc get_installer_record {name record_list} { set posn 0 - set found_posn -1 + set found_posns [list] set record "" #puts ">>>> checking [llength $record_list] punkcheck records" foreach rec $record_list { @@ -2175,12 +2218,20 @@ namespace eval punkcheck { if {[dict get $rec -name] eq $name} { set found_posn $posn set record $rec - break + lappend found_posns $posn } } incr posn } - return [list position $found_posn record $record] + if {[llength $found_posns] > 1} { + error "punkcheck::recordlist::get_installer_record - multiple installer records with name '$name' found at positions $found_posns" + } elseif {[llength $found_posns] == 0} { + return [list position -1 record ""] + } else { + #single record found + return [list position [lindex $found_posn 0] record $record] + } + } proc new_installer_record {name args} { diff --git a/src/modules/punkcheck-0.1.0.tm b/src/modules/punkcheck-0.1.0.tm index e147b4d1..59fd14c7 100644 --- a/src/modules/punkcheck-0.1.0.tm +++ b/src/modules/punkcheck-0.1.0.tm @@ -539,6 +539,8 @@ namespace eval punkcheck { set o_targetroot "" set o_rel_sourceroot "" set o_rel_targetroot "" + set o_record_list [list] + #todo - validate punkcheck file location further?? set punkcheck_folder [file dirname $o_checkfile] if {![file isdirectory $punkcheck_folder]} { @@ -546,6 +548,47 @@ namespace eval punkcheck { } my load_all_records + if {![llength $o_record_list]} { + puts stderr "\x1b\[32mNo existing records found in punkcheck file '$o_checkfile' for installer '$installername'. Starting with empty record list.\x1b\[m" + } else { + #verify no duplicate installer records for this installer. + #JMN + set sanity_dict [dict create] + set insane "" + foreach rec $o_record_list { + if {[dict get $rec tag] eq "INSTALLER"} { + set name [dict get $rec -name] + if {[dict exists $sanity_dict $name]} { + #todo - warn - duplicate record for same targetlist - shouldn't happen as we should be using get_file_record to find existing records + puts stderr "\x1b\[31mpunkcheck::recordlist::records_as_target_dict - multiple records with same targetlist '$tgtlist'\x1b\[m" + set insane "$name" + break + } + dict set sanity_dict $name {} + } + } + if {$insane ne ""} { + set msg "Sanity check: punkcheck file '$o_checkfile' contains multiple records for INSTALLER -name '$insane'." + append msg \n "This may indicate a problem such as multiple concurrent installtrack instances using the same punkcheck file," + append msg \n " or a previous installtrack instance that did not complete properly." + append msg \n " Please verify that this is expected and safe to proceed before confirming with 'yes'." + set answer [punk::lib::askuser $msg] + if {$answer ne "yes"} { + error "Aborting due to sanity check failure. User did not confirm with 'yes'." + } + if {[file exists $o_checkfile] && [file isfile $o_checkfile]} { + file delete $o_checkfile + } + if {[file exists $o_checkfile]} { + error "Failed to delete punkcheck file '$o_checkfile' after sanity check failure. Please investigate and resolve the issue before proceeding." + } + set o_record_list [list] + } else { + puts stderr "\x1b\[32mSanity check passed: no duplicate INSTALLER records found for installer '$installername' in punkcheck file '$o_checkfile'.\x1b\[m" + } + unset sanity_dict + } + set resultinfo [punkcheck::recordlist::get_installer_record $o_name $o_record_list] set existing_header_posn [dict get $resultinfo position] if {$existing_header_posn == -1} { @@ -2164,10 +2207,10 @@ namespace eval punkcheck { return [dict create changed $changed unchanged $unchanged] } - #assume only one for name - use first encountered + #assume only one for name - use first encountered? proc get_installer_record {name record_list} { set posn 0 - set found_posn -1 + set found_posns [list] set record "" #puts ">>>> checking [llength $record_list] punkcheck records" foreach rec $record_list { @@ -2175,12 +2218,20 @@ namespace eval punkcheck { if {[dict get $rec -name] eq $name} { set found_posn $posn set record $rec - break + lappend found_posns $posn } } incr posn } - return [list position $found_posn record $record] + if {[llength $found_posns] > 1} { + error "punkcheck::recordlist::get_installer_record - multiple installer records with name '$name' found at positions $found_posns" + } elseif {[llength $found_posns] == 0} { + return [list position -1 record ""] + } else { + #single record found + return [list position [lindex $found_posn 0] record $record] + } + } proc new_installer_record {name args} {