|
27 | 27 |
|
28 | 28 | set dir [file dirname [info script]] |
29 | 29 | set version_file [open "${dir}/VERSION"] |
30 | | -gets $version_file CV_DASHBOARD_VERSION |
| 30 | +gets $version_file git_date |
31 | 31 | close $version_file |
32 | 32 | # Convert to Tcl-style package version number |
33 | | -set CV_DASHBOARD_TCL_VERSION [string map { "-" "." } $CV_DASHBOARD_VERSION] |
34 | | -package provide cv_dashboard $CV_DASHBOARD_TCL_VERSION |
| 33 | +set CV_DASHBOARD_VERSION [string map { "-" "." } $git_date] |
| 34 | +package provide cv_dashboard $CV_DASHBOARD_VERSION |
35 | 35 |
|
36 | 36 | namespace eval ::cv_dashboard { |
37 | 37 | # General UI state |
@@ -95,7 +95,7 @@ namespace eval ::cv_dashboard { |
95 | 95 | variable version $CV_DASHBOARD_VERSION |
96 | 96 | variable repo_user "Colvars" |
97 | 97 | variable repo_name "colvars" |
98 | | - variable branch "master" |
| 98 | + variable branch "dashboard_update" |
99 | 99 | } |
100 | 100 |
|
101 | 101 | set script_dir [file dirname [info script]] |
@@ -1037,276 +1037,3 @@ proc ::cv_dashboard::save_traj_file { fileName } { |
1037 | 1037 | } |
1038 | 1038 | close $o |
1039 | 1039 | } |
1040 | | - |
1041 | | - |
1042 | | -#################################### |
1043 | | -# Self-update utilities |
1044 | | - |
1045 | | -proc ::cv_dashboard::check_version_file {} { |
1046 | | - variable version |
1047 | | - variable repo_user |
1048 | | - variable repo_name |
1049 | | - variable branch |
1050 | | - |
1051 | | - # Download VERSION file from repo |
1052 | | - set version_url "https://raw.githubusercontent.com/$repo_user/$repo_name/$branch/vmd/cv_dashboard/VERSION" |
1053 | | - set temp_file [file join [file dirname [info script]] "remote_version.txt"] |
1054 | | - |
1055 | | - if {[catch {exec curl -L -o $temp_file $version_url 2>/dev/null}] && |
1056 | | - [catch {exec wget -O $temp_file $version_url 2>/dev/null}]} { |
1057 | | - error "Could not check version file" |
1058 | | - } |
1059 | | - |
1060 | | - set fp [open $temp_file r] |
1061 | | - set remote_version [string trim [read $fp]] |
1062 | | - close $fp |
1063 | | - file delete $temp_file |
1064 | | - |
1065 | | - set comparison [compare_versions $version $remote_version] |
1066 | | - return [list $comparison $remote_version] |
1067 | | -} |
1068 | | - |
1069 | | -proc ::cv_dashboard::compare_versions {current latest} { |
1070 | | - # Versioned by date: e.g. 2025-05-21 |
1071 | | - set current_parts [split $current "-"] |
1072 | | - set latest_parts [split $latest "-"] |
1073 | | - |
1074 | | - # Pad with zeros if needed |
1075 | | - while {[llength $current_parts] < 3} {lappend current_parts 0} |
1076 | | - while {[llength $latest_parts] < 3} {lappend latest_parts 0} |
1077 | | - |
1078 | | - for {set i 0} {$i < 3} {incr i} { |
1079 | | - set curr [lindex $current_parts $i] |
1080 | | - set lat [lindex $latest_parts $i] |
1081 | | - |
1082 | | - if {$lat > $curr} { |
1083 | | - return "outdated" |
1084 | | - } elseif {$lat < $curr} { |
1085 | | - return "newer" |
1086 | | - } |
1087 | | - } |
1088 | | - return "current" |
1089 | | -} |
1090 | | - |
1091 | | -proc ::cv_dashboard::download_github_directory {user repo directory {branch "main"} {destdir "."}} { |
1092 | | - set url "https://github.com/$user/$repo/archive/refs/heads/$branch.tar.gz" |
1093 | | - set archive "[file join $destdir $repo.tar.gz]" |
1094 | | - set temp_dir "[file join $destdir temp_$repo]" |
1095 | | - |
1096 | | - file mkdir $destdir |
1097 | | - file mkdir $temp_dir |
1098 | | - |
1099 | | - # Download full repo |
1100 | | - set downloaded 0 |
1101 | | - if {![catch {exec curl -L -o $archive $url 2>/dev/null}]} { |
1102 | | - set downloaded 1 |
1103 | | - } elseif {![catch {exec wget -O $archive $url 2>/dev/null}]} { |
1104 | | - set downloaded 1 |
1105 | | - } elseif {$::tcl_platform(platform) eq "windows" && |
1106 | | - ![catch {exec powershell -command "Invoke-WebRequest -Uri '$url' -OutFile '$archive'" 2>nul}]} { |
1107 | | - set downloaded 1 |
1108 | | - } |
1109 | | - |
1110 | | - if {!$downloaded} { |
1111 | | - error "Could not download: no suitable tool found" |
1112 | | - } |
1113 | | - |
1114 | | - # Extract to temp directory |
1115 | | - exec tar -xzf $archive -C $temp_dir |
1116 | | - file delete $archive |
1117 | | - |
1118 | | - # Move specific directory to destination |
1119 | | - set extracted_repo "[file join $temp_dir $repo-$branch]" |
1120 | | - set source_dir "[file join $extracted_repo $directory]" |
1121 | | - set dest_dir "[file join $destdir [file tail $directory]]" |
1122 | | - |
1123 | | - if {![file exists $source_dir]} { |
1124 | | - file delete -force $temp_dir |
1125 | | - error "Directory '$directory' not found in repository" |
1126 | | - } |
1127 | | - |
1128 | | - file rename $source_dir $dest_dir |
1129 | | - file delete -force $temp_dir |
1130 | | - |
1131 | | - puts "Directory downloaded to: $dest_dir" |
1132 | | - return $dest_dir |
1133 | | -} |
1134 | | - |
1135 | | -proc ::cv_dashboard::download_github_directory_git {user repo directory {branch "main"} {destdir "."}} { |
1136 | | - set repo_url "https://github.com/$user/$repo.git" |
1137 | | - set clone_dir "[file join $destdir $repo-sparse]" |
1138 | | - |
1139 | | - file mkdir $destdir |
1140 | | - # Check if git is available |
1141 | | - if {[catch {exec git --version 2>/dev/null}]} { |
1142 | | - error "Git not available - use download_github_directory instead" |
1143 | | - } |
1144 | | - |
1145 | | - # Clone with no checkout |
1146 | | - exec git clone --no-checkout --depth 1 --branch $branch $repo_url $clone_dir 2>@1 |
1147 | | - |
1148 | | - # Set up sparse checkout |
1149 | | - set git_dir [file join $clone_dir ".git"] |
1150 | | - exec git --git-dir=$git_dir --work-tree=$clone_dir config core.sparseCheckout true |
1151 | | - |
1152 | | - # Specify directory to checkout |
1153 | | - set sparse_file [file join $clone_dir ".git" "info" "sparse-checkout"] |
1154 | | - set fp [open $sparse_file w] |
1155 | | - puts $fp "$directory/*" |
1156 | | - close $fp |
1157 | | - |
1158 | | - # Checkout only the specified directory |
1159 | | - exec git --git-dir=$git_dir --work-tree=$clone_dir checkout 2>@1 |
1160 | | - |
1161 | | - # Move the directory to final location |
1162 | | - set source_dir "[file join $clone_dir $directory]" |
1163 | | - set dest_dir "[file join $destdir [file tail $directory]]" |
1164 | | - |
1165 | | - if {![file exists $source_dir]} { |
1166 | | - file delete -force $clone_dir |
1167 | | - error "Directory '$directory' not found in repository" |
1168 | | - } |
1169 | | - |
1170 | | - file rename $source_dir $dest_dir |
1171 | | - file delete -force $clone_dir |
1172 | | - |
1173 | | - puts "Directory downloaded to: $dest_dir" |
1174 | | - return $dest_dir |
1175 | | -} |
1176 | | - |
1177 | | -proc ::cv_dashboard::download_directory_smart {user repo directory {branch "main"} {destdir "."}} { |
1178 | | - # Try git sparse-checkout first (most efficient) |
1179 | | - if {![catch {exec git --version 2>/dev/null}]} { |
1180 | | - puts "Using git sparse-checkout..." |
1181 | | - return [download_github_directory_git $user $repo $directory $branch $destdir] |
1182 | | - } else { |
1183 | | - puts "Git not available, downloading full repository..." |
1184 | | - return [download_github_directory $user $repo $directory $branch $destdir] |
1185 | | - } |
1186 | | -} |
1187 | | - |
1188 | | -proc ::cv_dashboard::get_local_dir {} { |
1189 | | - |
1190 | | - set dirname "colvars" |
1191 | | - |
1192 | | - switch $::tcl_platform(platform) { |
1193 | | - "windows" { |
1194 | | - set base [expr {[info exists ::env(LOCALAPPDATA)] ? $::env(LOCALAPPDATA) : $::env(USERPROFILE)}] |
1195 | | - return [file join $base $dirname] |
1196 | | - } |
1197 | | - "unix" { |
1198 | | - set home $::env(HOME) |
1199 | | - if {$::tcl_platform(os) eq "Darwin"} { |
1200 | | - return [file join $home "Library" "Application Support" $dirname] |
1201 | | - } else { |
1202 | | - return [file join $home ".local" "share" $dirname] |
1203 | | - } |
1204 | | - } |
1205 | | - } |
1206 | | -} |
1207 | | - |
1208 | | -proc ::cv_dashboard::self_update {{force false}} { |
1209 | | - variable version |
1210 | | - variable repo_user |
1211 | | - variable repo_name |
1212 | | - variable branch |
1213 | | - |
1214 | | - # Check for updates |
1215 | | - if {!$force} { |
1216 | | - lassign [check_version_file] status latest_version |
1217 | | - if {$status eq "current"} { |
1218 | | - puts "Local package ($version) is up to date" |
1219 | | - return false |
1220 | | - } elseif {$status eq "newer"} { |
1221 | | - puts "Local package ($version) is newer than remote ($latest_version)" |
1222 | | - return false |
1223 | | - } |
1224 | | - puts "Update available: $version -> $latest_version" |
1225 | | - } |
1226 | | - |
1227 | | - set package_dir [get_local_dir] |
1228 | | - set backup_dir "${package_dir}.backup.[clock seconds]" |
1229 | | - |
1230 | | - # Create backup |
1231 | | - if {[file exists $package_dir]} { |
1232 | | - file copy $package_dir $backup_dir |
1233 | | - } |
1234 | | - |
1235 | | - try { |
1236 | | - # Download new version |
1237 | | - puts "Downloading update..." |
1238 | | - set temp_dir [file join [file dirname $package_dir] "temp_update"] |
1239 | | - download_directory_smart $repo_user $repo_name "vmd/cv_dashboard" $branch $temp_dir |
1240 | | - |
1241 | | - # Replace current installation |
1242 | | - puts "Installing update..." |
1243 | | - file delete -force $package_dir |
1244 | | - file rename $temp_dir $package_dir |
1245 | | - |
1246 | | - puts "Update completed successfully" |
1247 | | - if {[file exists $backup_dir]} { |
1248 | | - puts "Backup available at: $backup_dir" |
1249 | | - } |
1250 | | - cleanup_backups $package_dir |
1251 | | - return true |
1252 | | - |
1253 | | - } on error {err} { |
1254 | | - puts "Update failed: $err" |
1255 | | - |
1256 | | - if {[file exists $backup_dir]} { |
1257 | | - puts "Restoring from backup..." |
1258 | | - if {[file exists $package_dir]} { |
1259 | | - file delete -force $package_dir |
1260 | | - } |
1261 | | - file rename $backup_dir $package_dir |
1262 | | - } |
1263 | | - return false |
1264 | | - } |
1265 | | -} |
1266 | | - |
1267 | | -proc ::cv_dashboard::cleanup_backups { package_dir {keep 2}} { |
1268 | | - set parent_dir [file dirname $package_dir] |
1269 | | - set package_name [file tail $package_dir] |
1270 | | - |
1271 | | - # Find backup directories |
1272 | | - set backups {} |
1273 | | - foreach item [glob -nocomplain -directory $parent_dir "${package_name}.backup.*"] { |
1274 | | - if {[file isdirectory $item]} { |
1275 | | - lappend backups $item |
1276 | | - } |
1277 | | - } |
1278 | | - |
1279 | | - # Sort by timestamp and remove old ones |
1280 | | - set backups [lsort $backups] |
1281 | | - set to_remove [lrange $backups 0 end-$keep] |
1282 | | - |
1283 | | - foreach backup $to_remove { |
1284 | | - puts "Removing old backup: $backup" |
1285 | | - file delete -force $backup |
1286 | | - } |
1287 | | -} |
1288 | | - |
1289 | | -proc ::cv_dashboard::load_newer_version {} { |
1290 | | - |
1291 | | - # Try to load updated local version |
1292 | | - set package_dir [::cv_dashboard::get_local_dir] |
1293 | | - if {[file exists $package_dir]} { |
1294 | | - # Compare versions |
1295 | | - set version_file [open [file join $package_dir "cv_dashboard" VERSION]] |
1296 | | - gets $version_file LOCAL_VERSION |
1297 | | - close $version_file |
1298 | | - if { [string compare $LOCAL_VERSION $::cv_dashboard::version] > 0 } { |
1299 | | - puts "Superseding current version ($::cv_dashboard::version) with local installation of cv_dashboard from $package_dir ($LOCAL_VERSION)" |
1300 | | - package forget cv_dashboard |
1301 | | - namespace delete ::cv_dashboard |
1302 | | - source [file join $package_dir "cv_dashboard" pkgIndex.tcl] |
1303 | | - package require cv_dashboard |
1304 | | - return true |
1305 | | - } |
1306 | | - } |
1307 | | - return false |
1308 | | -} |
1309 | | - |
1310 | | -# Try to update and switch to newer version when package is loaded |
1311 | | -::cv_dashboard::self_update |
1312 | | -::cv_dashboard::load_newer_version |
0 commit comments