Open jmooring opened 6 months ago
one point regarding handling from (my) users perspective. mounting a non-existing folder should cause at least a "no such file" warning or even an error. not just a normal rendering stuff.
mounting a non-existing folder...
consider the strange windows behavior with having drive letters and cwd
for each drive (multiple roots)
No idea about
go handles that
or Hugo already considered these
no idea how the virtual fs works
if the file X:\content-other\p2.md exists
and your current working directory is on drive X:
/content-other
is a valid path that points to X:\content-other
so your second test case should fail on windows
willing to assist , if there's something (not GO) that would help
and more special stuff
drive letters -> so more than one root cygwin solves that by mapping these to /c/, /d/, /x/ respective. did not find how go handles these
drive relative paths
with cwd = c:\bla
cd c:hi
means c:\bla\hi
and \hi
means c:\
(in fact current drive letter)
each drive has a cwd
that can be changed from outside (guess for current shell)
...
source="c:" or source ="d:" may be problematic cause they refer to the current folder of that drive. So if you are somewhere in c:... and address d: it may point to some unexpected unwanted folder.
btw. docs state it must me forward slashes, but "c:\content" works fine
@irkode you have some valid points. My take on this would be that if
os.Stat("/foo/bar.txt") // Using the correct OS path separator
... throws an error (typically os.ErrNotExist
), then that file does not exist.
I'm not sure exactly happens in this particular case, but I'm pretty sure it can be explained re. the above.
I played around a little with Windows style pathes and have a finding
Go's Stat
and Abs
method seem not to handle Drive Relative Paths like
x:some-path-without-starting-slash
I'm new to Go, so there might be methods that handle that
Dunno if this will affect Hugo code
I could not identify issues if absolute paths are used X:\
(p.s. backslash and slash are handled properly)
wrote a small Go program that
run that for several filenames and compared with the output of Windows Powershell tests
The Good answer for all tested combinations where
have an absolute path with the same drive the results are identical Even for Drive relative paths.
if the drive letter differs
Go's method seem not to handle Drive Relative paths respect the current working of the tested Drive and uses absolute paths
drive C:
C:\
├───bar.md
└───stat
├───bar.md
└───baz.md
this reads as:
path
PS E:\> C:\mydir\winosstat\mystat.ps1| ?{-Not $_.status }| ft -AutoSize
status cwd driveCwd path winStat goStat winAbs goAbs
------ --- -------- ---- ------- ------ ------ -----
False E:\ c:\stat c:bar.md True True C:\stat\bar.md C:\bar.md
False E:\ c:\stat c:baz.md True False C:\stat\baz.md
False E:\ c:\stat c:stat/bar.md False True C:\stat\bar.md
False E:\ c:\stat c:stat/baz.md False True C:\stat\baz.md
False E:\ c:\mydir c:bar.md False True C:\bar.md
False E:\ c:\mydir c:stat/bar.md False True C:\stat\bar.md
False E:\ c:\mydir c:stat/baz.md False True C:\stat\baz.md
False E:\ c:\_repos c:bar.md False True C:\bar.md
False E:\ c:\_repos c:stat/bar.md False True C:\stat\bar.md
False E:\ c:\_repos c:stat/baz.md False True C:\stat\baz.md
quite hacky powershell and my first Go program - please be generous.
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
if len(os.Args) != 2 {
var arg0 = os.Args[0]
prg, _ := os.Stat(arg0)
fmt.Printf("Usage: %s <PATH>", prg.Name())
os.Exit(1)
}
var filename = os.Args[1]
_, err := os.Stat(filename)
if err != nil {
os.Exit(2)
} else {
absPath, err := filepath.Abs(filename)
if err != nil {
os.Exit(3)
} else {
fmt.Print(absPath)
os.Exit(0)
}
}
os.Exit(1)
}
Powershell
$mystat = "C:\mydir\winosstat\mystat.exe"
# This will be the current workin directories for finding files from
$driveCwds = @(
"c:\" # bar.txt
"c:\stat" # bar.txt & baz.txt
"c:\mydir" # neither
"c:\_repos" # neither
)
# Matrix test prefixes + pathes
$prefixes = @(
"",
"/",
"c:",
"c:/"
)
$pathes = @(
"bar.md"
"baz.md"
"stat/bar.md"
"stat/baz.md"
)
# Save Current Working directory to be able to go back after changing work director on other drive
$cwd = Get-Location
$driveCwds | % {
$driveCwd = $_
# Switch the tested drives working folder and come back
$newLoc = Set-location $driveCwd -PassThru
if ($cwd.Drive -ne $newLoc.Drive) {
Set-Location $cwd
}
$prefixes | % {
$pre = $_; $pathes | % {
$checkPath = $pre + $_
$winAbs = $Null
$goAbs = $Null
# check Windows style
$winStat = Test-Path $checkPath -ErrorAction SilentlyContinue
If ($winStat) {
$winAbs = (Resolve-Path $checkPath).Path
}
# Use Go program
$goAbs = & $mystat $checkPath
$goStat = $LastExitCode -eq 0
[PSCustomObject]@{
# compare results
status = (($winStat -eq $goStat) -and ($winAbs -eq $goAbs))
cwd = $cwd
driveCwd = $driveCwd
path = $checkPath
winStat = $winStat
goStat = $goStat
winAbs = $winAbs
goAbs = $goAbs
}
}
}
}
Reference: https://discourse.gohugo.io/t/linux-hugo-for-ubuntu-renders-one-page-less-than-windows-version-from-mounted-folder/49664/7?u=jmooring
On Windows, if a mount path has a leading slash, and that path exists relative to the root of the project directory, Hugo finds the path in the project directory and mounts the directory when it shouldn't. Paths with leading slashes are supposed to be relative to the system root.