#FILEINFO record - target fileset with body records: INSTALLRECORD,INSTALL-INPROGRESS,SKIPPED,DELETERECORD,DELETE-INPROGRESS,MODIFY-INPROGRESS,MODIFYRECORD
#FILEINFO record - target fileset with body records: INSTALL-RECORD,INSTALL-INPROGRESS,INSTALL-SKIPPED,DELETE-RECORD,DELETE-INPROGRESS,MODIFY-INPROGRESS,MODIFY-RECORD
#each FILEINFO body being a list of SOURCE records
oo::class create targetset {
variable o_targets
@ -126,10 +126,10 @@ namespace eval punkcheck {
method get_last_record {fileset_record} {
set body [dict_getwithdefault $fileset_record body [list]]
set previous_records [lrange $body 0 end-1]
#get last previous that is tagged INSTALLRECORD,MODIFYRECORD,DELETERECORD
#get last previous that is tagged INSTALL-RECORD,MODIFY-RECORD,DELETE-RECORD
set revlist [lreverse $previous_records]
foreach rec $revlist {
if {[dict get $rec tag] in [list "INSTALLRECORD" "MODIFYRECORD" "DELETERECORD"]} {
if {[dict get $rec tag] in [list "INSTALL-RECORD" "MODIFY-RECORD" "DELETE-RECORD" "VIRTUAL-RECORD"]} {
return $rec
}
}
@ -180,7 +180,7 @@ namespace eval punkcheck {
set o_rel_targetroot $rel_targetroot
}
destructor {
puts "[self] destructor called"
#puts "[self] destructor called"
}
method as_record {} {
set begin_seconds [expr {$o_ts_begin / 1000000}]
@ -218,7 +218,7 @@ namespace eval punkcheck {
set punkcheck_folder [file dirname [$o_installer get_checkfile]]
set existing [list]
foreach t $o_targets {
if {[file exists [file join $puncheck_folder $t]]} {
if {[file exists [file join $punkcheck_folder $t]]} {
lappend existing $t
}
}
@ -276,7 +276,7 @@ namespace eval punkcheck {
set oldposition [dict get $extractioninfo oldposition]
unset extractioninfo
#INSTALL-INPROGRESS will become INSTALLRECORD or INSTALLFAILED or SKIPPED upon finalisation
#INSTALL-INPROGRESS will become INSTALL-RECORD or INSTALL-FAILED or INSTALL-SKIPPED upon finalisation
#-installer and -eventid keys are added here
set new_inprogress_record [dict create tag [string toupper $operation]-INPROGRESS {*}$fields -tempcontext [my as_record] body {}]
#set existing_body [dict_getwithdefault $o_fileset_record body [list]]
@ -298,42 +298,55 @@ namespace eval punkcheck {
set punkcheck_folder [file dirname [$o_installer get_checkfile]]
set o_fileset_record [punkcheck::installfile_started_install $punkcheck_folder $o_fileset_record]
}
method targetset_finished {} {
if {$o_operation_start_ts eq ""} {
error "[self] targetset_finished - no current operation - call targetset_start first"
method targetset_end {status args} {
set defaults [dict create\
-note \uFFFF\
]
set known_opts [dict keys $defaults]
if {[llength $args] % 2 != 0} {
error "targetset_end arguments after status must be in the form of -flag value pairs. known flags: $known_opts"
}
set opts [dict merge $defaults $args]
if {[dict get $opts -note] eq "\uFFFF"} {
dict unset opts -note
}
set operation_end_ts [clock microseconds]
set elapsed [expr {$o_operation_start_ts - $operation_end_ts}]
set punkcheck_file [$o_installer get_checkfile]
set record_list [punkcheck::load_records_from_file $punkcheck_file]
set status [string toupper $status]
set statusdict [dict create OK RECORD SKIPPED SKIPPED FAILED FAILED]
if {$o_operation_start_ts eq ""} {
error "[self] targetset_end $status - no current operation - call targetset_started first"
}
if {$status ni [dict keys $statusdict]} {
error "[self] targetset_end unrecognized status:$status known values: [dict keys $statusdict]"
}
if {![punkcheck::lib::is_file_record_inprogress $o_fileset_record]} {
error "targetset_finished_install error: bad fileset_record - expected FILEINFO with last body element *-INPROGRESS"
error "targetset_end $status error: bad fileset_record - expected FILEINFO with last body element *-INPROGRESS"
}
set file_record_body [dict get $o_fileset_record body]
set targetlist [dict get $o_fileset_record -targets]
if {$targetlist ne $o_targets} {
error "targetset_finished error. targetlist mismatch between file : $targetlist vs $o_targets"
error "targetset_end $status error. targetlist mismatch between file : $targetlist vs $o_targets"
}
set operation_end_ts [clock microseconds]
set elapsed_us [expr {$operation_end_ts - $o_operation_start_ts}]
set file_record_body [dict get $o_fileset_record body]
set installing_record [lindex $file_record_body end]
set ts_start [dict get $installing_record -ts]
set punkcheck_file [$o_installer get_checkfile]
set record_list [punkcheck::load_records_from_file $punkcheck_file]
if {[dict exists $installing_record -ts_start_transfer]} {
set ts_start_transfer [dict get $installing_record -ts_start_transfer]
set ts_now [clock microseconds]
set elapsed_us [expr {$ts_now - $ts_start}]
set transfer_us [expr {$ts_now - $ts_start_transfer}]
set transfer_us [expr {$operation_end_ts - $ts_start_transfer}]
dict set installing_record -transfer_us $transfer_us
}
if {[dict exists $opts -note]} {
dict set installing_record -note [dict get $opts -note]
}
dict set installing_record -elapsed_us $elapsed_us
dict unset installing_record -tempcontext
dict set installing_record tag "${o_operation}RECORD"
dict set installing_record tag "${o_operation}-[dict get $statusdict $status]" ;# e.g INSTALL-RECORD, INSTALL-SKIPPED
lset file_record_body end $installing_record
dict set o_fileset_record body $file_record_body
set o_fileset_record [punkcheck::recordlist::file_record_prune $o_fileset_record]
set oldrecordinfo [punkcheck::recordlist::get_file_record $targetlist $record_list]
set oldposition [dict get $extractioninfo oldposition]
unset extractioninfo
#INSTALL-INPROGRESS will become INSTALLRECORD or INSTALLFAILED or SKIPPED upon finalisation
#INSTALL-INPROGRESS will become INSTALL-RECORD or INSTALL-FAILED or INSTALL-SKIPPED upon finalisation
#-installer and -eventid keys are added here
set new_installing_record [dict create tag INSTALL-INPROGRESS {*}$opts -tempcontext $active_event body {}]
#set existing_body [dict_getwithdefault $file_record body [list]]
@ -728,6 +695,7 @@ namespace eval punkcheck {
set ts_start [clock microseconds]
set last_installrecord [lib::file_record_get_last_installrecord $file_record]
set prev_ftype ""
set prev_fsize ""
set prev_cksum ""
set prev_cksum_opts ""
if {[llength $last_installrecord]} {
@ -735,6 +703,7 @@ namespace eval punkcheck {
if {[llength $src]} {
if {[dict_getwithdefault $src -path ""] eq $source_relpath} {
set prev_ftype [dict_getwithdefault $src -type ""]
set prev_fsize [dict_getwithdefault $src -size ""]
set prev_cksum [dict_getwithdefault $src -cksum ""]
set prev_cksum_opts [dict_getwithdefault $src -cksum_all_opts ""]
}
@ -753,14 +722,24 @@ namespace eval punkcheck {
} else {
set cksum_opts ""
}
set ftype [file type [file join $punkcheck_folder/$source_relpath]]
#allow nonexistant as a source
set fpath [file join $punkcheck_folder $source_relpath]
if {![file exists $fpath]} {
set ftype "missing"
set fsize ""
#get_relativecksum_from_base will set cksum to <PATHNOTFOUND>
set source_cksum_info [punk::mix::base::lib::get_relativecksum_from_base $punkcheck_folder $source_relpath {*}$cksum_opts]
} else {
set ftype [file type $fpath]
if {$ftype eq "directory"} {
set source_cksum_info [punk::mix::base::lib::get_relativecksum_from_base $punkcheck_folder $source_relpath {*}$cksum_opts]
set fsize "NA"
} else {
#todo - optionally use mtime instead of cksum (for files only)?
#mtime is not reliable across platforms and filesystems though.. see article linked at toop.
set source_cksum_info [punk::mix::base::lib::get_relativecksum_from_base $punkcheck_folder $source_relpath {*}$cksum_opts]
set fsize [file size $fpath]
}
}
@ -770,7 +749,7 @@ namespace eval punkcheck {
}
set cksum [dict get $ckinfo cksum]
set cksum_all_opts [dict get $ckinfo cksum_all_opts]
if {$cksum ne $prev_cksum || $ftype ne $prev_ftype} {
if {$cksum ne $prev_cksum || $ftype ne $prev_ftype || $fsize ne $prev_fsize} {
set changed 1
} else {
set changed 0
@ -778,7 +757,7 @@ namespace eval punkcheck {
set installing_record_sources [dict_getwithdefault $installing_record body [list]]
set ts_now [clock microseconds] ;#gathering metadata - especially checsums on folder can take some time - calc and store elapsed us for time taken to gather metadata
set metadata_us [expr {$ts_now - $ts_start}]
set this_source_record [dict create tag SOURCE -type $ftype -path $source_relpath -cksum $cksum -cksum_all_opts $cksum_all_opts -changed $changed -metadata_us $metadata_us]
set this_source_record [dict create tag SOURCE -type $ftype -size $fsize -path $source_relpath -cksum $cksum -cksum_all_opts $cksum_all_opts -changed $changed -metadata_us $metadata_us]
if {[dict get $install_record tag] ni [list "INSTALLRECORD" "SKIPPED" "INSTALL-INPROGRESS" "MODIFY-INPROGRESS" "MODIFYRECORD" "VIRTUAL-INPROGRESS" "VIRTUALRECORD" "DELETERECORD" "DELETE-INPROGRESS"]} {
error "file_install_record_source_changes bad file->install record: tag not INSTALLRECORD|SKIPPED|INSTALL-INPROGRESS|MODIFYRECORD|MODIFY-INPROGRESS|VIRTUALRECORD|VIRTUAL-INPROGRESS|DELETERECORD|DELETE-INPROGRESS"
if {[dict get $install_record tag] ni [list "INSTALL-RECORD" "SKIPPED" "INSTALL-INPROGRESS" "MODIFY-INPROGRESS" "MODIFY-RECORD" "VIRTUAL-INPROGRESS" "VIRTUAL-RECORD" "DELETE-RECORD" "DELETE-INPROGRESS"]} {
error "file_install_record_source_changes bad file->install record: tag not INSTALL-RECORD|SKIPPED|INSTALL-INPROGRESS|MODIFY-RECORD|MODIFY-INPROGRESS|VIRTUAL-RECORD|VIRTUAL-INPROGRESS|DELETE-RECORD|DELETE-INPROGRESS"
}
set source_list [dict_getwithdefault $install_record body [list]]