pyodcs 0.2.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.
Files changed (86) hide show
  1. pyodcs-0.2.0/.editorconfig +18 -0
  2. pyodcs-0.2.0/.github/workflows/checks.yml +47 -0
  3. pyodcs-0.2.0/.github/workflows/ci.yml +9 -0
  4. pyodcs-0.2.0/.github/workflows/release.yml +217 -0
  5. pyodcs-0.2.0/.gitignore +28 -0
  6. pyodcs-0.2.0/CHANGELOG.md +24 -0
  7. pyodcs-0.2.0/CONTRIBUTING.md +48 -0
  8. pyodcs-0.2.0/Cargo.lock +647 -0
  9. pyodcs-0.2.0/Cargo.toml +49 -0
  10. pyodcs-0.2.0/LICENSE +17 -0
  11. pyodcs-0.2.0/PKG-INFO +119 -0
  12. pyodcs-0.2.0/README.md +94 -0
  13. pyodcs-0.2.0/ROADMAP.md +120 -0
  14. pyodcs-0.2.0/SPEC.md +173 -0
  15. pyodcs-0.2.0/docs/README.md +30 -0
  16. pyodcs-0.2.0/docs/implementation/README.md +26 -0
  17. pyodcs-0.2.0/docs/implementation/architecture.md +25 -0
  18. pyodcs-0.2.0/docs/implementation/cli-spec.md +31 -0
  19. pyodcs-0.2.0/docs/implementation/crate-layout.md +74 -0
  20. pyodcs-0.2.0/docs/implementation/diagnostics-guide.md +32 -0
  21. pyodcs-0.2.0/docs/implementation/implementation-phases.md +78 -0
  22. pyodcs-0.2.0/docs/implementation/model-guide.md +36 -0
  23. pyodcs-0.2.0/docs/implementation/non-goals.md +14 -0
  24. pyodcs-0.2.0/docs/implementation/project-goal.md +29 -0
  25. pyodcs-0.2.0/docs/implementation/public-api.md +23 -0
  26. pyodcs-0.2.0/docs/implementation/relationship-to-dtcs.md +29 -0
  27. pyodcs-0.2.0/docs/implementation/rust-dependencies.md +23 -0
  28. pyodcs-0.2.0/docs/implementation/spec-usage.md +15 -0
  29. pyodcs-0.2.0/docs/implementation/testing-plan.md +18 -0
  30. pyodcs-0.2.0/docs/implementation/validation-guide.md +17 -0
  31. pyodcs-0.2.0/examples/minimal.odcs.json +33 -0
  32. pyodcs-0.2.0/examples/minimal.odcs.yaml +22 -0
  33. pyodcs-0.2.0/pyproject.toml +40 -0
  34. pyodcs-0.2.0/python/pyodcs/__init__.py +75 -0
  35. pyodcs-0.2.0/python/pyodcs/__main__.py +137 -0
  36. pyodcs-0.2.0/python/tests/test_pyodcs.py +54 -0
  37. pyodcs-0.2.0/src/bin/odcs.rs +11 -0
  38. pyodcs-0.2.0/src/cli/mod.rs +279 -0
  39. pyodcs-0.2.0/src/compatibility/mod.rs +3 -0
  40. pyodcs-0.2.0/src/diagnostics/builders.rs +36 -0
  41. pyodcs-0.2.0/src/diagnostics/category.rs +25 -0
  42. pyodcs-0.2.0/src/diagnostics/codes.rs +20 -0
  43. pyodcs-0.2.0/src/diagnostics/diagnostic.rs +71 -0
  44. pyodcs-0.2.0/src/diagnostics/mod.rs +33 -0
  45. pyodcs-0.2.0/src/diagnostics/report.rs +52 -0
  46. pyodcs-0.2.0/src/diagnostics/severity.rs +23 -0
  47. pyodcs-0.2.0/src/diagnostics/stage.rs +21 -0
  48. pyodcs-0.2.0/src/lib.rs +73 -0
  49. pyodcs-0.2.0/src/model/contract.rs +41 -0
  50. pyodcs-0.2.0/src/model/custom.rs +3 -0
  51. pyodcs-0.2.0/src/model/field.rs +20 -0
  52. pyodcs-0.2.0/src/model/fundamentals.rs +3 -0
  53. pyodcs-0.2.0/src/model/mod.rs +21 -0
  54. pyodcs-0.2.0/src/model/pricing.rs +3 -0
  55. pyodcs-0.2.0/src/model/quality.rs +20 -0
  56. pyodcs-0.2.0/src/model/roles.rs +3 -0
  57. pyodcs-0.2.0/src/model/schema.rs +19 -0
  58. pyodcs-0.2.0/src/model/servers.rs +3 -0
  59. pyodcs-0.2.0/src/model/sla.rs +3 -0
  60. pyodcs-0.2.0/src/model/stakeholders.rs +3 -0
  61. pyodcs-0.2.0/src/model/support.rs +3 -0
  62. pyodcs-0.2.0/src/model/team.rs +3 -0
  63. pyodcs-0.2.0/src/model/versioning.rs +3 -0
  64. pyodcs-0.2.0/src/parser/json.rs +35 -0
  65. pyodcs-0.2.0/src/parser/mod.rs +86 -0
  66. pyodcs-0.2.0/src/parser/yaml.rs +35 -0
  67. pyodcs-0.2.0/src/python.rs +128 -0
  68. pyodcs-0.2.0/src/registry/mod.rs +3 -0
  69. pyodcs-0.2.0/src/validation/document.rs +13 -0
  70. pyodcs-0.2.0/src/validation/extensions.rs +13 -0
  71. pyodcs-0.2.0/src/validation/mod.rs +65 -0
  72. pyodcs-0.2.0/src/validation/phases.rs +20 -0
  73. pyodcs-0.2.0/src/validation/quality.rs +13 -0
  74. pyodcs-0.2.0/src/validation/references.rs +13 -0
  75. pyodcs-0.2.0/src/validation/schema.rs +13 -0
  76. pyodcs-0.2.0/src/validation/structural.rs +13 -0
  77. pyodcs-0.2.0/tests/cli.rs +99 -0
  78. pyodcs-0.2.0/tests/fixtures/invalid-empty-name.yaml +4 -0
  79. pyodcs-0.2.0/tests/fixtures/invalid-kind.yaml +4 -0
  80. pyodcs-0.2.0/tests/fixtures/malformed.json +1 -0
  81. pyodcs-0.2.0/tests/fixtures/malformed.yaml +1 -0
  82. pyodcs-0.2.0/tests/fixtures/minimal.odcs.json +33 -0
  83. pyodcs-0.2.0/tests/fixtures/minimal.odcs.yaml +22 -0
  84. pyodcs-0.2.0/tests/fixtures/unsupported-version.yaml +4 -0
  85. pyodcs-0.2.0/tests/fixtures/with-extensions.yaml +7 -0
  86. pyodcs-0.2.0/tests/skeleton.rs +141 -0
