feat!: one paperspec command with subcommands, help and examples
The six console scripts (paperspec-check, -build, -validate, -load, -stress, -site) become subcommands of a single `paperspec` command: paperspec validate, load, check, build, stress and site. `python -m paperspec COMMAND` runs the same thing. - paperspec/cli/main.py builds the whole parser, apart from the commands, so `paperspec --help` and `paperspec COMMAND --help` work without a checkout or the tools extra; a command's module is imported only when it runs. - `paperspec` with no command prints the overview: what each command does, examples, and which work anywhere (validate, load) and which need a checkout (check, build, stress, site). Each command's help has a description with advice, and worked examples; a misspelled command gets a suggestion (argparse suggest_on_error); `--version` prints the version and the pinned Unicode version. - Each command module exposes run(args) and returns the exit status. Arguments that parse but do not fit together raise UsageError, which prints the command's usage and exits 2: load now also refuses --built-from or --store without --bundle. - The failure messages say what to do: install paperspec[tools], clone the repository, rerun stress with the printed seed, or run paperspec build when the rebuild check differs. check and stress say how many failures they did not list. - check runs the rebuild as `python -m paperspec build`. - pyproject installs one script, `paperspec`; the pixi tasks and the docs use the subcommands. pixi run check passes (run here as `python -m paperspec check` with src/ on the path); the rebuild is byte-identical. pixi.lock still needs `pixi lock`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
30 files changed
+385
-174
No files matched your search
+1
-1
@@ -428,7 +428,7 @@ Keep using it as a reading and distribution format.
|
||||
*Status.*
|
||||
The specification is version 0.1.0.
|
||||
`registry/formats.json` lists 32 formats: 19 are `candidate` (complete, with vectors and fixtures, ready to implement) and 13 are `provisional` (complete; expected to change as implementations gain experience): project, bundle, dataset, digitization, view, snapshot, draft-ids, exercise, submission, grade, checklist, log-entry and checkpoint ([spec/00 §0.4](../spec/00-introduction.md#04-status)).
|
||||
The repository holds 24 chapters, 42 JSON Schemas, 25 vector files, five valid fixture packages, one of them also zipped, and 31 invalid ones, each naming the rule it breaks, and a reference checker, `paperspec-check`.
|
||||
The repository holds 24 chapters, 42 JSON Schemas, 25 vector files, five valid fixture packages, one of them also zipped, and 31 invalid ones, each naming the rule it breaks, and a reference checker, `paperspec check`.
|
||||
Licenses: prose CC BY 4.0; schemas, SQL, the JSON-LD context, registries, vectors and fixtures CC0 1.0; tools Apache-2.0 ([README.md](../README.md#licenses)).
|
||||
|
||||
*No adoption claim.*
|
||||
|
||||
+5
-5
@@ -19,10 +19,10 @@ This shows how to confirm that the repository's specification, fixtures and test
|
||||
pixi run check
|
||||
```
|
||||
|
||||
`pixi run check` lints the Markdown, then runs `paperspec-check`, the repository's reference checker.
|
||||
`pixi run check` lints the Markdown, then runs `paperspec check`, the repository's reference checker.
|
||||
Each section prints how many checks it ran, and the last line is `All checks pass.`
|
||||
`pixi run quick`, or `paperspec-check --quick`, skips the slowest part, which rebuilds everything and compares it byte for byte.
|
||||
Without pixi, the Markdown lint is a separate step (`markdownlint-cli2`); `paperspec-check` does not run it.
|
||||
`pixi run quick`, or `paperspec check --quick`, skips the slowest part, which rebuilds everything and compares it byte for byte.
|
||||
Without pixi, the Markdown lint is a separate step (`markdownlint-cli2`); `paperspec check` does not run it.
|
||||
|
||||
## Recompute a hash by hand
|
||||
|
||||
@@ -146,7 +146,7 @@ This shows that the same packages can live in a database and be queried with SQL
|
||||
pixi run load --sqlite lab.db fixtures/packages/hale2026harmonic-damb fixtures/packages/okafor2025solvent-acth fixtures/packages/writer2027fixed-ynr7.v3
|
||||
```
|
||||
|
||||
Without pixi, run `paperspec-load` with the same arguments.
|
||||
Without pixi, run `paperspec load` with the same arguments.
|
||||
|
||||
```text
|
||||
hale2026harmonic-damb: 75 nodes
|
||||
@@ -154,7 +154,7 @@ okafor2025solvent-acth: 15 nodes
|
||||
writer2027fixed-ynr7.v3: 15 nodes
|
||||
```
|
||||
|
||||
The tables are those of [sql/doc.sql](../sql/doc.sql) and [sql/store.sql](../sql/store.sql), which run unchanged on Dolt and PostgreSQL as well ([chapter 13](../spec/13-database.md)); `paperspec-check` exercises them on SQLite only, and this repository has not yet run them on Dolt or PostgreSQL.
|
||||
The tables are those of [sql/doc.sql](../sql/doc.sql) and [sql/store.sql](../sql/store.sql), which run unchanged on Dolt and PostgreSQL as well ([chapter 13](../spec/13-database.md)); `paperspec check` exercises them on SQLite only, and this repository has not yet run them on Dolt or PostgreSQL.
|
||||
Here are four queries, in Python's `sqlite3` so that nothing else is needed.
|
||||
|
||||
```python
|
||||
|
||||
+2
-2
@@ -107,7 +107,7 @@ A `candidate` format is complete, with vectors and fixtures, and ready to implem
|
||||
A `provisional` one is complete and expected to change as implementations gain experience.
|
||||
The provisional formats are dataset, digitization, view, project, bundle, snapshot, draft-ids, exercise, submission, grade, checklist, log-entry and checkpoint.
|
||||
|
||||
The repository holds a reference checker (`paperspec-check`), 25 vector files, five valid packages, one of them also as a zip, and 31 deliberately broken packages ([spec/00 §0.4](../spec/00-introduction.md#04-status), [spec/22](../spec/22-conformance.md)).
|
||||
The repository holds a reference checker (`paperspec check`), 25 vector files, five valid packages, one of them also as a zip, and 31 deliberately broken packages ([spec/00 §0.4](../spec/00-introduction.md#04-status), [spec/22](../spec/22-conformance.md)).
|
||||
|
||||
## What does it not do?
|
||||
|
||||
@@ -126,6 +126,6 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md).
|
||||
|
||||
## What are the files in `tools/` for?
|
||||
|
||||
`paperspec-build` builds the fixtures and vectors. `paperspec-check` recomputes and checks every one, and `paperspec-load` loads packages into SQLite.
|
||||
`paperspec build` builds the fixtures and vectors. `paperspec check` recomputes and checks every one, and `paperspec load` loads packages into SQLite.
|
||||
The oracle's modules in `src/paperspec/` compute every expected value, so that none is typed by hand.
|
||||
The other repositories of the project install them as the Python package `paperspec`; independent implementations follow the specification ([tools/README.md](../tools/README.md)).
|
||||
+3
-3
@@ -54,7 +54,7 @@ It appears inside hashed data and test vectors, and it is separate from the repo
|
||||
| [spec/](../spec/README.md) | The specification, in 24 chapters (00 to 23). Normative. |
|
||||
| [schemas/](../schemas/README.md) | 42 JSON (plain-text data format) Schemas for the files and records. |
|
||||
| [registry/](../registry/README.md) | The list of formats, the rule IDs a checker reports, download-stamp rules, and default rights requirements. |
|
||||
| [tools/](../tools/README.md) | How to run the reference commands: `paperspec-check` checks everything, `paperspec-build` rebuilds the fixtures and vectors, and `paperspec-load` loads packages into SQLite. |
|
||||
| [tools/](../tools/README.md) | How to run the reference commands: `paperspec check` checks everything, `paperspec build` rebuilds the fixtures and vectors, and `paperspec load` loads packages into SQLite. |
|
||||
| [src/paperspec/](../src/paperspec/) | The oracle, a compact implementation of every rule, which the other repositories of the project install as the Python package `paperspec`. |
|
||||
| [vectors/](../vectors/README.md) | 25 files of test vectors: inputs and the exact outputs every implementation must compute. |
|
||||
| [fixtures/](../fixtures/README.md) | Five valid example packages, one of them also as a zip, 31 deliberately broken ones that each break one named rule, example records, and the test keys that signed them. All text is synthetic. |
|
||||
@@ -73,8 +73,8 @@ The repository ships reference tools only for the checker and store roles.
|
||||
| Reader | Opens a package, resolves addresses and anchors, and shows text, annotations and each passage's fidelity level. |
|
||||
| Writer | Produces files in these formats: nodes, corrections, receipts, annotations, datasets. |
|
||||
| Converter | Turns a witness (a PDF, JATS XML, the article format publishers use, a LaTeX source archive, an HTML page, an EPUB or a Typst project) into a package and raises doubtful readings as suspects (flagged disagreements awaiting review). |
|
||||
| Checker | Recomputes hashes, validates files against their schemas and reports broken rules by rule ID. `paperspec-check` does this for the repository. |
|
||||
| Store | Keeps packages and records in a database a team can clone. `paperspec-load` loads packages into SQLite. |
|
||||
| Checker | Recomputes hashes, validates files against their schemas and reports broken rules by rule ID. `paperspec check` does this for the repository. |
|
||||
| Store | Keeps packages and records in a database a team can clone. `paperspec load` loads packages into SQLite. |
|
||||
|
||||
The [specification's reading paths](../spec/README.md) say which chapters each role needs.
|
||||
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ It has nothing to do with the repository's name.
|
||||
|
||||
Open [fixtures/packages/hale2026harmonic-damb/](../fixtures/packages/hale2026harmonic-damb/) beside this page, because every ID below is in it.
|
||||
A package is a folder of files, mostly JSON Lines (`.jsonl`: one JSON record per line).
|
||||
The hand-written source of the first reading is [fixtures/src/hale2026harmonic.json](../fixtures/src/hale2026harmonic.json); no converter ran on it, and [`paperspec-build`](../src/paperspec/cli/build.py) expands it into the package.
|
||||
The hand-written source of the first reading is [fixtures/src/hale2026harmonic.json](../fixtures/src/hale2026harmonic.json); no converter ran on it, and [`paperspec build`](../src/paperspec/cli/build.py) expands it into the package.
|
||||
Each step says what a converter, a person or a checker does.
|
||||
|
||||
## 1. A PDF arrives
|
||||
@@ -166,7 +166,7 @@ It is a [Frictionless Data Package](https://datapackage.org/standard/data-packag
|
||||
Its CSV keeps every digit as printed (`1.526` and `1.5260` stay different), and every value has an anchor to the cell that prints it, so a claim that rests on a value can show the cell.
|
||||
The descriptor types the fields as numbers; how a generic Data Package tool treats `1.5260` was not verified.
|
||||
All twelve value anchors resolve as `current`.
|
||||
The reference checker, [`paperspec-check`](../src/paperspec/cli/check.py), confirms each CSV value equals its cell's text.
|
||||
The reference checker, [`paperspec check`](../src/paperspec/cli/check.py), confirms each CSV value equals its cell's text.
|
||||
|
||||
## 8. Sharing without the text
|
||||
|
||||
|
||||
Reference in new issue
Block a user