Artifact 23669f7c5d3a8eaa5a9898e75380c0a986b8e2f870a03542cefabcbf27efe2a1:
- File
simio/storage.go
— part of check-in
[2d2e62d420]
at
2026-10-18 22:16:06
on branch feat/submanifest-reader
— fix(checkout): scan missing files and mode changes as fossil does
Port the remaining branches of fossil's vfile_check_signature. A missing file is marked changed with mtime -1, a removed file is marked changed, and the permission half sets chnged 6-9 for exec-bit and symlink changes (returning to 0 when undone), honouring the allow-symlinks setting: off, a symlink is seen as what it points to; on, as itself, its content its target's name.
Status reports the mode changes as fossil's changes command labels them (executable, symlink, unexec, unlink). Commit records the permission it finds on disk, l included, with a symlink's target as its content. Where the storage has no file modes (MemStorage) or on Windows, the recorded permissions are kept, as fossil on Windows keeps them. ScanENotFile now refuses a non-file where a tracked file belongs, and merge scans with it as fossil's does. Extract still writes a missing file without Force.
Interop tests run the same edits through fossil changes and go-libfossil status on one checkout, in both orders and with allow-symlinks on and off, and compare a commit's F cards with fossil's.
Tracked in #449 (user: [email protected], size: 2005) [annotate] [blame] [check-ins using] [more...]
package simio import ( "io/fs" "os" "time" ) // Storage abstracts filesystem operations for WASM portability. type Storage interface { Stat(path string) (os.FileInfo, error) Remove(path string) error MkdirAll(path string, perm os.FileMode) error ReadFile(path string) ([]byte, error) WriteFile(path string, data []byte, perm os.FileMode) error ReadDir(path string) ([]fs.DirEntry, error) Chtimes(path string, atime, mtime time.Time) error } // OSStorage delegates to the os package. Used in production and WASI. type OSStorage struct{} func (OSStorage) Stat(path string) (os.FileInfo, error) { return os.Stat(path) } func (OSStorage) Remove(path string) error { return os.Remove(path) } func (OSStorage) MkdirAll(path string, perm os.FileMode) error { return os.MkdirAll(path, perm) } func (OSStorage) ReadFile(path string) ([]byte, error) { return os.ReadFile(path) } func (OSStorage) WriteFile(path string, data []byte, perm os.FileMode) error { return os.WriteFile(path, data, perm) } func (OSStorage) ReadDir(path string) ([]fs.DirEntry, error) { return os.ReadDir(path) } func (OSStorage) Chtimes(path string, atime, mtime time.Time) error { return os.Chtimes(path, atime, mtime) } // Chmod changes a file's mode. It is not part of Storage, since not every // storage has file modes; callers that need it check for it. func (OSStorage) Chmod(path string, mode os.FileMode) error { return os.Chmod(path, mode) } // Lstat is Stat without following a final symbolic link. It is not part of // Storage, since not every storage has symbolic links or file modes; // callers that need it check for it. func (OSStorage) Lstat(path string) (os.FileInfo, error) { return os.Lstat(path) } // Readlink returns the target a symbolic link names. Like Lstat, it is not // part of Storage. func (OSStorage) Readlink(path string) (string, error) { return os.Readlink(path) }