@@ -0,0 +1,18 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+
9
+ [*.md]
10
+ trim_trailing_whitespace = false
11
+
12
+ [*.{rs,toml}]
13
+ indent_style = space
14
+ indent_size = 4
15
+
16
+ [*.yaml]
17
+ indent_style = space
18
+ indent_size = 2
@@ -0,0 +1,47 @@
1
+ name: Checks
2
+
3
+ on:
4
+ workflow_call:
5
+
6
+ env:
7
+ CARGO_TERM_COLOR: always
8
+
9
+ jobs:
10
+ python:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: dtolnay/rust-toolchain@stable
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - name: Build and test Python package
19
+ run: |
20
+ python -m venv .venv
21
+ source .venv/bin/activate
22
+ python -m pip install --upgrade pip
23
+ python -m pip install maturin pytest
24
+ maturin develop --features python --locked
25
+ pytest python/tests -v
26
+ - name: maturin build (dry run)
27
+ run: |
28
+ source .venv/bin/activate
29
+ maturin build --features python --locked
30
+
31
+ rust:
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - uses: dtolnay/rust-toolchain@stable
36
+ with:
37
+ components: rustfmt, clippy
38
+ - name: cargo fmt
39
+ run: cargo fmt --all -- --check
40
+ - name: cargo clippy
41
+ run: cargo clippy --all-targets -- -D warnings
42
+ - name: cargo test
43
+ run: cargo test --locked
44
+ - name: cargo build
45
+ run: cargo build --locked --all-targets
46
+ - name: cargo publish (dry run)
47
+ run: cargo publish --dry-run --locked
@@ -0,0 +1,9 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ checks:
9
+ uses: ./.github/workflows/checks.yml
@@ -0,0 +1,217 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ env:
9
+ CARGO_TERM_COLOR: always
10
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
11
+ MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
12
+
13
+ jobs:
14
+ checks:
15
+ uses: ./.github/workflows/checks.yml
16
+
17
+ publish-crates-io:
18
+ needs: checks
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: dtolnay/rust-toolchain@stable
23
+ - name: Verify tag matches crate and Python versions
24
+ run: |
25
+ crate_version=$(grep '^version' Cargo.toml | head -1 | cut -d'"' -f2)
26
+ py_version=$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2)
27
+ tag_version="${GITHUB_REF_NAME#v}"
28
+ if [ "$crate_version" != "$tag_version" ]; then
29
+ echo "Tag ${GITHUB_REF_NAME} (v${tag_version}) does not match Cargo.toml version ${crate_version}"
30
+ exit 1
31
+ fi
32
+ if [ "$py_version" != "$tag_version" ]; then
33
+ echo "Tag ${GITHUB_REF_NAME} (v${tag_version}) does not match pyproject.toml version ${py_version}"
34
+ exit 1
35
+ fi
36
+ - name: cargo publish
37
+ run: |
38
+ set +e
39
+ output="$(cargo publish --locked --token "$CARGO_REGISTRY_TOKEN" 2>&1)"
40
+ code=$?
41
+ echo "$output"
42
+ if [ "$code" -ne 0 ] && echo "$output" | grep -q "already exists on crates.io index"; then
43
+ echo "crate already published; skipping"
44
+ exit 0
45
+ fi
46
+ exit "$code"
47
+
48
+ build-python-linux:
49
+ needs: checks
50
+ runs-on: ${{ matrix.platform.runner }}
51
+ strategy:
52
+ fail-fast: false
53
+ matrix:
54
+ platform:
55
+ - runner: ubuntu-22.04
56
+ target: x86_64
57
+ - runner: ubuntu-22.04
58
+ target: x86
59
+ - runner: ubuntu-22.04
60
+ target: aarch64
61
+ manylinux: 2_28
62
+ - runner: ubuntu-22.04
63
+ target: armv7
64
+ - runner: ubuntu-22.04
65
+ target: s390x
66
+ - runner: ubuntu-22.04
67
+ target: ppc64le
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+ - uses: actions/setup-python@v5
71
+ with:
72
+ python-version: "3.12"
73
+ - name: Build wheels
74
+ uses: PyO3/maturin-action@v1
75
+ with:
76
+ target: ${{ matrix.platform.target }}
77
+ args: --release --out dist --features python --locked --compatibility pypi
78
+ sccache: "true"
79
+ manylinux: ${{ matrix.platform.manylinux || 'auto' }}
80
+ - uses: actions/upload-artifact@v4
81
+ with:
82
+ name: python-dist-linux-${{ matrix.platform.target }}
83
+ path: dist/*
84
+ if-no-files-found: error
85
+
86
+ build-python-musllinux:
87
+ needs: checks
88
+ runs-on: ${{ matrix.platform.runner }}
89
+ strategy:
90
+ fail-fast: false
91
+ matrix:
92
+ platform:
93
+ - runner: ubuntu-22.04
94
+ target: x86_64
95
+ - runner: ubuntu-22.04
96
+ target: x86
97
+ - runner: ubuntu-22.04
98
+ target: aarch64
99
+ - runner: ubuntu-22.04
100
+ target: armv7
101
+ steps:
102
+ - uses: actions/checkout@v4
103
+ - uses: actions/setup-python@v5
104
+ with:
105
+ python-version: "3.12"
106
+ - name: Build wheels
107
+ uses: PyO3/maturin-action@v1
108
+ with:
109
+ target: ${{ matrix.platform.target }}
110
+ args: --release --out dist --features python --locked --compatibility pypi
111
+ sccache: "true"
112
+ manylinux: musllinux_1_2
113
+ - uses: actions/upload-artifact@v4
114
+ with:
115
+ name: python-dist-musllinux-${{ matrix.platform.target }}
116
+ path: dist/*
117
+ if-no-files-found: error
118
+
119
+ build-python-windows:
120
+ needs: checks
121
+ runs-on: ${{ matrix.platform.runner }}
122
+ strategy:
123
+ fail-fast: false
124
+ matrix:
125
+ platform:
126
+ - runner: windows-latest
127
+ target: x64
128
+ python_arch: x64
129
+ - runner: windows-latest
130
+ target: x86
131
+ python_arch: x86
132
+ - runner: windows-11-arm
133
+ target: aarch64
134
+ python_arch: arm64
135
+ steps:
136
+ - uses: actions/checkout@v4
137
+ - uses: actions/setup-python@v5
138
+ with:
139
+ python-version: "3.12"
140
+ architecture: ${{ matrix.platform.python_arch }}
141
+ - name: Build wheels
142
+ uses: PyO3/maturin-action@v1
143
+ with:
144
+ target: ${{ matrix.platform.target }}
145
+ args: --release --out dist --features python --locked --compatibility pypi
146
+ sccache: "true"
147
+ - uses: actions/upload-artifact@v4
148
+ with:
149
+ name: python-dist-windows-${{ matrix.platform.target }}
150
+ path: dist/*
151
+ if-no-files-found: error
152
+
153
+ build-python-macos:
154
+ needs: checks
155
+ runs-on: ${{ matrix.platform.runner }}
156
+ strategy:
157
+ fail-fast: false
158
+ matrix:
159
+ platform:
160
+ - runner: macos-15-intel
161
+ target: x86_64
162
+ - runner: macos-latest
163
+ target: aarch64
164
+ steps:
165
+ - uses: actions/checkout@v4
166
+ - uses: actions/setup-python@v5
167
+ with:
168
+ python-version: "3.12"
169
+ - name: Build wheels
170
+ uses: PyO3/maturin-action@v1
171
+ with:
172
+ target: ${{ matrix.platform.target }}
173
+ args: --release --out dist --features python --locked --compatibility pypi
174
+ sccache: "true"
175
+ - uses: actions/upload-artifact@v4
176
+ with:
177
+ name: python-dist-macos-${{ matrix.platform.target }}
178
+ path: dist/*
179
+ if-no-files-found: error
180
+
181
+ build-python-sdist:
182
+ needs: checks
183
+ runs-on: ubuntu-latest
184
+ steps:
185
+ - uses: actions/checkout@v4
186
+ - name: Build sdist
187
+ uses: PyO3/maturin-action@v1
188
+ with:
189
+ command: sdist
190
+ args: --out dist
191
+ - uses: actions/upload-artifact@v4
192
+ with:
193
+ name: python-dist-sdist
194
+ path: dist/*
195
+ if-no-files-found: error
196
+
197
+ publish-pypi:
198
+ needs:
199
+ - build-python-linux
200
+ - build-python-musllinux
201
+ - build-python-windows
202
+ - build-python-macos
203
+ - build-python-sdist
204
+ runs-on: ubuntu-latest
205
+ steps:
206
+ - uses: actions/download-artifact@v4
207
+ with:
208
+ pattern: python-dist-*
209
+ merge-multiple: true
210
+ path: dist
211
+ - uses: actions/setup-python@v5
212
+ with:
213
+ python-version: "3.12"
214
+ - name: Publish Python package to PyPI
215
+ run: |
216
+ pip install maturin
217
+ maturin upload --username __token__ --password "$MATURIN_PYPI_TOKEN" dist/*
@@ -0,0 +1,28 @@
1
+ # Rust
2
+ /target/
3
+ **/*.rs.bk
4
+
5
+ # Editor and OS
6
+ .DS_Store
7
+ *.swp
8
+ *.swo
9
+ *~
10
+ .idea/
11
+ .vscode/
12
+ .cursor/
13
+ *.code-workspace
14
+
15
+ # Environment
16
+ .env
17
+ .env.*
18
+
19
+ # Python
20
+ __pycache__/
21
+ *.py[cod]
22
+ *.so
23
+ *.egg-info/
24
+ .eggs/
25
+ dist/
26
+ .python-version
27
+ venv/
28
+ .venv/
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ First published release.
6
+
7
+ - Phase 1 skeleton milestone (module stubs, fixtures, CLI tests, exit codes)
8
+ - Rust crate `odcs` and Python package `pyodcs`
9
+ - CI and release workflows
10
+
11
+ ## 0.1.0
12
+
13
+ Phase 1 — Skeleton (complete).
14
+
15
+ - Professional repository layout aligned with DTCS conventions
16
+ - Rust crate skeleton with full module tree per `crate-layout.md`
17
+ - Basic YAML and JSON parsing for minimal ODCS contracts
18
+ - Extension field preservation on parse
19
+ - CLI: `validate`, `inspect`, `diagnostics`, `schema`, `version` with `--json`
20
+ - CLI exit codes: 0 valid, 1 validation error, 2 parse/IO failure
21
+ - Expanded fixture suite and integration tests (`tests/skeleton.rs`, `tests/cli.rs`)
22
+ - `pyodcs` Python package with PyO3 bindings
23
+ - CI pipeline (fmt, clippy, test) plus release workflow
24
+ - Documentation reorganized under `docs/implementation/`
@@ -0,0 +1,48 @@
1
+ # Contributing to ODCS
2
+
3
+ Thank you for contributing to the Open Data Contract Standard reference implementation.
4
+
5
+ ## Upstream specification
6
+
7
+ Normative ODCS semantics are defined in the [upstream specification](https://github.com/bitol-io/open-data-contract-standard). This repository's [SPEC.md](SPEC.md) documents how we track and synchronize with upstream releases.
8
+
9
+ When implementing behavior:
10
+
11
+ 1. Read the relevant upstream ODCS specification sections.
12
+ 2. Consult [docs/implementation/](docs/implementation/) for architecture and API guidance.
13
+ 3. Preserve spec-aligned naming and behavior.
14
+ 4. Add tests that exercise spec requirements. See [docs/implementation/testing-plan.md](docs/implementation/testing-plan.md).
15
+
16
+ ### Authority
17
+
18
+ The upstream ODCS specification is the single source of truth for semantics, terminology, and conformance. Implementation docs in [docs/implementation/](docs/implementation/) are illustrative unless explicitly normative.
19
+
20
+ ## Implementation changes
21
+
22
+ The Rust reference crate lives in [src/](src/). Before implementing a module:
23
+
24
+ 1. Read the relevant upstream specification sections.
25
+ 2. Consult [docs/implementation/crate-layout.md](docs/implementation/crate-layout.md) for module boundaries.
26
+ 3. Preserve spec-aligned naming and behavior.
27
+ 4. Add tests for behavioral changes.
28
+
29
+ ### Scope
30
+
31
+ The initial crate targets parsing, the canonical object model, validation, and diagnostics. Do not add execution, pipeline composition, or transformation features without an agreed milestone. See [docs/implementation/non-goals.md](docs/implementation/non-goals.md).
32
+
33
+ ### Code style
34
+
35
+ - Run `cargo fmt` and `cargo clippy` before submitting changes.
36
+ - Keep modules aligned with [docs/implementation/crate-layout.md](docs/implementation/crate-layout.md).
37
+ - Prefer conservative behavior when the spec is ambiguous; document open questions with a `TODO` referencing the spec section.
38
+
39
+ ## Pull requests
40
+
41
+ 1. Describe whether the change is implementation, documentation, or infrastructure.
42
+ 2. Link related issues or design discussions when available.
43
+ 3. Include or update tests for behavioral changes.
44
+ 4. Ensure `cargo test` passes.
45
+
46
+ ## Questions
47
+
48
+ For ambiguous upstream spec language, open an issue with the relevant section rather than inventing behavior in code.