shacl2code 1.1.0__tar.gz → 1.3.2__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 (148) hide show
  1. shacl2code-1.3.2/.github/dependabot.yml +14 -0
  2. shacl2code-1.3.2/.github/workflows/bandit.yaml +30 -0
  3. {shacl2code-1.1.0 → shacl2code-1.3.2}/.github/workflows/coverage-generate.yaml +26 -7
  4. {shacl2code-1.1.0 → shacl2code-1.3.2}/.github/workflows/coverage-report.yaml +1 -1
  5. shacl2code-1.3.2/.github/workflows/publish.yaml +71 -0
  6. {shacl2code-1.1.0 → shacl2code-1.3.2}/.github/workflows/scorecard.yml +2 -2
  7. shacl2code-1.3.2/.github/workflows/test-sbom.yaml +73 -0
  8. shacl2code-1.3.2/.github/workflows/test.yaml +102 -0
  9. {shacl2code-1.1.0 → shacl2code-1.3.2}/.gitignore +5 -0
  10. {shacl2code-1.1.0 → shacl2code-1.3.2}/PKG-INFO +130 -8
  11. {shacl2code-1.1.0 → shacl2code-1.3.2}/README.md +115 -0
  12. {shacl2code-1.1.0 → shacl2code-1.3.2}/SECURITY.md +2 -1
  13. {shacl2code-1.1.0 → shacl2code-1.3.2}/pyproject.toml +22 -6
  14. shacl2code-1.3.2/scripts/ajv-compile.js +76 -0
  15. {shacl2code-1.1.0 → shacl2code-1.3.2}/scripts/format.sh +1 -0
  16. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/__init__.py +1 -0
  17. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/__main__.py +1 -0
  18. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/context.py +1 -0
  19. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/__init__.py +3 -0
  20. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/common.py +24 -8
  21. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/cpp.py +0 -5
  22. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/golang.py +2 -7
  23. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/python.py +14 -0
  24. shacl2code-1.3.2/src/shacl2code/lang/rust.py +280 -0
  25. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/Makefile.j2 +5 -1
  26. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/jsonld-source.j2 +15 -0
  27. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/objectset.cpp.j2 +1 -2
  28. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/walk.hpp.j2 +18 -16
  29. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/classes.go.j2 +23 -8
  30. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/decode.go.j2 +7 -7
  31. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/encode.go.j2 +1 -0
  32. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/errorhandler.go.j2 +1 -0
  33. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/errors.go.j2 +4 -3
  34. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/extensible.go.j2 +2 -3
  35. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/linkstate.go.j2 +1 -0
  36. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/listproperty.go.j2 +2 -1
  37. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/optional.go.j2 +1 -0
  38. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/path.go.j2 +1 -0
  39. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/property.go.j2 +1 -0
  40. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/ref.go.j2 +5 -3
  41. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/reflistproperty.go.j2 +1 -0
  42. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/refproperty.go.j2 +1 -0
  43. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/shaclobject.go.j2 +3 -2
  44. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/shaclobjectset.go.j2 +16 -4
  45. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/shacltype.go.j2 +1 -0
  46. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/util.go.j2 +2 -1
  47. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/golang/validator.go.j2 +12 -12
  48. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/jsonschema.j2 +73 -2
  49. shacl2code-1.3.2/src/shacl2code/lang/templates/python/_macros.j2 +13 -0
  50. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/python/model.py.j2 +90 -26
  51. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/python/model.pyi.j2 +16 -23
  52. shacl2code-1.3.2/src/shacl2code/lang/templates/rust/Cargo.toml.j2 +15 -0
  53. shacl2code-1.3.2/src/shacl2code/lang/templates/rust/lib.rs.j2 +2210 -0
  54. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/main.py +21 -4
  55. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/model.py +146 -3
  56. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/urlcontext.py +1 -0
  57. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/util.py +1 -0
  58. shacl2code-1.3.2/src/shacl2code/version.py +8 -0
  59. {shacl2code-1.1.0 → shacl2code-1.3.2}/testfixtures/testfixtures/jsonvalidation.py +61 -0
  60. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/conftest.py +2 -0
  61. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/bad-node-kind.ttl +1 -1
  62. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/bad-pattern-class.ttl +1 -1
  63. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/bad-pattern-integer.ttl +1 -1
  64. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/bad-prop-type.ttl +1 -1
  65. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/context.j2 +0 -3
  66. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/missing-range.ttl +1 -1
  67. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/model/test-context.json +2 -2
  68. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/model/test.ttl +7 -1
  69. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/raw.j2 +2 -2
  70. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/reserved-words.ttl +1 -1
  71. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_cpp.py +256 -210
  72. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_golang.py +68 -20
  73. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_jsonschema.py +39 -7
  74. shacl2code-1.3.2/tests/test_lint.py +32 -0
  75. shacl2code-1.3.2/tests/test_model.py +32 -0
  76. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_python.py +705 -97
  77. shacl2code-1.3.2/tests/test_rust.py +844 -0
  78. shacl2code-1.1.0/.github/dependabot.yml +0 -6
  79. shacl2code-1.1.0/.github/workflows/publish.yaml +0 -37
  80. shacl2code-1.1.0/.github/workflows/test.yaml +0 -69
  81. shacl2code-1.1.0/src/shacl2code/version.py +0 -1
  82. {shacl2code-1.1.0 → shacl2code-1.3.2}/.clang-format +0 -0
  83. {shacl2code-1.1.0 → shacl2code-1.3.2}/.flake8 +0 -0
  84. {shacl2code-1.1.0 → shacl2code-1.3.2}/LICENSE +0 -0
  85. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/jinja.py +0 -0
  86. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/jsonschema.py +0 -0
  87. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/lang.py +0 -0
  88. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/sources/cpp/json.hpp +0 -0
  89. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/Doxyfile.j2 +0 -0
  90. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/api.hpp.j2 +0 -0
  91. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/datetime.cpp.j2 +0 -0
  92. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/datetime.hpp.j2 +0 -0
  93. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/decode.cpp.j2 +0 -0
  94. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/decode.hpp.j2 +0 -0
  95. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/encode.cpp.j2 +0 -0
  96. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/encode.hpp.j2 +0 -0
  97. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/errorhandler.cpp.j2 +0 -0
  98. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/errorhandler.hpp.j2 +0 -0
  99. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/exceptions.hpp.j2 +0 -0
  100. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/extensible.cpp.j2 +0 -0
  101. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/extensible.hpp.j2 +0 -0
  102. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/header.j2 +0 -0
  103. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/jsonld-header.j2 +0 -0
  104. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/link.cpp.j2 +0 -0
  105. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/link.hpp.j2 +0 -0
  106. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/namedindividual.cpp.j2 +0 -0
  107. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/namedindividual.hpp.j2 +0 -0
  108. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/object.cpp.j2 +0 -0
  109. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/object.hpp.j2 +0 -0
  110. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/objectpath.cpp.j2 +0 -0
  111. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/objectpath.hpp.j2 +0 -0
  112. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/objectset.hpp.j2 +0 -0
  113. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/pkgconfig.pc.j2 +0 -0
  114. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/prop.hpp.j2 +0 -0
  115. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/property.cpp.j2 +0 -0
  116. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/property.hpp.j2 +0 -0
  117. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/propertyvalue.cpp.j2 +0 -0
  118. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/propertyvalue.hpp.j2 +0 -0
  119. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/ref.hpp.j2 +0 -0
  120. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/refproperty.cpp.j2 +0 -0
  121. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/refproperty.hpp.j2 +0 -0
  122. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/source.j2 +0 -0
  123. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/type.cpp.j2 +0 -0
  124. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/type.hpp.j2 +0 -0
  125. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/util.cpp.j2 +0 -0
  126. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/util.hpp.j2 +0 -0
  127. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/cpp/validate.j2 +0 -0
  128. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/python/__init__.py.j2 +0 -0
  129. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/python/__main__.py.j2 +0 -0
  130. {shacl2code-1.1.0 → shacl2code-1.3.2}/src/shacl2code/lang/templates/python/cmd.py.j2 +0 -0
  131. {shacl2code-1.1.0 → shacl2code-1.3.2}/testfixtures/testfixtures/__init__.py +0 -0
  132. {shacl2code-1.1.0 → shacl2code-1.3.2}/testfixtures/testfixtures/httpserver.py +0 -0
  133. {shacl2code-1.1.0 → shacl2code-1.3.2}/testfixtures/testfixtures/timetests.py +0 -0
  134. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/abort.j2 +0 -0
  135. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/bad-id.j2 +0 -0
  136. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/bad-reference.jsonld +0 -0
  137. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/context-url.j2 +0 -0
  138. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/links.json +0 -0
  139. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/python/bad-object-type-inline.json +0 -0
  140. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/python/bad-object-type-ref-after.json +0 -0
  141. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/python/bad-object-type-ref-before.json +0 -0
  142. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/data/roundtrip.json +0 -0
  143. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_cli.py +0 -0
  144. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_common_jinja.py +0 -0
  145. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_common_prefix.py +0 -0
  146. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_context.py +0 -0
  147. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_convert_version_string.py +0 -0
  148. {shacl2code-1.1.0 → shacl2code-1.3.2}/tests/test_model_source.py +0 -0
