Add FILE_FLAG_OPEN_REPARSE_POINT to the Windows CreateFile call in skillPathFileIdentityImpl so symlinks are opened as reparse points rather than followed to their target. Staged symlinks carry relative targets computed for the final destination, which may not resolve from the staging directory; following them caused CreateFile to fail, yielding an empty file ID that rejected publication and broke canonical skill layout migration on Windows. Make skillPathSameFileIdentity a seam variable so the tunneled replacement test can deterministically simulate the identity change on Unix. On tmpfs (used by Linux CI runners), os.SameFile can return true for a recreated file due to inode reuse, making the test flaky. On Windows the swap is a no-op because skillPathIdentityProven compares file IDs from GetFileInformationByHandle and ignores skillPathSameFileIdentity.
25 lines
535 B
Go
25 lines
535 B
Go
//go:build !linux && !darwin && !windows
|
|
|
|
package upgrade
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
func skillPathFileIncarnationImpl(info os.FileInfo) string {
|
|
return fmt.Sprintf("%d:%d:%s", info.ModTime().UnixNano(), info.Size(), info.Mode())
|
|
}
|
|
|
|
func skillPathSameFileIdentityImpl(left, right os.FileInfo) bool {
|
|
return os.SameFile(left, right)
|
|
}
|
|
|
|
func skillPathFileIdentityImpl(_ string) string {
|
|
return ""
|
|
}
|
|
|
|
func skillPathIdentityProven(staged, published os.FileInfo, _, _ string) bool {
|
|
return skillPathSameFileIdentity(staged, published)
|
|
}
|