56 lines
2.4 KiB
Markdown
56 lines
2.4 KiB
Markdown
# Internal: File Operations
|
|
|
|
`internal/fileops` owns the narrow mechanics for atomically visible replacement of one
|
|
byte file. Callers keep ownership of serialization, validation, cancellation,
|
|
and destination-directory policy.
|
|
|
|
## Destination Paths
|
|
|
|
Ordinary workspace replacement uses standard operating-system path semantics.
|
|
Callers with a root-scoped safety contract own that validation at their boundary.
|
|
|
|
Remote object acquisition is owned by its domain caller. The caller writes a
|
|
sibling temporary file, validates the complete result, and passes that file to
|
|
`InstallSiblingTempFile` only when it is ready to become canonical. Callers own
|
|
remote object selection, validation, conflict handling, and temporary-file
|
|
cleanup.
|
|
|
|
Directory bundles are not promoted by `internal/fileops`; extraction owns its
|
|
validated Notarius bundle rename.
|
|
|
|
## Cleanup Contract
|
|
|
|
`RemoveAllUnderRoot` accepts an explicit root and a proper descendant, opens
|
|
that root with `os.OpenRoot`, and removes the normalized root-relative target
|
|
with `Root.RemoveAll`. It rejects root, traversal, and out-of-root targets; a
|
|
missing target is successful. `RemoveFileUnderRoot` additionally requires an
|
|
existing leaf to be regular. Command and post-publish policy remains owned by
|
|
`internal/app`.
|
|
|
|
## Bounded Reads
|
|
|
|
`ReadFileBounded` opens a normal path and reads at most its caller-supplied
|
|
limit. Credential mode policy and environment precedence remain owned by
|
|
`internal/app`.
|
|
|
|
## Replacement Contract
|
|
|
|
`ReplaceFileAtomic` requires an existing destination directory. It creates a
|
|
sibling temporary file, writes the complete byte sequence, applies the
|
|
caller-supplied mode, closes the file, runs an optional pre-rename check, and
|
|
replaces the destination with a rename.
|
|
|
|
The pre-rename check is the last point at which a caller can cancel without
|
|
installing a new destination. A failure before the rename leaves the old
|
|
destination unchanged and removes the temporary file. Successful replacement
|
|
provides atomic visibility; it makes no crash- or power-loss durability claim.
|
|
|
|
Replacement follows the operating system's same-filesystem rename semantics.
|
|
If a platform cannot replace an existing destination, the operation returns an
|
|
error and never removes the old file as an emulation step.
|
|
|
|
`WriteFileAtomic` and the copy helpers create the destination parent with the
|
|
repository's workspace permissions. `InstallSiblingTempFile` requires the
|
|
caller to provide an existing temporary file in the existing destination
|
|
directory.
|