@@ -0,0 +1,14 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ cooldown:
8
+ default-days: 7
9
+ - package-ecosystem: "github-actions"
10
+ directory: "/"
11
+ schedule:
12
+ interval: "weekly"
13
+ cooldown:
14
+ default-days: 7
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: Bandit
3
+
4
+ on:
5
+ push:
6
+ # Only run when shacl2code's own Python source could be affected
7
+ paths: &trigger-paths
8
+ - "src/shacl2code/**"
9
+ - "pyproject.toml"
10
+ - ".github/workflows/bandit.yaml"
11
+ pull_request:
12
+ paths: *trigger-paths
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ bandit:
19
+ runs-on: ubuntu-latest
20
+ permissions:
21
+ # Needed to upload results to the code scanning dashboard
22
+ security-events: write
23
+ actions: read
24
+ contents: read
25
+ steps:
26
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
27
+ - name: Run Bandit
28
+ uses: PyCQA/bandit-action@67a458d90fa11fb1463e91e7f4c8f068b5863c7f # v1.0.1
29
+ with:
30
+ targets: src/shacl2code
@@ -7,6 +7,10 @@ on:
7
7
  branches:
8
8
  - "main"
9
9
 
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
12
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
13
+
10
14
  permissions:
11
15
  contents: read
12
16
 
