openarchieven 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openarchieven-0.1.0/.github/workflows/ci.yml +47 -0
- openarchieven-0.1.0/.github/workflows/homebrew.yml +78 -0
- openarchieven-0.1.0/.github/workflows/release.yml +161 -0
- openarchieven-0.1.0/.gitignore +12 -0
- openarchieven-0.1.0/CHANGELOG.md +26 -0
- openarchieven-0.1.0/CLAUDE.md +38 -0
- openarchieven-0.1.0/Cargo.lock +2827 -0
- openarchieven-0.1.0/Cargo.toml +49 -0
- openarchieven-0.1.0/LICENSE +21 -0
- openarchieven-0.1.0/Makefile +91 -0
- openarchieven-0.1.0/PKG-INFO +51 -0
- openarchieven-0.1.0/README.md +28 -0
- openarchieven-0.1.0/openarchieven/__init__.py +10 -0
- openarchieven-0.1.0/prek.toml +22 -0
- openarchieven-0.1.0/pyproject.toml +37 -0
- openarchieven-0.1.0/scripts/render-homebrew-formula.sh +74 -0
- openarchieven-0.1.0/src/cache.rs +725 -0
- openarchieven-0.1.0/src/cli.rs +155 -0
- openarchieven-0.1.0/src/client.rs +428 -0
- openarchieven-0.1.0/src/commands/archives.rs +72 -0
- openarchieven-0.1.0/src/commands/births.rs +209 -0
- openarchieven-0.1.0/src/commands/cache_cmd.rs +112 -0
- openarchieven-0.1.0/src/commands/census.rs +290 -0
- openarchieven-0.1.0/src/commands/deaths.rs +205 -0
- openarchieven-0.1.0/src/commands/event_records.rs +188 -0
- openarchieven-0.1.0/src/commands/marriages.rs +218 -0
- openarchieven-0.1.0/src/commands/match_record.rs +189 -0
- openarchieven-0.1.0/src/commands/mod.rs +19 -0
- openarchieven-0.1.0/src/commands/search.rs +553 -0
- openarchieven-0.1.0/src/commands/show.rs +200 -0
- openarchieven-0.1.0/src/commands/stats/archive_stat.rs +151 -0
- openarchieven-0.1.0/src/commands/stats/comments.rs +64 -0
- openarchieven-0.1.0/src/commands/stats/events.rs +64 -0
- openarchieven-0.1.0/src/commands/stats/familynames.rs +390 -0
- openarchieven-0.1.0/src/commands/stats/firstnames.rs +269 -0
- openarchieven-0.1.0/src/commands/stats/mod.rs +8 -0
- openarchieven-0.1.0/src/commands/stats/professions.rs +342 -0
- openarchieven-0.1.0/src/commands/stats/records.rs +64 -0
- openarchieven-0.1.0/src/commands/stats/sources.rs +64 -0
- openarchieven-0.1.0/src/commands/weather.rs +294 -0
- openarchieven-0.1.0/src/commands/yearsago.rs +200 -0
- openarchieven-0.1.0/src/error.rs +229 -0
- openarchieven-0.1.0/src/lib.rs +11 -0
- openarchieven-0.1.0/src/main.rs +214 -0
- openarchieven-0.1.0/src/output.rs +497 -0
- openarchieven-0.1.0/src/runtime.rs +256 -0
- openarchieven-0.1.0/src/schema_cmd.rs +261 -0
- openarchieven-0.1.0/src/tty.rs +116 -0
- openarchieven-0.1.0/tests/archives.rs +101 -0
- openarchieven-0.1.0/tests/cache_cmd.rs +101 -0
- openarchieven-0.1.0/tests/census.rs +195 -0
- openarchieven-0.1.0/tests/cli_smoke.rs +119 -0
- openarchieven-0.1.0/tests/client_cache.rs +172 -0
- openarchieven-0.1.0/tests/client_http.rs +127 -0
- openarchieven-0.1.0/tests/client_retry.rs +133 -0
- openarchieven-0.1.0/tests/event_records.rs +259 -0
- openarchieven-0.1.0/tests/match.rs +107 -0
- openarchieven-0.1.0/tests/schema.rs +67 -0
- openarchieven-0.1.0/tests/search.rs +156 -0
- openarchieven-0.1.0/tests/show.rs +190 -0
- openarchieven-0.1.0/tests/snapshots/schema__schema_is_byte_stable.snap +1140 -0
- openarchieven-0.1.0/tests/stats_archive.rs +186 -0
- openarchieven-0.1.0/tests/stats_familynames.rs +264 -0
- openarchieven-0.1.0/tests/stats_firstnames.rs +158 -0
- openarchieven-0.1.0/tests/stats_professions.rs +144 -0
- openarchieven-0.1.0/tests/weather.rs +186 -0
- openarchieven-0.1.0/tests/yearsago.rs +157 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CARGO_TERM_COLOR: always
|
|
11
|
+
RUST_BACKTRACE: 1
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
check:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install Rust toolchain
|
|
20
|
+
uses: dtolnay/rust-toolchain@stable
|
|
21
|
+
with:
|
|
22
|
+
components: rustfmt, clippy
|
|
23
|
+
|
|
24
|
+
- uses: Swatinem/rust-cache@v2
|
|
25
|
+
|
|
26
|
+
- name: Install cargo-nextest
|
|
27
|
+
uses: taiki-e/install-action@nextest
|
|
28
|
+
|
|
29
|
+
- name: make check
|
|
30
|
+
run: make check
|
|
31
|
+
|
|
32
|
+
build:
|
|
33
|
+
runs-on: ${{ matrix.os }}
|
|
34
|
+
strategy:
|
|
35
|
+
fail-fast: false
|
|
36
|
+
matrix:
|
|
37
|
+
os: [ubuntu-latest, macos-latest]
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- name: Install Rust toolchain
|
|
42
|
+
uses: dtolnay/rust-toolchain@stable
|
|
43
|
+
|
|
44
|
+
- uses: Swatinem/rust-cache@v2
|
|
45
|
+
|
|
46
|
+
- name: make build
|
|
47
|
+
run: make build
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: Homebrew
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_run:
|
|
5
|
+
workflows: [Release]
|
|
6
|
+
types: [completed]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
tag:
|
|
10
|
+
description: "Release tag (e.g. v0.1.0)"
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
update-tap:
|
|
16
|
+
name: Update Homebrew tap
|
|
17
|
+
# workflow_run fires on every Release run, including failures — gate
|
|
18
|
+
# on success here. workflow_dispatch always runs.
|
|
19
|
+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Resolve release tag
|
|
25
|
+
id: tag
|
|
26
|
+
run: |
|
|
27
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
28
|
+
tag="${{ inputs.tag }}"
|
|
29
|
+
else
|
|
30
|
+
# workflow_run fires for tag-triggered Release runs;
|
|
31
|
+
# head_branch holds the tag name in that case.
|
|
32
|
+
tag="${{ github.event.workflow_run.head_branch }}"
|
|
33
|
+
fi
|
|
34
|
+
if [ -z "$tag" ] || [ "${tag#v}" = "$tag" ]; then
|
|
35
|
+
echo "could not resolve a v* release tag (got: '$tag')" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
|
|
39
|
+
echo "version=${tag#v}" >> "$GITHUB_OUTPUT"
|
|
40
|
+
|
|
41
|
+
- name: Download release sha256 sidecars
|
|
42
|
+
env:
|
|
43
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
44
|
+
run: |
|
|
45
|
+
mkdir -p dist
|
|
46
|
+
gh release download "${{ steps.tag.outputs.tag }}" \
|
|
47
|
+
--repo "${GITHUB_REPOSITORY}" \
|
|
48
|
+
--pattern "*.sha256" \
|
|
49
|
+
--dir dist
|
|
50
|
+
|
|
51
|
+
- name: Render formula
|
|
52
|
+
run: |
|
|
53
|
+
make homebrew-formula \
|
|
54
|
+
VERSION=${{ steps.tag.outputs.version }} \
|
|
55
|
+
TAG=${{ steps.tag.outputs.tag }}
|
|
56
|
+
|
|
57
|
+
- name: Push formula to homebrew-tap
|
|
58
|
+
env:
|
|
59
|
+
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
60
|
+
run: |
|
|
61
|
+
if [ -z "${GH_TOKEN}" ]; then
|
|
62
|
+
echo "HOMEBREW_TAP_TOKEN secret is not set; cannot push to tap." >&2
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
tag="${{ steps.tag.outputs.tag }}"
|
|
66
|
+
git clone "https://x-access-token:${GH_TOKEN}@github.com/rvben/homebrew-tap.git" /tmp/tap
|
|
67
|
+
mkdir -p /tmp/tap/Formula
|
|
68
|
+
cp dist/openarchieven.rb /tmp/tap/Formula/openarchieven.rb
|
|
69
|
+
cd /tmp/tap
|
|
70
|
+
git config user.name "github-actions[bot]"
|
|
71
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
72
|
+
git add Formula/openarchieven.rb
|
|
73
|
+
if git diff --cached --quiet; then
|
|
74
|
+
echo "Formula already up to date for ${tag}; nothing to push."
|
|
75
|
+
else
|
|
76
|
+
git commit -m "Update openarchieven to ${tag}"
|
|
77
|
+
git push
|
|
78
|
+
fi
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
CARGO_TERM_COLOR: always
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
name: Build ${{ matrix.target }}
|
|
17
|
+
runs-on: ${{ matrix.os }}
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
include:
|
|
22
|
+
- target: x86_64-unknown-linux-gnu
|
|
23
|
+
os: ubuntu-latest
|
|
24
|
+
maturin_args: --compatibility manylinux_2_28 --zig
|
|
25
|
+
- target: aarch64-unknown-linux-gnu
|
|
26
|
+
os: ubuntu-latest
|
|
27
|
+
maturin_args: --compatibility manylinux_2_28 --zig
|
|
28
|
+
- target: x86_64-apple-darwin
|
|
29
|
+
os: macos-latest
|
|
30
|
+
maturin_args: ""
|
|
31
|
+
- target: aarch64-apple-darwin
|
|
32
|
+
os: macos-latest
|
|
33
|
+
maturin_args: ""
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Install Rust toolchain
|
|
38
|
+
uses: dtolnay/rust-toolchain@stable
|
|
39
|
+
with:
|
|
40
|
+
targets: ${{ matrix.target }}
|
|
41
|
+
|
|
42
|
+
- uses: Swatinem/rust-cache@v2
|
|
43
|
+
|
|
44
|
+
- uses: astral-sh/setup-uv@v6
|
|
45
|
+
|
|
46
|
+
- name: Install maturin (with zig for cross-compiled Linux wheels)
|
|
47
|
+
shell: bash
|
|
48
|
+
run: |
|
|
49
|
+
uv venv "${RUNNER_TEMP}/build-venv"
|
|
50
|
+
uv pip install --python "${RUNNER_TEMP}/build-venv/bin/python" maturin ziglang
|
|
51
|
+
echo "${RUNNER_TEMP}/build-venv/bin" >> "$GITHUB_PATH"
|
|
52
|
+
|
|
53
|
+
- name: Compute version from tag
|
|
54
|
+
id: version
|
|
55
|
+
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
|
56
|
+
|
|
57
|
+
- name: make build-wheel
|
|
58
|
+
run: make build-wheel TARGET=${{ matrix.target }} MATURIN_ARGS="${{ matrix.maturin_args }}"
|
|
59
|
+
|
|
60
|
+
- name: make release-archive
|
|
61
|
+
run: |
|
|
62
|
+
make release-archive \
|
|
63
|
+
TARGET=${{ matrix.target }} \
|
|
64
|
+
VERSION=${{ steps.version.outputs.version }}
|
|
65
|
+
|
|
66
|
+
- name: Upload binary archive
|
|
67
|
+
uses: actions/upload-artifact@v4
|
|
68
|
+
with:
|
|
69
|
+
name: binary-${{ matrix.target }}
|
|
70
|
+
path: dist/*
|
|
71
|
+
|
|
72
|
+
- name: Upload wheel
|
|
73
|
+
uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: wheel-${{ matrix.target }}
|
|
76
|
+
path: target/wheels/*.whl
|
|
77
|
+
|
|
78
|
+
sdist:
|
|
79
|
+
name: Build sdist
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/checkout@v4
|
|
83
|
+
- uses: astral-sh/setup-uv@v6
|
|
84
|
+
- name: Install maturin
|
|
85
|
+
shell: bash
|
|
86
|
+
run: |
|
|
87
|
+
uv venv "${RUNNER_TEMP}/build-venv"
|
|
88
|
+
uv pip install --python "${RUNNER_TEMP}/build-venv/bin/python" maturin
|
|
89
|
+
echo "${RUNNER_TEMP}/build-venv/bin" >> "$GITHUB_PATH"
|
|
90
|
+
- name: make build-sdist
|
|
91
|
+
run: make build-sdist
|
|
92
|
+
- uses: actions/upload-artifact@v4
|
|
93
|
+
with:
|
|
94
|
+
name: sdist
|
|
95
|
+
path: target/wheels/*.tar.gz
|
|
96
|
+
|
|
97
|
+
release:
|
|
98
|
+
name: Publish release
|
|
99
|
+
needs: build
|
|
100
|
+
runs-on: ubuntu-latest
|
|
101
|
+
steps:
|
|
102
|
+
- uses: actions/checkout@v4
|
|
103
|
+
|
|
104
|
+
- uses: actions/download-artifact@v4
|
|
105
|
+
with:
|
|
106
|
+
pattern: binary-*
|
|
107
|
+
path: dist
|
|
108
|
+
merge-multiple: true
|
|
109
|
+
|
|
110
|
+
- name: Create GitHub Release
|
|
111
|
+
env:
|
|
112
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
113
|
+
run: |
|
|
114
|
+
version="${GITHUB_REF_NAME#v}"
|
|
115
|
+
notes_file=$(mktemp)
|
|
116
|
+
if [ -f CHANGELOG.md ]; then
|
|
117
|
+
awk -v v="$version" '
|
|
118
|
+
/^## / { if (in_section) exit; if ($2 == v || $2 == "v"v || $2 == "["v"]") in_section = 1; next }
|
|
119
|
+
in_section
|
|
120
|
+
' CHANGELOG.md > "$notes_file"
|
|
121
|
+
fi
|
|
122
|
+
if [ ! -s "$notes_file" ]; then
|
|
123
|
+
echo "Release $version" > "$notes_file"
|
|
124
|
+
fi
|
|
125
|
+
gh release create "$GITHUB_REF_NAME" \
|
|
126
|
+
--title "$GITHUB_REF_NAME" \
|
|
127
|
+
--notes-file "$notes_file" \
|
|
128
|
+
dist/*
|
|
129
|
+
|
|
130
|
+
publish-crates:
|
|
131
|
+
name: Publish to crates.io
|
|
132
|
+
needs: release
|
|
133
|
+
runs-on: ubuntu-latest
|
|
134
|
+
steps:
|
|
135
|
+
- uses: actions/checkout@v4
|
|
136
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
137
|
+
- name: make publish-crates
|
|
138
|
+
env:
|
|
139
|
+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
140
|
+
run: make publish-crates
|
|
141
|
+
|
|
142
|
+
publish-pypi:
|
|
143
|
+
name: Publish to PyPI
|
|
144
|
+
needs: [build, sdist]
|
|
145
|
+
runs-on: ubuntu-latest
|
|
146
|
+
steps:
|
|
147
|
+
- uses: actions/checkout@v4
|
|
148
|
+
- uses: actions/download-artifact@v4
|
|
149
|
+
with:
|
|
150
|
+
pattern: wheel-*
|
|
151
|
+
path: artifacts/wheels
|
|
152
|
+
- uses: actions/download-artifact@v4
|
|
153
|
+
with:
|
|
154
|
+
name: sdist
|
|
155
|
+
path: artifacts/sdist
|
|
156
|
+
- uses: astral-sh/setup-uv@v6
|
|
157
|
+
- name: make publish-pypi
|
|
158
|
+
env:
|
|
159
|
+
TWINE_USERNAME: __token__
|
|
160
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
161
|
+
run: make publish-pypi WHEEL_DIR=artifacts/wheels SDIST_DIR=artifacts/sdist
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-04-30
|
|
8
|
+
|
|
9
|
+
Initial release.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- All 17 endpoints of the openarchieven.nl API v1.1: `archives`, `search`,
|
|
13
|
+
`show`, `match`, `births`, `deaths`, `marriages`, `yearsago`, `census`,
|
|
14
|
+
`weather`, and the seven `stats` subcommands.
|
|
15
|
+
- Three output formats (`json`, `table`, `markdown`) selected automatically by
|
|
16
|
+
TTY/pipe context, overridable with `--output/-o`.
|
|
17
|
+
- `schema` subcommand emits a byte-stable, machine-readable contract for
|
|
18
|
+
scripts and AI agents.
|
|
19
|
+
- On-disk response cache with advisory locking and per-endpoint TTLs;
|
|
20
|
+
`cache info`, `cache prune`, and `cache clear --yes` for management.
|
|
21
|
+
- Built-in rate limiter (4 req/sec default) and retry with jittered backoff
|
|
22
|
+
that respects `Retry-After`.
|
|
23
|
+
- Structured JSON error contract on stderr with stable `kind` enum.
|
|
24
|
+
- `--fields` projection for list and single-flat responses.
|
|
25
|
+
- Distribution: crates.io, PyPI wheel, and Homebrew tap, all published from
|
|
26
|
+
one tag-driven release workflow.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
Guidance for Claude Code working in this repository.
|
|
4
|
+
|
|
5
|
+
## Build & Test
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
make check # lint + test (CI runs this)
|
|
9
|
+
make build # cargo build --release
|
|
10
|
+
make test # cargo nextest run (or cargo test fallback)
|
|
11
|
+
make lint # fmt --check + clippy -D warnings
|
|
12
|
+
make fmt # auto-format
|
|
13
|
+
make install # release build → ~/.local/bin/openarchieven
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
|
|
18
|
+
Binary `openarchieven` wraps the openarchieven.nl API per the design spec at
|
|
19
|
+
`docs/superpowers/specs/2026-04-29-openarchieven-cli-design.md`. Core flow:
|
|
20
|
+
`main.rs` parses args → command module → `Client::get()` (cache + rate limit
|
|
21
|
+
+ retry) → response shaped into `Renderable` → renderer (json/table/markdown)
|
|
22
|
+
→ stdout. Errors always go to stderr as JSON.
|
|
23
|
+
|
|
24
|
+
## Modules
|
|
25
|
+
|
|
26
|
+
- `client.rs`: HTTP, rate limiter, retry/backoff, `Retry-After` parsing.
|
|
27
|
+
- `cache.rs`: on-disk JSON cache with atomic writes and advisory locks.
|
|
28
|
+
- `error.rs`: `ErrorKind` enum and structured stderr emission.
|
|
29
|
+
- `output.rs`: `Renderable` shapes and three renderers.
|
|
30
|
+
- `schema_cmd.rs`: emits the machine-readable schema contract.
|
|
31
|
+
- `commands/<name>.rs`: one module per API endpoint.
|
|
32
|
+
|
|
33
|
+
## Conventions
|
|
34
|
+
|
|
35
|
+
- TDD throughout. Test failure paths explicitly.
|
|
36
|
+
- `cargo nextest run` preferred (fast, token-optimized via RTK).
|
|
37
|
+
- No live network in unit/integration tests — `wiremock` stands in.
|
|
38
|
+
- Schema output is byte-stable; `tests/schema.rs` snapshots it.
|