GyoshukuKit(凝縮Kit)

読み取りの KaitoKit と対をなす、純 Swift の書庫書き込みフレームワーク

Pure-Swift archive writer, twin of KaitoKit

対応環境
macOS 26 以降 / Apple Silicon(ビルドは Xcode 27 / Swift 6.4 以上)
最新リリース
GyoshukuKit 0.8.0 (2026-10-08)
ライセンス
MIT
言語
Swift
更新
2026-10-09

リリースページ (v0.8.0) GitHub で見る

GyoshukuKit の概要図。解凍Kit と凝縮Kit の対、ArchiveWriter の create → add → finish の流れ、対応形式と暗号化出力
読む KaitoKit と書く GyoshukuKit の対。ArchiveWriter.create → add → finish() の流れと、新規作成・更新・暗号化出力の対応形式(図解)

GyoshukuKit(凝縮Kit)は、macOS 向けの純 Swift 書庫書き込みフレームワークです。読み取り専用の KaitoKit(解凍Kit)と対をなし、ZIP / ZIP64 の新規作成・追加・削除・改名と、tar / tar.gz / tar.bz2 / tar.xz / tar.zst / tar.lzma / tar.lz / tar.lz4 / tar.br / tar.Z / 7z / LHA の作成・全体再構築を扱います。tar / tar.gz / tar.bz2 / tar.xz・7z・LHA の既存書庫への追加・削除・改名と、単独ファイルの .gz / .bz2 / .xz / .zst / .lzma / .lz / .lz4 / .br / .Z への圧縮にも対応します。

KaitoKit を読み取り専用のまま保つのは意図的な設計です。書き込みを足すと読み取りしか必要としない利用者にまで writer のコードが届くため、別リポジトリに分け、依存は GyoshukuKit から KaitoKit への一方向だけにしました。

API は KaitoKit の ArchiveReader と対称です。ArchiveWriter で新規作成し、ArchiveUpdater で既存 ZIP への追加・削除・改名を一つの commit にまとめ、TarUpdater / CompressedTarUpdater / LHAUpdater / SevenZipUpdater で他の形式の既存書庫を編集し、ArchiveRewriter で全体の再圧縮・形式変換を行い、SingleStreamCompressor で通常ファイル一つを圧縮します。生き残る entry は再圧縮せずに運び、更新は APFS clone 上で進めて atomic に置き換えるため、途中失敗や取消しで原本を変更しません。

import GyoshukuKit

let writer = try ArchiveWriter.create(
    url: destination,
    format: .zip,
    options: WriterOptions(deflateLevel: 6)
)
try writer.addDirectory("docs")
try writer.add(data: Data("こんにちは\n".utf8), as: "docs/readme.txt",
               modificationDate: Date(), permissions: 0o644)
try writer.add(contentsOf: sourceURL, as: "assets")
try writer.finish()