@@ -23,31 +27,46 @@ jobs:
23
27
  # comments (to avoid publishing multiple comments in the same PR)
24
28
  contents: write
25
29
  steps:
26
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
27
- - name: Setup Python ${{ matrix.python-version }}
28
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
30
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
31
+ - name: Setup Python
32
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
29
33
  with:
30
34
  python-version: "3.11"
35
+ cache: "pip"
36
+ cache-dependency-path: "pyproject.toml"
37
+ - name: Setup Node
38
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
39
+ with:
40
+ node-version: 24
31
41
  - name: Install dependencies
32
42
  run: |
33
- sudo apt install -y build-essential doxygen graphviz
43
+ sudo apt install -y build-essential cppcheck doxygen graphviz
44
+ npm install -g jsonld-cli
45
+ npm --prefix scripts ci
46
+ - name: Install Go static analysis tools
47
+ run: |
48
+ echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
49
+ go install honnef.co/go/tools/cmd/staticcheck@latest
50
+ - name: Install Rust static analysis tools
51
+ run: |
52
+ rustup component add clippy
34
53
  - name: Install package
35
54
  run: |
55
+ pip install --upgrade pip
36
56
  pip install -e .[dev]
37
57
  - name: Generate coverage report
38
58
  run: |
39
59
  pytest -v
