Browse Source

winlnk (windows shortcut) resolution fixes for non-windows os e.g WSL

master
Julian Noble 4 days ago
parent
commit
3e183031db
  1. 5
      src/bootsupport/modules/punk/mix/util-0.1.0.tm
  2. 45
      src/modules/punk/winlnk-999999.0a1.0.tm
  3. 5
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/util-0.1.0.tm
  4. 5
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/util-0.1.0.tm
  5. 5
      src/vfs/_vfscommon.vfs/modules/punk/mix/util-0.1.0.tm
  6. 45
      src/vfs/_vfscommon.vfs/modules/punk/winlnk-0.1.0.tm

5
src/bootsupport/modules/punk/mix/util-0.1.0.tm

@ -107,9 +107,6 @@ namespace eval punk::mix::util {
set opts [dict remove $opts -noredirect]
}
if {$::tcl_platform(platform) ne "windows"} {
return [fileutil::cat {*}$args]
}
set finalpaths [list]
set is_windows [string match *windows* $::tcl_platform(platform)]
@ -120,7 +117,9 @@ namespace eval punk::mix::util {
lappend finalpaths $p
}
}
#fauxlink is platform agnostic.
set has_fauxlink [expr {![catch {package require fauxlink}]}]
#While .lnk files are windows specific, we want to be able to resolve them on other platforms if possible, so we try to load punk::winlnk on all platforms.
set has_winlnk [expr {![catch {package require punk::winlnk}]}]
if {!$opt_noredirect && ($has_fauxlink || $has_winlnk)} {

45
src/modules/punk/winlnk-999999.0a1.0.tm

@ -612,7 +612,50 @@ tcl::namespace::eval punk::winlnk {
set linkfields [LinkInfo_get_fields $linkinfocontent]
set localbase_path [dict get $linkfields localbasepath]
set suffix_path [dict get $linkfields commonpathsuffix]
set link_target [file join $localbase_path $suffix_path]
if {"windows" eq $::tcl_platform(platform)} {
set link_target [file join $localbase_path $suffix_path]
} else {
if {[regexp {([a-zA-Z]):/(.*)} $localbase_path _match drive_letter tail]} {
set link_target ""
#shortcut basepath is a windows path with drive letter - try to resolve it on unix by looking for a corresponding mount from fstab or a point under /mnt
set mountinfo [exec mount]
foreach line [split $mountinfo "\n"] {
#review - a more specific mount target might exist that includes the drive letter as part of the mount point name and is a longer prefix of the localbase_path
#- we should probably look for the longest prefix match rather than just the drive letter
if {[regexp -nocase -- [string cat ^$drive_letter {:\\\s+on\s+(\S)}] $line _match mount_point]} {
set link_target [file join $mount_point $tail $suffix_path]
break
}
}
if {$link_target eq ""} {
#review - under what circumstances could this happen? If the drive letter doesn't match any mount points, then /mnt/drive_letter should generally already have been found above above
# - However, it may be possible for /mnt/drive_Letter to still exist even if it's not reflected in the output of mount or the output of mount is in an unexpected format.
#nothing in mount result matches the drive letter - try looking for a mount point under /mnt with the drive letter as the name
if {[file exists /mnt/$drive_letter]} {
set link_target [file join /mnt/$drive_letter $tail $suffix_path]
} else {
if {$drive_letter eq [string tolower $drive_letter]]} {
set op_drive_letter [string toupper $drive_letter]
} else {
set op_drive_letter [string tolower $drive_letter]
}
if {[file exists /mnt/$op_drive_letter]} {
set link_target [file join /mnt/$op_drive_letter $tail $suffix_path]
} else {
#leave as is - probably won't resolve correctly but we have no better option
set link_target [file join $localbase_path $suffix_path]
}
}
} else {
#shortcut basepath is a windows path with drive letter and we found a matching mount point - link_target is set to the resolved path
}
} else {
#shortcut basepath doesn't match expected windows path format - just join it with the suffix and hope for the best
#could be something like a network path or it could be something else entirely
set link_target [file join $localbase_path $suffix_path]
}
}
}
set result [dict create\

5
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/util-0.1.0.tm

@ -107,9 +107,6 @@ namespace eval punk::mix::util {
set opts [dict remove $opts -noredirect]
}
if {$::tcl_platform(platform) ne "windows"} {
return [fileutil::cat {*}$args]
}
set finalpaths [list]
set is_windows [string match *windows* $::tcl_platform(platform)]
@ -120,7 +117,9 @@ namespace eval punk::mix::util {
lappend finalpaths $p
}
}
#fauxlink is platform agnostic.
set has_fauxlink [expr {![catch {package require fauxlink}]}]
#While .lnk files are windows specific, we want to be able to resolve them on other platforms if possible, so we try to load punk::winlnk on all platforms.
set has_winlnk [expr {![catch {package require punk::winlnk}]}]
if {!$opt_noredirect && ($has_fauxlink || $has_winlnk)} {

5
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/util-0.1.0.tm

@ -107,9 +107,6 @@ namespace eval punk::mix::util {
set opts [dict remove $opts -noredirect]
}
if {$::tcl_platform(platform) ne "windows"} {
return [fileutil::cat {*}$args]
}
set finalpaths [list]
set is_windows [string match *windows* $::tcl_platform(platform)]
@ -120,7 +117,9 @@ namespace eval punk::mix::util {
lappend finalpaths $p
}
}
#fauxlink is platform agnostic.
set has_fauxlink [expr {![catch {package require fauxlink}]}]
#While .lnk files are windows specific, we want to be able to resolve them on other platforms if possible, so we try to load punk::winlnk on all platforms.
set has_winlnk [expr {![catch {package require punk::winlnk}]}]
if {!$opt_noredirect && ($has_fauxlink || $has_winlnk)} {

5
src/vfs/_vfscommon.vfs/modules/punk/mix/util-0.1.0.tm

@ -107,9 +107,6 @@ namespace eval punk::mix::util {
set opts [dict remove $opts -noredirect]
}
if {$::tcl_platform(platform) ne "windows"} {
return [fileutil::cat {*}$args]
}
set finalpaths [list]
set is_windows [string match *windows* $::tcl_platform(platform)]
@ -120,7 +117,9 @@ namespace eval punk::mix::util {
lappend finalpaths $p
}
}
#fauxlink is platform agnostic.
set has_fauxlink [expr {![catch {package require fauxlink}]}]
#While .lnk files are windows specific, we want to be able to resolve them on other platforms if possible, so we try to load punk::winlnk on all platforms.
set has_winlnk [expr {![catch {package require punk::winlnk}]}]
if {!$opt_noredirect && ($has_fauxlink || $has_winlnk)} {

45
src/vfs/_vfscommon.vfs/modules/punk/winlnk-0.1.0.tm

@ -612,7 +612,50 @@ tcl::namespace::eval punk::winlnk {
set linkfields [LinkInfo_get_fields $linkinfocontent]
set localbase_path [dict get $linkfields localbasepath]
set suffix_path [dict get $linkfields commonpathsuffix]
set link_target [file join $localbase_path $suffix_path]
if {"windows" eq $::tcl_platform(platform)} {
set link_target [file join $localbase_path $suffix_path]
} else {
if {[regexp {([a-zA-Z]):/(.*)} $localbase_path _match drive_letter tail]} {
set link_target ""
#shortcut basepath is a windows path with drive letter - try to resolve it on unix by looking for a corresponding mount from fstab or a point under /mnt
set mountinfo [exec mount]
foreach line [split $mountinfo "\n"] {
#review - a more specific mount target might exist that includes the drive letter as part of the mount point name and is a longer prefix of the localbase_path
#- we should probably look for the longest prefix match rather than just the drive letter
if {[regexp -nocase -- [string cat ^$drive_letter {:\\\s+on\s+(\S)}] $line _match mount_point]} {
set link_target [file join $mount_point $tail $suffix_path]
break
}
}
if {$link_target eq ""} {
#review - under what circumstances could this happen? If the drive letter doesn't match any mount points, then /mnt/drive_letter should generally already have been found above above
# - However, it may be possible for /mnt/drive_Letter to still exist even if it's not reflected in the output of mount or the output of mount is in an unexpected format.
#nothing in mount result matches the drive letter - try looking for a mount point under /mnt with the drive letter as the name
if {[file exists /mnt/$drive_letter]} {
set link_target [file join /mnt/$drive_letter $tail $suffix_path]
} else {
if {$drive_letter eq [string tolower $drive_letter]]} {
set op_drive_letter [string toupper $drive_letter]
} else {
set op_drive_letter [string tolower $drive_letter]
}
if {[file exists /mnt/$op_drive_letter]} {
set link_target [file join /mnt/$op_drive_letter $tail $suffix_path]
} else {
#leave as is - probably won't resolve correctly but we have no better option
set link_target [file join $localbase_path $suffix_path]
}
}
} else {
#shortcut basepath is a windows path with drive letter and we found a matching mount point - link_target is set to the resolved path
}
} else {
#shortcut basepath doesn't match expected windows path format - just join it with the suffix and hope for the best
#could be something like a network path or it could be something else entirely
set link_target [file join $localbase_path $suffix_path]
}
}
}
set result [dict create\

Loading…
Cancel
Save