modern-swift-dev/cabinet-swift
Typed files and directories for Swift, with throwing I/O, explicit overwrite policies, Codable helpers, and optional ZIP archives.
Installation
Add the package to your Package.swift:
.package(url: "https://github.com/modern-swift-dev/cabinet-swift.git", branch: "main")Add .product(name: "Cabinet", package: "cabinet-swift") to your target dependencies. Add .product(name: "CabinetZip", package: "cabinet-swift") when you need ZIP archives. Until a release is tagged, pin a commit for reproducible builds.
Cabinet requires Swift 6.3. Apple deployment targets start at iOS 18, macOS 15, tvOS 18, watchOS 11, and visionOS 2. Both products also support Linux. Apple file-protection and backup attributes are available only on Apple platforms. See Package.swift for the package configuration.
Save a value
import Cabinet
import Foundation
struct Preferences: Codable {
var showsHiddenFiles: Bool
}
let directory = try Cabinet.Directory.applicationSupport
.subdirectory(named: "MyApplication")
try directory.create()
let file = try directory.file(named: "preferences.json")
try file.writeJSON(Preferences(showsHiddenFiles: false), policy: .replace)
let preferences = try file.readJSON(Preferences.self)Writes fail if a file already exists unless you select .replace. Replacement writes the new contents atomically. File operations are synchronous and throw on failure; schedule blocking work appropriately for your application.
What is included
| Area | Capabilities | | --- | --- | | Typed locations | Cabinet.File and Cabinet.Directory, validated child names, common application directories | | File I/O | Read, write, copy, move, remove, and explicit collision policies | | Directory operations | Create, enumerate, clear, remove, move, and calculate total size | | Metadata | File size and available creation, modification, access, and metadata-change dates | | Codable | JSON encoding and decoding with configurable encoders and decoders | | Optional archives | ZIP creation and extraction through CabinetZip |
Directory moves reject an existing destination. Cabinet does not replace nonempty directories. Typed locations are conveniences for filesystem operations; they do not create a security sandbox or coordinate concurrent writers.
Migrating from SwiftLibs
Replace the SLFileSystem dependency and import with Cabinet. Use Cabinet.File and Cabinet.Directory explicitly. URL initializers and I/O methods now throw, so handle failures at the call site.
Construct children with file(named:) and subdirectory(named:). Each accepts a single path component. Use move(to:) to rename an item, and retain the updated value because moves mutate its stored location. Select .replace explicitly when overwriting a file is intended. Use readJSON and writeJSON for Codable values.
ZIP functionality is a separate product: add and import CabinetZip at archive call sites. Cabinet has no SwiftLibs dependency.
Documentation and development
Read the website guides and API reference.
The central documentation repository owns Astro, the shared theme, and website/API generation. Edit page Markdown in Documentation/Site/ and keep DocC catalogs beside the module sources. See the docs README for local build and preview commands. Generated HTML is not committed here.
make test runs the macOS tests with filesystem writes restricted to a fresh sandbox. Every test owns its fixtures, including symlink targets, and cleans them up on failure or success.
make documentation creates .build/documentation/Cabinet-Documentation.zip, containing the Cabinet and CabinetZip DocC archives. See CONTRIBUTING.md for build, test, format, and lint commands.
Package Metadata
Repository: modern-swift-dev/cabinet-swift
Default branch: main
README: README.md