40
60
  - name: Coverage comment
41
61
  id: coverage_comment
42
- uses: py-cov-action/python-coverage-comment-action@2b84cfb222691291ba358a586c13606f0a9c172c # v3
62
+ uses: py-cov-action/python-coverage-comment-action@a05be3d2e8a6272d3ef5fb2840ab20368bb2eb71 # v4.3
43
63
  with:
44
64
  GITHUB_TOKEN: ${{ github.token }}
45
65
  - name: Store Pull Request comment to be posted
46
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
66
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
47
67
  if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
48
68
  with:
49
69
  # If you use a different name, update COMMENT_ARTIFACT_NAME accordingly
50
70
  name: python-coverage-comment-action
51
71
  # If you use a different name, update COMMENT_FILENAME accordingly
52
72
  path: python-coverage-comment-action.txt
53
-
@@ -30,7 +30,7 @@ jobs:
30
30
  # DO NOT run actions/checkout here, for security reasons
31
31
  # For details, refer to https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
32
32
  - name: Post comment
33
- uses: py-cov-action/python-coverage-comment-action@2b84cfb222691291ba358a586c13606f0a9c172c # v3
33
+ uses: py-cov-action/python-coverage-comment-action@a05be3d2e8a6272d3ef5fb2840ab20368bb2eb71 # v4.3
34
34
  with:
