https://github.com/lebje/cpioarchivekit
A simple, 0-dependency Swift package for reading and writing cpio archives.
https://github.com/lebje/cpioarchivekit
cpio cpio-archives linux macos swift swift-library swift5 windows
Last synced: 3 months ago
JSON representation
A simple, 0-dependency Swift package for reading and writing cpio archives.
- Host: GitHub
- URL: https://github.com/lebje/cpioarchivekit
- Owner: LebJe
- License: mit
- Created: 2021-05-17T01:46:50.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-01-06T00:48:16.000Z (almost 2 years ago)
- Last Synced: 2024-11-17T03:36:18.430Z (11 months ago)
- Topics: cpio, cpio-archives, linux, macos, swift, swift-library, swift5, windows
- Language: Swift
- Homepage: https://lebje.github.io/CPIOArchiveKit/
- Size: 15.5 MB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# CPIOArchiveKit
**A simple, 0-dependency Swift package for reading and writing [`cpio`](https://en.wikipedia.org/wiki/Cpio) archives. Inspired by [go-cpio](https://github.com/cavaliercoder/go-cpio).**
[](https://swift.org)
[](https://swift.org/package-manager)
[](https://github.com/LebJe/CPIOArchiveKit/releases)
[](https://github.com/LebJe/CPIOArchiveKit/actions?query=workflow%3A%22Build+and+Test%22)
[](https://swiftpackageindex.com/LebJe/CPIOArchiveKit)
[](https://swiftpackageindex.com/LebJe/CPIOArchiveKit)# Table of Contents
- [CPIOArchiveKit](#cpioarchivekit)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Swift Package Manager](#swift-package-manager)
- [Usage](#usage)
- [Writing Archives](#writing-archives)
- [Checksums](#checksums)
- [Computed Checksum](#computed-checksum)
- [Pre-computed Checksum](#pre-computed-checksum)
- [Reading Archives](#reading-archives)
- [Iteration](#iteration)
- [Subscript](#subscript)
- [FileMode](#filemode)
- [File Type](#file-type)
- [Permissions](#permissions)
- [Examples](#examples)
- [Other Platforms](#other-platforms)
- [Windows](#windows)
- [Contributing](#contributing)Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)
Documentation is available [here](https://lebje.github.io/CPIOArchiveKit).
## Installation
### Swift Package Manager
Add this to the `dependencies` array in `Package.swift`:
```swift
.package(url: "https://github.com/LebJe/CPIOArchiveKit.git", from: "0.0.2")
```Also add this to the `targets` array in the aforementioned file:
```swift
.product(name: "CPIOArchiveKit", package: "CPIOArchiveKit")
```## Usage
### Writing Archives
To write archives, you'll need a `CPIOArchiveWriter`:
```swift
var writer = CPIOArchiveWriter()
```Once you have your writer, you must create a `Header`, that describes the file you wish to add to your archive:
```swift
var time: Int = 1615929568// You can also use date
let date: Date = ...
time = Int(date.timeIntervalSince1970)// File
let header = Header(
name: "hello.txt",
mode: FileMode(0o644, modes: [.regular]),
modificationTime: time
)// Directory
let header = Header(
name: "dir/",
mode: FileMode(0o644, modes: [.directory]),
modificationTime: time
)
```#### Checksums
If you would like to provide a cpio checksum with the `Header` you created above, there are two ways to do so.
##### Computed Checksum
```swift
// Compute the checksum.
let fileContents: [UInt8] = ...
let checksum = Checksum(bytes: fileContents)
```##### Pre-computed Checksum
```swift
let preComputedChecksum = 123
let checksum = Checksum(sum: preComputedChecksum)
l
```Once you have a `checksum`, add it to the checksum parameter of your `Header`:
```swift
Header(..., checksum: checksum, ...)
```Once you have your `Header`, you can write it, along with the contents of your file, to the archive:
```swift
// Without Foundation
var contents = Array("Hello".utf8)// With Foundation
let myData: Data = "Hello".data(using .utf8)!
contents = Array(myData)writer.addFile(header: header, contents: contents)
```If you have a text file, use the overloaded version of `addFile`:
```swift
writer.addFile(header: header, contents: "Hello")
```> For directories, omit the `contents` parameter in `addFile`. For symlinks, set the `contents` parameter to the file or directory the link points to.
Once you have added your files, you must call `finalize()` to create the archive and return the data:
```swift
// The binary representation (Array) of the created archive.
let bytes = writer.finalize()// You convert it to `Data` like this:
let data = Data(bytes)// And write it:
try data.write(to: URL(fileURLWithPath: "myArchive.cpio"))
```if you want to reuse `writer`, call `finalize(clear: true)` instead, which will clear the state inside `writer`.
### Reading Archives
To read archives, you need an `CPIOArchiveReader`:
```swift
// myData is the bytes of the archive.
let myData: Data = ...let reader = CPIOArchiveReader(archive: Array(myData))
```Once you have your reader, there are several ways you can retrieve the data:
#### Iteration
You can iterate though all the files in the archive like this:
```swift
for (header, data) in reader {
// `data` is `Array` that contains the raw bytes of the file in the archive.
// `header` is the `Header` that describes the `data`.// if you know `data` is a `String`, then you can use this initializer:
let str = String(data)
}
```#### Subscript
Accessing data through the `subscript` is useful when you only need to access a few items in a large archive:
```swift
// The subscript provides you with random access to any file in the archive:
let firstFile = reader[0]
let fifthFile = reader[6]
```You can also use the version of the subscript that takes a `Header` - useful for when you have a `Header`, but not the index of that header.
```swift
let header = reader.headers.first(where: { $0.name.contains(".swift") })!
let data = reader[header: header]
```#### `FileMode`
Once you have retrived a `FileMode` from a `Header` in a `CPIOArchiveReader`, you can access the file's type and UNIX permissions.
#### File Type
```swift
let type = header.mode.typeswitch type {
case .regular: // Regular file.
case .directory: // Directory.
case .symlink: // Symbolic link.
...
}
```#### Permissions
To access the UNIX permissions, use the `permissions` variable in `FileMode`.
## Examples
- `Examples/CreateReadWrite`: This example shows how to use CPIOArchiveKit to read, create, or extract an archive; or compute a checksum for an archive using only `Darwin.C` (macOS), `Glibc` (Linux) or `ucrt` (Windows (not tested)).
## Other Platforms
CPIOArchiveKit doesn't depend on any library, `Foundation`, or `Darwin`/`Glibc`/`ucrt` - only the Swift standard library. It should compile on any platform where the standard library compiles.
### Windows
CPIOArchiveKit is currently being built on Windows, but not tested, as the [Swift Package Manager Resources](https://github.com/apple/swift-evolution/blob/main/proposals/0271-package-manager-resources.md) doesn't seem to work (or isn't available) on Windows.
## Contributing
Before committing, please install [pre-commit](https://pre-commit.com), [swift-format](https://github.com/nicklockwood/SwiftFormat), and [Prettier](https://prettier.io), then install the pre-commit hook:
```bash
$ brew bundle # install the packages specified in Brewfile
$ pre-commit install# Commit your changes.
```To install pre-commit on other platforms, refer to the [documentation](https://pre-commit.com/#install).