repomatic.file_ops module¶
How this package puts a file on disk, and takes one off.
The counterpart of repomatic.file_inventory, which answers what is on
disk: this one decides how something lands there. Format-neutral by design, and
the reason it is its own module rather than a helper beside one format’s
readers, where the CSV writer, the SVG chart renderer, the download cache and
the release freeze each had to reach across for one.
Three concerns, deliberately separate, because a caller needs to pick:
write_if_changed()leaves a matching file untouched. Every generator leans on it rather than treating it as a nicety: one that rewrote its output unconditionally would turn each scheduled run into a commit, and a sync job opening a pull request would open one forever.atomic_write()makes a half-written file unobservable. What a cache another process reads needs, and what a killed run must not leave behind.unlink_with_empty_parents()removes a file or a whole component and takes the directories it emptied with it.
- repomatic.file_ops.write_if_changed(path, content, previous=None)[source]¶
Write content to path, leaving an already-matching file alone.
Creates the parent directories when missing.
- Parameters:
path (
Path) – File to write.content (
str) – The full text the file should hold.previous (
str|None) – What the file holds already, when the caller has read it anyway. Left unset, the file is read back here to compare. A caller that transformed text it already had in hand passes it and skips the read.
- Return type:
- Returns:
Truewhen the file was created or its content changed.
- repomatic.file_ops.atomic_write(dest, prefix, write)[source]¶
Write dest atomically: temp file in the target directory, then rename.
The other half of the question
write_if_changed()answers. That one asks whether the bytes differ; this one asks whether a reader can ever observe half of them. A cache another process reads, or a file a killed run leaves behind, needs this one.The rename is atomic on POSIX (same-filesystem rename) and safe on Windows (
Path.replaceoverwrites atomically). write receives the temp path and fills it (its return value is ignored, sowrite_text/write_bytespass straight through); partial writes are cleaned up on any failure.
- repomatic.file_ops.unlink_with_empty_parents(target, root)[source]¶
Delete target, then prune now-empty parent directories up to root.
target may be a directory, removed with everything it carries: what is being deleted is often a whole component rather than one file.
Stops at the first parent that still holds something, and never touches root itself.