Liking cljdoc? Tell your friends :D

sturdy.fs

A small collection of file system utilities for Clojure.

This library provides a thin, opinionated wrapper around babashka.fs for common tasks such as reading and writing files, handling byte arrays, and working with paths.

Clojars Project

com.sturdystats/sturdy-fs {:mvn/version "VERSION"}

Features

  • Read files as bytes, strings, EDN, or lines
  • Write bytes, strings, or EDN with automatic parent directory creation
  • Optional atomic file writes
  • Atomic moves for single regular files, including a cross-filesystem fallback
  • Simple helpers for path manipulation
  • POSIX permission helpers (chmod-600!, chmod-400!)
  • Read-only artifact trees and deterministic directory hashing

sturdy.fs/atomic-move accepts a single regular file as its source; directories and symbolic links are rejected before either path is changed. It first attempts an operating-system atomic move. Across filesystems, it copies to a temporary file beside the destination, atomically publishes that file, and then removes the source. Destination publication and source removal cannot be one atomic operation in the fallback, so a source-deletion failure can leave both paths present.

Write options

spit-bytes! supports :append and :atomic?; these options are mutually exclusive. spit-string! supports the same options plus :charset. spit-edn! supports :atomic? and :charset, but not append. These are the complete supported option sets; options are not forwarded to babashka.fs/write-bytes.

Immutable artifact trees

The sturdy.fs.immutable namespace manages read-only artifact trees on POSIX filesystems:

(require '[sturdy.fs.immutable :as immutable])

(immutable/make-immutable! "artifacts/model")
(def digest (immutable/compute-dir-sha256 "artifacts/model"))
(immutable/delete-immutable-tree! "artifacts/model")

make-immutable! recursively changes regular files to 0444 (r--r--r--) and directories to 0555 (r-xr-xr-x). Here, "immutable" means read-only through POSIX mode bits; it does not set an operating-system immutable flag. A file owner or privileged process can change the modes again. Symbolic links are rejected rather than followed.

delete-immutable-tree! makes a managed tree writable before deleting it. Directories are changed to 0700 and files to 0600, so this operation does not preserve their prior permissions if deletion fails partway through.

These operations require a filesystem that supports POSIX permissions. They are not portable to filesystems or operating systems without the POSIX attribute view.

Directory hashes

compute-dir-sha256 returns a SHA-256 digest as a byte array. The digest includes each regular file's root-relative path (encoded as UTF-8) and contents. Paths are sorted to make the result independent of directory traversal order, and file boundaries are cryptographically separated.

The digest does not include permissions, timestamps, ownership, directory names, or empty directories. Non-regular entries other than symbolic links are currently ignored. Every symbolic link is rejected, including links whose targets are inside the tree and broken links, so hashing does not intentionally read content outside the requested root.

Hashing and permission changes assume the tree is not being modified concurrently. These path-based operations are not a security boundary for an attacker-writable tree: entries can be changed between inspection and use.

Design

  • Minimal API
  • Explicit error checking (via taoensso.truss)
  • No global state
  • Intended as a small shared utility library, not a full filesystem abstraction

Non-goals

  • Streaming or lazy IO
  • File watching
  • Appending EDN forms (the resulting document semantics are ambiguous)
  • Path sanitization or traversal policy; functions operate on the paths supplied by callers
  • Platform-specific abstractions beyond what babashka.fs provides

License

Apache License 2.0

Copyright © Sturdy Statistics

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close