Policy names five README sections that were missing or misnamed. The Description first line now names the project, purpose, category, WTFPL license, and author. A new Getting Started section gives a copy-pasteable build-from-source block and gen/check/fetch usage; every command was run against a built binary. Problem Statement and Proposed Solution are consolidated under a new Rationale heading, keeping the prose rather than duplicating it. A new Design section documents the package layout: mfer/ library, internal/cli commands, internal/log and internal/bork support, cmd/mfer entrypoint, and the committed protobuf code. Authors is renamed Author with the canonical link. Getting Started uses go build because the make build target invokes protoc, which script/bootstrap does not install. Model: opus-4-8
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# mfer
|
# mfer
|
||||||
|
|
||||||
[mfer](https://git.eeqj.de/sneak/mfer) is a reference implementation library and
|
[mfer](https://git.eeqj.de/sneak/mfer) is a [WTFPL](https://wtfpl.net)-licensed
|
||||||
thin wrapper command-line utility written in [Go](https://golang.org) and first
|
(public domain) [Go](https://golang.org) library and command-line tool by
|
||||||
published in 2022 under the [WTFPL](https://wtfpl.net) (public domain) license.
|
[@sneak](https://sneak.berlin) that specifies and generates `.mf` manifest files
|
||||||
It specifies and generates `.mf` manifest files over a directory tree of files
|
over a directory tree to encapsulate metadata about the files — such as
|
||||||
to encapsulate metadata about them (such as cryptographic checksums or
|
cryptographic checksums and signatures over same — to aid in archiving,
|
||||||
signatures over same) to aid in archiving, downloading, and streaming, or
|
downloading, streaming, and mirroring. It was first published in 2022. The
|
||||||
mirroring. The manifest files' data is serialized with Google's
|
manifest files' data is serialized with Google's
|
||||||
[protobuf serialization format](https://developers.google.com/protocol-buffers).
|
[protobuf serialization format](https://developers.google.com/protocol-buffers).
|
||||||
The structure of these files can be found
|
The structure of these files can be found
|
||||||
[in the format specification](https://git.eeqj.de/sneak/mfer/src/branch/main/mfer/mf.proto)
|
[in the format specification](https://git.eeqj.de/sneak/mfer/src/branch/main/mfer/mf.proto)
|
||||||
@@ -21,6 +21,36 @@ This project was started by [@sneak](https://sneak.berlin) to scratch an itch in
|
|||||||
as a de-facto standard and be incorporated into other software. A compatible
|
as a de-facto standard and be incorporated into other software. A compatible
|
||||||
javascript library is planned.
|
javascript library is planned.
|
||||||
|
|
||||||
|
# Getting Started
|
||||||
|
|
||||||
|
`mfer` builds from source with a Go 1.23+ toolchain. The generated protobuf code
|
||||||
|
is committed, so no `protoc` toolchain is required:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://git.eeqj.de/sneak/mfer.git
|
||||||
|
cd mfer
|
||||||
|
go build -o bin/mfer ./cmd/mfer
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate a manifest for a directory tree, verify it later, and fetch a published
|
||||||
|
tree by URL:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Write .index.mf describing every file under the current directory.
|
||||||
|
bin/mfer gen .
|
||||||
|
|
||||||
|
# Verify the files on disk against the manifest. Exits nonzero if any file
|
||||||
|
# is missing or corrupted.
|
||||||
|
bin/mfer check .index.mf
|
||||||
|
|
||||||
|
# Download and cryptographically verify a tree published over HTTP: mfer
|
||||||
|
# fetches <url>/index.mf, then downloads every file it lists.
|
||||||
|
bin/mfer fetch https://example.com/tree/
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `bin/mfer help` for the full command list, or `bin/mfer <command> --help`
|
||||||
|
for a single command's options.
|
||||||
|
|
||||||
# Build Status
|
# Build Status
|
||||||
|
|
||||||
CI runs via `script/cibuild` (`docker build .`), which executes `make check`
|
CI runs via `script/cibuild` (`docker build .`), which executes `make check`
|
||||||
@@ -81,7 +111,9 @@ Any changes submitted to this project must also be
|
|||||||
See [`REPO_POLICIES.md`](REPO_POLICIES.md) for detailed coding standards,
|
See [`REPO_POLICIES.md`](REPO_POLICIES.md) for detailed coding standards,
|
||||||
tooling requirements, and workflow conventions.
|
tooling requirements, and workflow conventions.
|
||||||
|
|
||||||
# Problem Statement
|
# Rationale
|
||||||
|
|
||||||
|
## The problem
|
||||||
|
|
||||||
Given a plain URL, there is no standard way to safely and programmatically
|
Given a plain URL, there is no standard way to safely and programmatically
|
||||||
download everything "under" that URL path. `wget -r` can traverse directory
|
download everything "under" that URL path. `wget -r` can traverse directory
|
||||||
@@ -105,7 +137,7 @@ Real issues I face:
|
|||||||
- when I download a large file via HTTP, I have no way of knowing if the file
|
- when I download a large file via HTTP, I have no way of knowing if the file
|
||||||
content is what it's supposed to be
|
content is what it's supposed to be
|
||||||
|
|
||||||
# Proposed Solution
|
## The solution
|
||||||
|
|
||||||
A standard, a manifest file format, and a tool for generating same.
|
A standard, a manifest file format, and a tool for generating same.
|
||||||
|
|
||||||
@@ -137,6 +169,27 @@ The manifest file would do several important things:
|
|||||||
- maybe a bittorrent chunklist for torrent client compatibility? perhaps a
|
- maybe a bittorrent chunklist for torrent client compatibility? perhaps a
|
||||||
top-level infohash for the whole manifest?
|
top-level infohash for the whole manifest?
|
||||||
|
|
||||||
|
# Design
|
||||||
|
|
||||||
|
The repository is split into a reusable library and a thin command-line wrapper
|
||||||
|
around it.
|
||||||
|
|
||||||
|
- `mfer/` is the reusable library and the heart of the project: it defines the
|
||||||
|
manifest format and implements building, scanning, checking, serialization,
|
||||||
|
and signing. The protobuf schema is `mfer/mf.proto`, and the generated code it
|
||||||
|
produces (`mfer/mf.pb.go`) is committed alongside it so the library builds
|
||||||
|
with `go get` and needs no `protoc` toolchain.
|
||||||
|
- `internal/cli/` holds the command implementations — `gen`, `check`, `freshen`,
|
||||||
|
`export`, `list`, and `fetch` — that wire the library to the command-line
|
||||||
|
interface.
|
||||||
|
- `internal/log/` provides the logging used across the commands.
|
||||||
|
- `internal/bork/` provides error-handling support.
|
||||||
|
- `cmd/mfer/` is the entrypoint: its `main` package assembles the pieces above
|
||||||
|
into the `mfer` binary.
|
||||||
|
|
||||||
|
Everything under `internal/` is private to this repository; only the `mfer/`
|
||||||
|
package is intended for import by other software.
|
||||||
|
|
||||||
# Design Goals
|
# Design Goals
|
||||||
|
|
||||||
- Replace SHASUMS/SHASUMS.asc files
|
- Replace SHASUMS/SHASUMS.asc files
|
||||||
@@ -462,9 +515,9 @@ proto `go_package` option. Which is canonical?
|
|||||||
- Issues:
|
- Issues:
|
||||||
[https://git.eeqj.de/sneak/mfer/issues](https://git.eeqj.de/sneak/mfer/issues)
|
[https://git.eeqj.de/sneak/mfer/issues](https://git.eeqj.de/sneak/mfer/issues)
|
||||||
|
|
||||||
# Authors
|
# Author
|
||||||
|
|
||||||
- [@sneak <sneak@sneak.berlin>](mailto:sneak@sneak.berlin)
|
- [@sneak](https://sneak.berlin)
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ only thing left of the `chore/align-repo-policies` branch is the list below.
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-09-21: added the required README sections — named author, license, and
|
||||||
|
category in the Description first line; added Getting Started (verified
|
||||||
|
install/usage block), Rationale (folding in Problem Statement and Proposed
|
||||||
|
Solution), and a Design section for the package layout; renamed Authors to
|
||||||
|
Author (#75)
|
||||||
- 2026-09-21: added the canonical `.editorconfig`, made `.gitignore` cover
|
- 2026-09-21: added the canonical `.editorconfig`, made `.gitignore` cover
|
||||||
secrets, OS, editor, and Go artifacts, and removed the dead Drone CI
|
secrets, OS, editor, and Go artifacts, and removed the dead Drone CI
|
||||||
references from `.gitignore` and `bin/gitrev.sh` (#72)
|
references from `.gitignore` and `bin/gitrev.sh` (#72)
|
||||||
|
|||||||
Reference in New Issue
Block a user