35
35
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
36
  GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }}
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: Upload Python Package
3
+ on:
4
+ release:
5
+ types:
6
+ - published
7
+
8
+ jobs:
9
+ test:
10
+ uses: ./.github/workflows/test.yaml
11
+
12
+ deploy:
13
+ needs:
14
+ - test
15
+
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ id-token: write
19
+
20
+ steps:
21
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
25
+ with:
26
+ python-version: '3.x'
27
+
28
+ - name: Install dependencies
29
+ run: |
30
+ python -m pip install --upgrade pip
31
+ pip install build spdx3-validate
32
+
33
+ - name: Build package
34
+ run: python -m build
35
+
36
+ - name: Embed SBOM into the wheel
37
+ id: pitloom
38
+ uses: bact/pitloom@68b02e2052902012716c6b888addbaf95d5e1bf5 # v0.17.0
39
+ with:
40
+ embed-wheel: "dist/*.whl"
41
+ extras: "content-type"
42
+ content-type: "true"
43
+ artifact-name: "sbom"
44
+
45
+ - name: Extract and validate embedded SBOM
46
+ env:
47
+ SBOM_PATH: ${{ steps.pitloom.outputs.sbom-path }}
48
+ run: |
49
+ set -euo pipefail
50
+ whl=$(ls dist/*.whl)
51
+ sbom_basename=$(basename "${SBOM_PATH}")
52
+
53
+ entry=""
54
+ while IFS= read -r line; do
55
+ case "${line}" in
56
+ *".dist-info/sboms/${sbom_basename}") entry="${line}"; break ;;
57
+ esac
58
+ done < <(unzip -Z1 "${whl}")
59
+
60
+ if [ -z "${entry}" ]; then
61
+ echo "::error::${sbom_basename} not found under */.dist-info/sboms/ in ${whl}"
62
+ exit 1
63
+ fi
64
+ echo "Found: ${entry}"
65
+
66
+ mkdir -p extracted-sbom
67
+ unzip -p "${whl}" "${entry}" > "extracted-sbom/${sbom_basename}"
68
+ spdx3-validate --json "extracted-sbom/${sbom_basename}"
69
+
70
+ - name: Publish distribution to PyPI
71
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
@@ -32,12 +32,12 @@ jobs:
32
32
 
33
33
  steps:
34
34
  - name: "Checkout code"
35
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
35
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
36
36
  with:
37
37
  persist-credentials: false
38
38
 
39
39
  - name: "Run analysis"
40
- uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
40
+ uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
41
41
  with:
42
42
  results_file: results.sarif
43
43
  results_format: sarif
@@ -0,0 +1,73 @@
1
+ ---
2
+ # Tests that the SBOM generation and embedding step works correctly on every PR.
3
+ name: Test SBOM generation
4
+
5
+ on:
6
+ push:
7
+ paths-ignore: &ignore-paths
8
+ - "docs/**"
9
+ - "**/*.md"
10
+ - "LICENSE*"
11
+ pull_request:
12
+ paths-ignore: *ignore-paths
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ test-sbom:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
26
+
27
+ - name: Setup Python
28
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
29
+ with:
30
+ python-version: "3.x"
31
+ cache: pip
32
+
33
+ - name: Install build tooling
34
+ run: |
35
+ python -m pip install --upgrade pip
36
+ pip install build spdx3-validate
37
+
38
+ - name: Build wheel
39
+ run: python -m build --wheel
40
+
41
+ - name: Embed SBOM into the wheel
42
+ id: pitloom
43
+ uses: bact/pitloom@68b02e2052902012716c6b888addbaf95d5e1bf5 # v0.17.0
44
+ with:
45
+ embed-wheel: "dist/*.whl"
46
+ extras: "content-type"
47
+ content-type: "true"
48
+ artifact-name: "sbom"
49
+
50
+ - name: Extract and validate embedded SBOM
51
+ env:
52
+ SBOM_PATH: ${{ steps.pitloom.outputs.sbom-path }}
53
+ run: |
54
+ set -euo pipefail
55
+ whl=$(ls dist/*.whl)
56
+ sbom_basename=$(basename "${SBOM_PATH}")
57
+
58
+ entry=""
59
+ while IFS= read -r line; do
60
+ case "${line}" in
61
+ *".dist-info/sboms/${sbom_basename}") entry="${line}"; break ;;
62
+ esac
63
+ done < <(unzip -Z1 "${whl}")
64
+
65
+ if [ -z "${entry}" ]; then
66
+ echo "::error::${sbom_basename} not found under */.dist-info/sboms/ in ${whl}"
67
+ exit 1
68
+ fi
69
+ echo "Found: ${entry}"
70
+
71
+ mkdir -p extracted-sbom
72
+ unzip -p "${whl}" "${entry}" > "extracted-sbom/${sbom_basename}"
73
+ spdx3-validate --json "extracted-sbom/${sbom_basename}"
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: Test shacl2code
3
+ on:
4
+ push:
5
+ # Skip changes in docs and other workflows
6
+ paths: &trigger-paths
7
+ - "**"
8
+ - "!**/*.md"
9
+ - "!LICENSE"
10
+ - "!.github/ISSUE_TEMPLATE/**"
11
+ - "!.github/workflows/**"
12
+ - ".github/workflows/test.yaml"
13
+ pull_request:
14
+ paths: *trigger-paths
15
+ workflow_call:
16
+
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ jobs:
25
+ build:
26
+ runs-on: ${{ matrix.os }}
27
+ strategy:
28
+ matrix:
29
+ os: [ubuntu-latest]
30
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
31
+ include:
32
+ - os: macos-latest
33
+ python-version: "3.10"
34
+ steps:
35
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
36
+ - name: Setup Python ${{ matrix.python-version }}
37
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+ cache: pip
41
+ - name: Setup Node
42
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
43
+ with:
44
+ node-version: 24
45
+ cache: npm
46
+ cache-dependency-path: scripts/package-lock.json
47
+ - name: Install dependencies
48
+ run: |
49
+ python -m pip install --upgrade pip
50
+ pip install build
51
+ npm install -g jsonld-cli
52
+ npm --prefix scripts ci
53
+ - name: Install Linux packages
54
+ if: runner.os == 'Linux'
55
+ run: |
56
+ sudo apt update
57
+ sudo apt install -y build-essential cppcheck doxygen graphviz ccache
58
+ - name: Install macOS packages
59
+ if: runner.os == 'macOS'
60
+ run: |
61
+ brew update
62
+ brew install cppcheck doxygen gcc go graphviz ccache
63
+ - name: Install Go static analysis tools
64
+ run: |
65
+ echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
66
+ go install honnef.co/go/tools/cmd/staticcheck@latest
67
+ - name: Install Rust static analysis tools
68
+ run: |
69
+ rustup component add clippy
70
+ - name: Configure ccache
71
+ uses: hendrikmuhs/ccache-action@v1.2
72
+ with:
73
+ key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.python-version }}
74
+ - name: Build package
75
+ run: |
76
+ python -m build
77
+ - name: Install package
78
+ run: |
79
+ pip install -e .[dev]
80
+ - name: Run tests
81
+ run: |
82
+ pytest -v
83
+ lint:
84
+ runs-on: ubuntu-latest
85
+ steps:
86
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
87
+ - name: Setup Python
88
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
89
+ with:
90
+ # Black in this Python version must support all target-versions listed in pyproject.toml
91
+ python-version: "3.14"
92
+ cache: pip
93
+ - uses: psf/black@87928e6d6761a4a6d22250e1fee5601b3998086e # 26.5.1
94
+ - uses: py-actions/flake8@84ec6726560b6d5bd68f2a5bed83d62b52bb50ba # v2.3.0
95
+ - name: Install dependencies
96
+ run: |
97
+ python -m pip install --upgrade pip
98
+ pip install clang-format
99
+ - name: Check code formatting
100
+ run: |
101
+ ./scripts/format.sh
102
+ git diff --exit-code
@@ -1,3 +1,8 @@
1
+ # Node
2
+ node_modules/
3
+ package.json
4
+ package-lock.json
5
+
1
6
  # Byte-compiled / optimized / DLL files
