-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat(deed-read): Rust .deed reader + fail-closed (updates) vocabulary #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| name: deed-read | ||
|
|
||
| # Builds and tests rs/deed-read, the Rust reader for .deed files and the | ||
| # (updates …) vocabulary. | ||
| # | ||
| # Deliberately NO `paths:` filter: a path-filtered workflow never reports on | ||
| # PRs outside its paths, so its check could never be made required without | ||
| # deadlocking those PRs. The build takes seconds. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| branches: [main] | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| defaults: | ||
| run: | ||
| working-directory: rs/deed-read | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Toolchain | ||
| run: rustc --version && cargo --version | ||
| - name: Test | ||
| run: cargo test --locked | ||
| - name: Clippy | ||
| run: cargo clippy --locked --all-targets -- -D warnings | ||
| - name: Docs | ||
| env: | ||
| RUSTDOCFLAGS: -D warnings | ||
| run: cargo doc --locked --no-deps | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
| /target/ |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # SPDX-License-Identifier: MPL-2.0 | ||
|
|
||
| [package] | ||
| name = "deed-read" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
| rust-version = "1.82" | ||
| authors = ["Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>"] | ||
| license = "MPL-2.0" | ||
| description = "Reader for the estate DEED (.deed) format and its vocabularies" | ||
| repository = "https://github.com/hyperpolymath/deed-ecosystem/tree/main/rs/deed-read" | ||
| readme = "README.adoc" | ||
| publish = false | ||
|
|
||
| # An independent root. `rs/` is the legacy `a2ml` package, not a workspace; | ||
| # this crate does not join or depend on it. | ||
| [workspace] | ||
|
|
||
| [dependencies] | ||
| anyhow = "1" | ||
|
|
||
| [dev-dependencies] | ||
| sha2 = "0.10" | ||
| hex = "0.4" |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,79 @@ | ||||||||||||||||||||
| // SPDX-License-Identifier: MPL-2.0 | ||||||||||||||||||||
| = deed-read | ||||||||||||||||||||
| :toc: macro | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Rust reader for the estate's `.deed` format and its vocabularies. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| toc::[] | ||||||||||||||||||||
|
|
||||||||||||||||||||
| == What it does | ||||||||||||||||||||
|
|
||||||||||||||||||||
| [cols="1,3"] | ||||||||||||||||||||
| |=== | ||||||||||||||||||||
| | Module | Purpose | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | `syntax` | ||||||||||||||||||||
| | Parses any deed against the normative grammar, | ||||||||||||||||||||
| `1-formats/deed/spec/abnf/deed.abnf` in `hyperpolymath/standards`. It rejects | ||||||||||||||||||||
| what that grammar rejects: tabs, `true`/`false` instead of `#t`/`#f`, a missing | ||||||||||||||||||||
| `:schema-version`, an unknown document head, unbalanced forms. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | `updates` | ||||||||||||||||||||
| | Reads the `(updates …)` repo-deed clause: the per-repo switch for automated | ||||||||||||||||||||
| dependency updates. Normative text: `1-formats/deed/vocabulary/updates.adoc`; | ||||||||||||||||||||
| policy: `docs/DEPENDABOT-POLICY.adoc` (owner ruling D269). | ||||||||||||||||||||
| |=== | ||||||||||||||||||||
|
|
||||||||||||||||||||
| [source,rust] | ||||||||||||||||||||
| ---- | ||||||||||||||||||||
| use deed_read::updates; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let policy = updates::from_path(std::path::Path::new("my-repo_chora.deed"))?; | ||||||||||||||||||||
| if !policy.enabled { /* arm nothing */ } | ||||||||||||||||||||
| ---- | ||||||||||||||||||||
|
Comment on lines
+31
to
+33
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value The README example does not compile as written. The example uses the Wrap the example in a function that returns 📝 Proposed fix-let policy = updates::from_path(std::path::Path::new("my-repo_chora.deed"))?;
-if !policy.enabled { /* arm nothing */ }
+fn main() -> Result<(), deed_read::updates::UpdatesError> {
+ let policy = updates::from_path(std::path::Path::new("my-repo_chora.deed"))?;
+ if !policy.enabled { /* arm nothing */ }
+ Ok(())
+}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||
|
|
||||||||||||||||||||
| == Fails closed | ||||||||||||||||||||
|
|
||||||||||||||||||||
| The `(updates …)` clause is how a repo turns automation *off*. A reader that | ||||||||||||||||||||
| skipped what it did not recognise would read the typo `:enabeld #f` as "on". | ||||||||||||||||||||
| So any of the following is an `UpdatesError`, and the caller must arm nothing | ||||||||||||||||||||
| for that repo and report the error: | ||||||||||||||||||||
|
|
||||||||||||||||||||
| * an unknown or repeated field; | ||||||||||||||||||||
| * an unknown nested clause; | ||||||||||||||||||||
| * a wrongly typed value (no coercion: `"no"` is not `#f`); | ||||||||||||||||||||
| * a negative `:soak-days`; | ||||||||||||||||||||
| * a `(hold …)` without `:reason`; | ||||||||||||||||||||
| * an impossible `:until` date; | ||||||||||||||||||||
| * the clause outside a `repo-deed`, or appearing twice; | ||||||||||||||||||||
| * a deed that does not parse, or cannot be read. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| A *missing* deed, or one with no clause, is not an error: the defaults apply | ||||||||||||||||||||
| (enabled, majors on, no soak). | ||||||||||||||||||||
|
|
||||||||||||||||||||
| == Provenance and the duplication window | ||||||||||||||||||||
|
|
||||||||||||||||||||
| `src/syntax.rs` and `tests/deed_corpus.rs` are copied from | ||||||||||||||||||||
| `hyperpolymath/launch-scaffolder` `crates/launcher-common` at `154b9b61`. The | ||||||||||||||||||||
| header, the import path and added one-line `///` docstrings differ; the code | ||||||||||||||||||||
| does not. Until launch-scaffolder replaces its | ||||||||||||||||||||
| copy with a dependency on this crate, there are two copies. Each is checked | ||||||||||||||||||||
| against the same vendored corpus (`tests/fixtures/deed/MANIFEST.sha256`), so if | ||||||||||||||||||||
| one drifts, the manifest test catches it. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| This crate is its own Cargo root. The `rs/` directory around it holds the | ||||||||||||||||||||
| legacy `a2ml` package, which this crate does not join or depend on. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| == Tests | ||||||||||||||||||||
|
|
||||||||||||||||||||
| [source,sh] | ||||||||||||||||||||
| ---- | ||||||||||||||||||||
| cargo test # syntax corpus, hub conformance/, (updates …) rules | ||||||||||||||||||||
| ---- | ||||||||||||||||||||
|
|
||||||||||||||||||||
| `tests/hub_conformance.rs` also checks this hub's `conformance/*.deed` files: | ||||||||||||||||||||
| the 4 valid ones must parse and the 5 invalid ones must be rejected. The | ||||||||||||||||||||
| `(updates …)` fixture lives in `tests/fixtures/`, not `conformance/`, because | ||||||||||||||||||||
| `conformance/run-deed-tests.sh` asserts exact file counts. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| CI: `.github/workflows/deed-read.yml`. | ||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| // SPDX-License-Identifier: MPL-2.0 | ||
| //! Reader for the estate's `.deed` format. | ||
| //! | ||
| //! * [`syntax`] parses any deed against the normative grammar | ||
| //! (`1-formats/deed/spec/abnf/deed.abnf` in `hyperpolymath/standards`). | ||
| //! * [`updates`] reads the `(updates …)` repo-deed vocabulary | ||
| //! (`1-formats/deed/vocabulary/updates.adoc`), failing closed. | ||
|
|
||
| pub mod syntax; | ||
| pub mod updates; | ||
|
|
||
| pub use syntax::{parse, Node, Value}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Add a
concurrencygroup to cancel superseded runs.The workflow has no
concurrencysetting. Repeated pushes to one pull request start overlapping runs that waste runner minutes. Cancel superseded runs on pull requests only, somainruns always finish.⚙️ Proposed fix
📝 Committable suggestion
🧰 Tools
🪛 zizmor (1.30.1)
[warning] 11-16: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Source: Linters/SAST tools