特徴

  • ZIP / ZIP64 の新規作成と、既存 ZIP / ZIP64 への追加・削除・改名。生き残る entry の圧縮 payload は再圧縮せず、そのまま運びます
  • ZIP の圧縮方式は stored / Deflate(既定)に加え、BZip2 / LZMA / Zstandard / XZ / PPMd を選べます。macOS の Archive Utility / ditto と /usr/bin/unzip はこれらを展開できないため、KaitoKit や 7-Zip を使う場合の opt-in です
  • tar / tar.gz / tar.bz2 / tar.xz / tar.zst / tar.lzma / tar.lz / tar.lz4 / tar.br / tar.Z / 7z / LHA の作成と、ArchiveRewriter による全体再構築・形式変換
  • 7z は LZMA2(既定)/ LZMA / Deflate / BZip2 / PPMd / Copy の方式と、solid、BCJ / ARM64 / Delta の filter を選べます。LHA は -lh5-(既定)/ -lh6- / -lh7- / 無圧縮の方式と、探索量 1〜9 を選べます
  • tar / tar.gz / tar.bz2 / tar.xz / LHA / 7z の既存書庫への追加・削除・改名。未変更の member や圧縮区間は運び、再圧縮するのは圧縮 tar の変更区間と 7z solid の一部削除だけです。tar.zst など新しい6形式の編集は ArchiveRewriter で全体を再符号化します
  • SingleStreamCompressor で通常ファイル一つを .gz / .bz2 / .xz / .zst / .lzma / .lz / .lz4 / .br / .Z に新規圧縮します。一時ファイルで圧縮を終えてから公開し、既存の出力は上書きしません
  • 暗号化出力は ZIP の WinZip AES-256(既定)と ZipCrypto、7z の AES-256。7z はファイル名を含む header の暗号化も選べます
  • ZIP / 7z は、既存書庫のパスワードの設定・変更・解除を再圧縮なしで行えます
  • ArchiveAddition による一括追加と、ディスク読取の byte 進捗、追加の完了処理や updater / rewriter の commit の進捗通知
  • compressionThreads で、ZIP / 7z / LHA は項目・folder・member を並列に、圧縮 tar と単独ファイルの gzip / bzip2 / XZ / Zstandard / lzip / LZ4 も並列に圧縮します。ZIP / 7z の BZip2 は大きな項目の中も並列に圧縮して一つの stream につなぎます。LZMA1 / PPMd の一つの stream と、LZMA_Alone / Brotli / compress は逐次です。自前の LZMA / Zstandard と ZIP / 7z の BZip2 は memoryLimit(既定は物理メモリの50%)に収まるよう並列数を抑えます
  • 更新は同一 volume の APFS clone 上で行い、commit で atomic に置き換えます。途中失敗・取消し・未 commit の破棄では原本を変更しません
  • 通常ファイルの payload は 256 KiB 単位で読み書きし、作業メモリをファイルサイズに比例させません
  • 新規追加・改名・再出力の名前は全形式で NFC へ正規化し、絶対パス・..・NUL などの危険な名前は拒否します。Windows の区切り文字 \ / : は ZIP / 7z / LHA の出力でだけ拒否し、tar では名前の一部として許可します。ZIP の名前は UTF-8 で書き、bit 11 を立てます
  • 外部依存を追加せず、system zlib・libbz2・Apple Compression・CommonCrypto / CryptoKit / Security をプロセス内で使い、LZMA / Zstandard / PPMd などの encoder は自前で実装しています。システムの libarchive は使いません
  • unzip / 7zz / ditto / bsdtar との差分と KaitoKit での往復で検証し、4 GiB 超の全バイトと 65,536 entry の全件検証も通常の swift test に含めます

RAR の作成、SFX の作成、sparse file の検出は対象外です。既定値は「相手が Windows でも困らない」側に倒しています。UTF-8 名と NFC 正規化、data descriptor を書かない、tar に macOS metadata を既定で書かない、uid/gid は 0 で作者のアカウント名を書庫に入れない、という選択です。

対応環境と入手方法

実行環境は macOS 26 以降 / Apple Silicon で、ビルドには Xcode 27 / Swift 6.4 以上が必要です。Xcode 26 / Swift 6.3 はビルドできても release で誤動作するためサポートしません(この要件は manifest では強制されません)。ライセンスは MIT です。

SwiftPM のパッケージとして導入します。Xcode の File → Add Package Dependencies… に https://github.com/shunnag/GyoshukuKit.git を入力し、最新のリリースを指定します(リリースにバイナリの添付はありません)。Package.swift では .upToNextMinor で指定し、利用側の target の dependencies に .product(name: "GyoshukuKit", package: "GyoshukuKit") を追加します。

// Package.swift
.package(url: "https://github.com/shunnag/GyoshukuKit.git", .upToNextMinor(from: "0.8.0"))

依存する KaitoKit は自動で解決されます。公開 API にも KaitoKit の型を含むため、KaitoKit への依存は .upToNextMinor で一つのマイナーバージョンの範囲に限定しています。

ソースからビルドするときは clone して swift build するだけです。隣に ../KaitoKit の checkout があれば開発用にその path 依存を、なければ tag 参照を Package.swift が自動で選びます(切り替わった後は swift package purge-cache で manifest を再評価させます)。

git clone https://github.com/shunnag/GyoshukuKit.git
cd GyoshukuKit
swift build
swift test

テストには /usr/bin/unzip, /opt/homebrew/bin/7zz, /usr/bin/ditto, /usr/bin/tar, /usr/bin/python3, /usr/bin/cmp が必要です。新しい形式の試験には /opt/homebrew/bin/lzip・lz4・brotli・xz と、macOS の gzip / bzip2 / uncompress / bsdtar も使います。参照ツールが欠けていればテストは失敗し、skip しません(名前に WhenAvailable を含むテストだけが例外です)。4 GiB + 1 MiB の全バイト往復や 65,536 entry の全件検証も通常の swift test に含まれるため、作業用 clone と展開物に約 12 GiB の空き領域を確保してください。

設計の背景は設計書に、段階ごとの検証は Documentation/verification/ の記録に、変更の履歴は CHANGELOG にまとめています。