2
7
  __pycache__/
3
8
  *.py[cod]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: shacl2code
3
- Version: 1.1.0
3
+ Version: 1.3.2
4
4
  Summary: Convert SHACL model file to code bindings
5
5
  Project-URL: Homepage, https://github.com/JPEWdev/shacl2code
6
6
  Project-URL: Repository, https://github.com/JPEWdev/shacl2code.git
@@ -10,33 +10,41 @@ License-Expression: MIT
10
10
  License-File: LICENSE
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: C++
14
+ Classifier: Programming Language :: Go
13
15
  Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.8
15
16
  Classifier: Programming Language :: Python :: 3.9
16
17
  Classifier: Programming Language :: Python :: 3.10
17
18
  Classifier: Programming Language :: Python :: 3.11
18
19
  Classifier: Programming Language :: Python :: 3.12
19
20
  Classifier: Programming Language :: Python :: 3.13
20
21
  Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Programming Language :: Rust
23
+ Classifier: Topic :: File Formats :: JSON :: JSON Schema
21
24
  Classifier: Topic :: Software Development :: Build Tools
22
- Requires-Python: >=3.8
25
+ Classifier: Topic :: Software Development :: Code Generators
26
+ Requires-Python: >=3.9
23
27
  Requires-Dist: jinja2>=3.1.2
24
28
  Requires-Dist: rdflib>=7.0.0
25
29
  Provides-Extra: dev
30
+ Requires-Dist: bandit<1.10.0,>=1.8.6; extra == 'dev'
31
+ Requires-Dist: black>=25.11.0; extra == 'dev'
26
32
  Requires-Dist: flake8-import-order>=0.19.2; extra == 'dev'
27
33
  Requires-Dist: flake8>=7.0.0; extra == 'dev'
28
- Requires-Dist: jsonschema>=4.23.0; extra == 'dev'
29
- Requires-Dist: mypy>=1.14.1; extra == 'dev'
34
+ Requires-Dist: jsonschema>=4.25.1; extra == 'dev'
35
+ Requires-Dist: mypy>=1.19.1; extra == 'dev'
30
36
  Requires-Dist: pyrefly>=0.55.0; extra == 'dev'
31
37
  Requires-Dist: pyright>=1.1.403; extra == 'dev'
32
- Requires-Dist: pyshacl>=0.25.0; extra == 'dev'
38
+ Requires-Dist: pyshacl!=0.40.0,>=0.25.0; extra == 'dev'
33
39
  Requires-Dist: pytest-cov>=4.1; extra == 'dev'
40
+ Requires-Dist: pytest-xdist>=3.5; extra == 'dev'
34
41
  Requires-Dist: pytest>=7.4; extra == 'dev'
35
- Requires-Dist: types-jsonschema>=4.23.0; extra == 'dev'
42
+ Requires-Dist: types-jsonschema>=4.25.1; extra == 'dev'
36
43
  Description-Content-Type: text/markdown
37
44
 
38
45
  # Convert SHACL Model to code bindings
39
46
 
47
+ [![PyPI - Version](https://img.shields.io/pypi/v/shacl2code)](https://pypi.org/project/shacl2code/)
40
48
  [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9999/badge)](https://www.bestpractices.dev/projects/9999)
41
49
  [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/JPEWdev/shacl2code/badge)](https://scorecard.dev/viewer/?uri=github.com/JPEWdev/shacl2code)
42
50
  [![Coverage Report](https://raw.githubusercontent.com/JPEWdev/shacl2code/python-coverage-comment-action-data/badge.svg)](https://htmlpreview.github.io/?https://github.com/JPEWdev/shacl2code/blob/python-coverage-comment-action-data/htmlcov/index.html)
@@ -83,6 +91,59 @@ The available language bindings can be viewed by running:
83
91
  shacl2code list
84
92
  ```
85
93
 
94
+ ### Using JSON-LD contexts
95
+
96
+ When using JSON-LD contexts, the context document shall align with the model.
97
+
98
+ During model development, there may be cases where the context URL is known
99
+ but not yet live or resolvable. In these situations, you can use the
100
+ `--context-url` option to map your local context file to its future public home.
101
+
102
+ The `--context-url` option accepts two arguments:
103
+
104
+ 1. `CONTEXT_LOCATION`: The actual path to the local or temporary file
105
+ containing the context.
106
+ 2. `CONTEXT_URL`: The official public URL. While temporarily unresolvable
107
+ during development, this is the URL that production JSON-LD processors will
108
+ eventually rely on, so it must be recorded inside the generated JSON Schema.
109
+
110
+ ### Generating the JSON Schema file
111
+
112
+ `shacl2code` can generate a JSON Schema directly from a model.
113
+
114
+ To view all options specific to JSON Schema generation, run:
115
+
116
+ ```shell
117
+ shacl2code generate jsonschema -h
118
+ ```
119
+
120
+ #### Example 1: Generating from publicly available URLs
121
+
122
+ To generate a schema using remote, publicly accessible assets
123
+ (such as SPDX 3.0.1):
124
+
125
+ ```shell
126
+ shacl2code generate \
127
+ --input https://spdx.org/rdf/3.0.1/spdx-model.ttl \
128
+ --input https://spdx.org/rdf/3.0.1/spdx-json-serialize-annotations.ttl \
129
+ --context https://spdx.org/rdf/3.0.1/spdx-context.jsonld \
130
+ jsonschema \
131
+ --output spdx-json-schema.json
132
+ ```
133
+
134
+ #### Example 2: Generating with a local context document
135
+
136
+ To generate a schema using a local context file while embedding its future
137
+ public URL:
138
+
139
+ ```shell
140
+ shacl2code generate \
141
+ --input model-draft.ttl \
142
+ --context-url context-draft.jsonld https://example.com/context.jsonld \
143
+ jsonschema \
144
+ --output schema.json
145
+ ```
146
+
86
147
  ## Developing
87
148
 
88
149
  Developing on `shacl2code` is best done using a virtual environment. You can
@@ -250,5 +311,66 @@ classes are automatically concrete unless they indicate otherwise.
250
311
  It is also possible to define a class as abstract by declaring it to be of
251
312
  type: `http://spdx.invalid./AbstractClass`, but this is not preferred.
252
313
 
314
+ ### Pre-Release models
315
+
316
+ `shacl2code` can detect if an ontology is a "pre-release" version (still
317
+ subject to breaking changes). For language bindings that support it (such as
318
+ Python), importing a pre-release ontology binding will emit a warning
319
+ (e.g. `FutureWarning`).
320
+
321
+ Pre-release status can be specified explicitly via command-line options,
322
+ or inferred automatically from various ontology annotations. For example,
323
+
324
+ ```ttl
325
+ <http://example.org/my-ontology> a ow:Ontology ;
326
+ sh-to-code:isPreRelease true
327
+ .
328
+ ```
329
+
330
+ Note that the IRI of the ontology must be the prefix of all IRIs that belong to
331
+ that ontology.
332
+
333
+ In the event of conflicting annotations, `shacl2code` evaluates pre-release
334
+ status using the following order of precedence (1 = the highest priority):
335
+
336
+ 1. **`--pre-release` or `--no-pre-release` command-line options**:
337
+ Explicitly marks the generated bindings as pre-release or stable,
338
+ overriding any annotations in the input ontology.
339
+ 2. **`sh-to-code:isPreRelease`**:
340
+ The `shacl2code` custom boolean annotation
341
+ (`sh-to-code:isPreRelease true` or `false`).
342
+ 3. **`adms:status` (EU SEMIC Vocabulary)**:
343
+ If the status is
344
+ `<http://publications.europa.eu/resource/authority/dataset-status/DEVELOP>`,
345
+ it is considered a pre-release.
346
+ Other values in the dataset-status vocabulary space (e.g. `COMPLETED`)
347
+ indicate a stable release.
348
+ 4. **`adms:status` (Original ADMS Vocabulary)**:
349
+ If the status is `<http://purl.org/adms/status/UnderDevelopment>`,
350
+ it is considered a pre-release.
351
+ Other values in the ADMS status namespace (e.g. `Completed`)
352
+ indicate a stable release.
353
+ 5. **`bibo:status` (Bibliographic Ontology)**:
354
+ If set to `<http://purl.org/ontology/bibo/status/draft>`, it is
355
+ considered a pre-release.
356
+ Other values in the BIBO status namespace (e.g. `published`, `legal`)
357
+ indicate a stable release.
358
+ 6. **`schema:creativeWorkStatus`**:
359
+ If set to `"Draft"` or `"Incomplete"`, it is considered a pre-release.
360
+ Other values (e.g. `"Published"`) indicate a stable release.
361
+ 7. **`vs:term_status`**:
362
+ If set to `"unstable"` or `"testing"`, it is considered a pre-release.
363
+ Other values (e.g. `"stable"`) indicate a stable release.
364
+ 8. **`owl:versionInfo` (pre-release extension)**:
365
+ If the version string contains a pre-release extension suffix
366
+ (e.g., `-alpha`, `-beta`, `-dev`, `-rc`, `-SNAPSHOT`, `.alpha`, etc.).
367
+ 9. **`owl:versionInfo` (major version zero)**:
368
+ If the version string corresponds to a major version zero in
369
+ [Semantic Versioning][semver] (e.g., `0.7.1`).
370
+ 10. **Default Fallback**:
371
+ If none of the above are present, the ontology is assumed to be a stable
372
+ release.
373
+
253
374
  [pytest]: https://www.pytest.org
254
375
  [pytest-cov]: https://pytest-cov.readthedocs.io/en/latest/
376
+ [semver]: https://semver.org/