plain-parser 0.1.2.dev6__tar.gz → 0.1.3__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 (153) hide show
  1. plain_parser-0.1.3/.github/dependabot.yml +27 -0
  2. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/.github/workflows/lint-and-test.yml +5 -0
  3. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/.github/workflows/publish-dev-to-pypi.yml +19 -13
  4. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/.github/workflows/publish-to-pypi.yml +68 -24
  5. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/PKG-INFO +1 -1
  6. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/pyproject.toml +1 -1
  7. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/plain_file.py +12 -3
  8. plain_parser-0.1.3/tests/data/requires/shared_export_above.plain +12 -0
  9. plain_parser-0.1.3/tests/data/requires/shared_export_base.plain +16 -0
  10. plain_parser-0.1.3/tests/data/requires/shared_export_middle.plain +12 -0
  11. plain_parser-0.1.3/tests/data/requires/shared_export_top.plain +13 -0
  12. plain_parser-0.1.3/tests/test_requires.py +269 -0
  13. plain_parser-0.1.2.dev6/tests/test_requires.py +0 -60
  14. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/.flake8 +0 -0
  15. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/.gitignore +0 -0
  16. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/LICENSE +0 -0
  17. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/README.md +0 -0
  18. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/__init__.py +0 -0
  19. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/cli.py +0 -0
  20. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/concept_utils.py +0 -0
  21. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/exceptions.py +0 -0
  22. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/graph.py +0 -0
  23. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/liquid_nodes.py +0 -0
  24. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/loaders.py +0 -0
  25. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/src/plain_parser/plain_spec.py +0 -0
  26. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/__init__.py +0 -0
  27. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/conftest.py +0 -0
  28. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/acceptance_test_binary_resource.plain +0 -0
  29. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/acceptance_test_resource.plain +0 -0
  30. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/base64_resource.plain +0 -0
  31. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/binary.bin +0 -0
  32. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/binary_resource.plain +0 -0
  33. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/code_variable_conflict.plain +0 -0
  34. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/code_variable_template.plain +0 -0
  35. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/missing_resource.plain +0 -0
  36. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/not_plain.md +0 -0
  37. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/notes.md +0 -0
  38. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/requires_binary_resource_base.plain +0 -0
  39. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/requires_binary_resource_top.plain +0 -0
  40. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/subdir/nested.plain +0 -0
  41. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/undefined_concept.plain +0 -0
  42. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/cli/valid.plain +0 -0
  43. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/circular_imports_1.plain +0 -0
  44. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/circular_imports_2.plain +0 -0
  45. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/circular_imports_main.plain +0 -0
  46. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/diamond_import_1.plain +0 -0
  47. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/diamond_import_2.plain +0 -0
  48. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/diamond_import_common.plain +0 -0
  49. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/diamond_imports_main.plain +0 -0
  50. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/import_with_functionalities.plain +0 -0
  51. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
  52. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/imports/non_existent_import.plain +0 -0
  53. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
  54. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  55. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
  56. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  57. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  58. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
  59. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  60. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/plain_source_with_missing_link.plain +0 -0
  61. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  62. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
  63. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  64. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  65. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  66. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  67. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  68. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  69. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  70. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  71. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  72. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  73. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  74. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  75. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  76. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/cyclic_definitions.plain +0 -0
  77. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/cyclic_definitions_across_import.plain +0 -0
  78. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/cyclic_definitions_long.plain +0 -0
  79. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/cyclic_definitions_sub_bullet.plain +0 -0
  80. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  81. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  82. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_defaults_exported.plain +0 -0
  83. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  84. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_imported_exported.plain +0 -0
  85. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_inherited_reexported.plain +0 -0
  86. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_malformed.plain +0 -0
  87. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_missing_definition.plain +0 -0
  88. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_missing_definition_example.plain +0 -0
  89. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_multiple_per_bullet.plain +0 -0
  90. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_multiple_per_bullet_undefined.plain +0 -0
  91. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  92. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  93. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_no_definitions.plain +0 -0
  94. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_not_declared.plain +0 -0
  95. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_not_declared_example.plain +0 -0
  96. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  97. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  98. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  99. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  100. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  101. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  102. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts.plain +0 -0
  103. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  104. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  105. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  106. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  107. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  108. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  109. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  110. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  111. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/requires_without_definitions_example.plain +0 -0
  112. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/topological_sort.plain +0 -0
  113. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  114. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/chain_base.plain +0 -0
  115. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/chain_fork_top.plain +0 -0
  116. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/chain_middle.plain +0 -0
  117. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/chain_top.plain +0 -0
  118. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/circular_requires_main.plain +0 -0
  119. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/circular_requires_sub.plain +0 -0
  120. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/diamond_requires_1.plain +0 -0
  121. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/diamond_requires_2.plain +0 -0
  122. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/diamond_requires_common.plain +0 -0
  123. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/diamond_requires_main.plain +0 -0
  124. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/independent_requires_1.plain +0 -0
  125. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/independent_requires_2.plain +0 -0
  126. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/independent_requires_main.plain +0 -0
  127. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/invalid_ancestor_base.plain +0 -0
  128. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/invalid_ancestor_top.plain +0 -0
  129. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/non_existent_require.plain +0 -0
  130. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/normal_requires_1.plain +0 -0
  131. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/normal_requires_2.plain +0 -0
  132. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/normal_requires_common.plain +0 -0
  133. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/requires/normal_requires_main.plain +0 -0
  134. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/sample_base64_image.txt +0 -0
  135. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/simple.plain +0 -0
  136. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/block_level_include.plain +0 -0
  137. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/code_variables.plain +0 -0
  138. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/header.plain +0 -0
  139. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/implement.plain +0 -0
  140. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/implement_2.plain +0 -0
  141. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/malformed_tag.plain +0 -0
  142. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/template_include.plain +0 -0
  143. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/test_hardest_problem.plain +0 -0
  144. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/data/templates/unterminated_output.plain +0 -0
  145. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_cli.py +0 -0
  146. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_concept_utils.py +0 -0
  147. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_exceptions.py +0 -0
  148. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_graph.py +0 -0
  149. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_imports.py +0 -0
  150. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_loaders.py +0 -0
  151. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_plainfile.py +0 -0
  152. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_plainfileparser.py +0 -0
  153. {plain_parser-0.1.2.dev6 → plain_parser-0.1.3}/tests/test_plainspec.py +0 -0
@@ -0,0 +1,27 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pip"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 3
8
+ commit-message:
9
+ prefix: "chore"
10
+ labels:
11
+ - "dependencies"
12
+
13
+ - package-ecosystem: "github-actions"
14
+ directory: "/"
15
+ schedule:
16
+ interval: "weekly"
17
+ open-pull-requests-limit: 5
18
+ commit-message:
19
+ prefix: "ci"
20
+ labels:
21
+ - "dependencies"
22
+ - "github-actions"
23
+ groups:
24
+ actions-minor-and-patch:
25
+ update-types:
26
+ - "minor"
27
+ - "patch"
@@ -9,12 +9,17 @@ on:
9
9
  # Lets the publish workflows run these checks as a job and depend on it.
10
10
  workflow_call:
11
11
 
12
+ permissions:
13
+ contents: read
14
+
12
15
  jobs:
13
16
  lint-and-test:
14
17
  name: Lint and test
15
18
  runs-on: ubuntu-latest
16
19
  steps:
17
20
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
+ with:
22
+ persist-credentials: false
18
23
  - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
19
24
  with:
20
25
  python-version: "3.11"
@@ -47,13 +47,15 @@ jobs:
47
47
  with:
48
48
  # hatch-vcs derives the version from git tags, so we need full history.
49
49
  fetch-depth: 0
50
+ persist-credentials: false
50
51
 
51
52
  - name: Install uv
52
53
  # uv provisions its own Python (honoring requires-python), so no
53
54
  # separate actions/setup-python step is needed.
54
- run: |
55
- curl -LsSf https://astral.sh/uv/install.sh | sh
56
- echo "$HOME/.local/bin" >> $GITHUB_PATH
55
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
56
+ with:
57
+ version: "0.12.23"
58
+ enable-cache: false
57
59
 
58
60
  - name: Compute dev version
59
61
  id: version
@@ -65,7 +67,7 @@ jobs:
65
67
  # run number as the dev counter: it is strictly increasing, so each
66
68
  # merge sorts after the last and re-runs never collide.
67
69
  run: |
68
- RAW=$(uvx --from setuptools-scm python -c \
70
+ RAW=$(uvx --from setuptools-scm==10.3.4 python -c \
69
71
  "from setuptools_scm import get_version; print(get_version())")
70
72
  echo "setuptools-scm reports: $RAW"
71
73
 
@@ -110,7 +112,7 @@ jobs:
110
112
  publish-dev:
111
113
  name: Publish dev build to PyPI
112
114
  needs: build
113
- if: needs.build.outputs.should-publish == 'true'
115
+ if: github.ref == 'refs/heads/main' && needs.build.outputs.should-publish == 'true'
114
116
  runs-on: ubuntu-latest
115
117
  environment:
116
118
  name: pypi
@@ -120,9 +122,6 @@ jobs:
120
122
  # authenticate this run — no long-lived API token needed.
121
123
  id-token: write
122
124
 
123
- env:
124
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
125
-
126
125
  steps:
127
126
  - name: Download distribution packages
128
127
  uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -138,20 +137,27 @@ jobs:
138
137
  skip-existing: true
139
138
 
140
139
  - name: Notify Slack (success)
141
- if: ${{ success() && env.SLACK_WEBHOOK_URL != '' }}
140
+ if: success()
141
+ continue-on-error: true
142
142
  env:
143
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
143
144
  VERSION: ${{ needs.build.outputs.version }}
144
145
  run: |
145
146
  # Spell out the --pre install: a plain "pip install plain-parser" will
146
147
  # NOT pick this up, which otherwise reads as a broken publish.
147
148
  TEXT="*plain-parser*: dev build \`$VERSION\` published to PyPI :test_tube:. Normal installs are unaffected — try it with \`pip install --pre plain-parser==$VERSION\`."
148
- curl -s -X POST "$SLACK_WEBHOOK_URL" \
149
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
149
150
  -H 'Content-type: application/json' \
150
151
  --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
151
152
 
152
153
  - name: Notify Slack (failure)
153
- if: ${{ failure() && env.SLACK_WEBHOOK_URL != '' }}
154
+ if: failure()
155
+ continue-on-error: true
156
+ env:
157
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
154
158
  run: |
155
- curl -s -X POST "$SLACK_WEBHOOK_URL" \
159
+ RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
160
+ TEXT="*plain-parser*: Publishing dev build to PyPI FAILED :x: (commit \`$GITHUB_SHA\`). See <$RUN_URL|the run log>."
161
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
156
162
  -H 'Content-type: application/json' \
157
- --data "{\"text\":\"*plain-parser*: Publishing dev build to PyPI FAILED :x: (commit \`${{ github.sha }}\`). See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
163
+ --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
@@ -23,30 +23,34 @@ jobs:
23
23
  needs: pre-publish-checks
24
24
  runs-on: ubuntu-latest
25
25
  permissions:
26
- contents: write
27
-
28
- env:
29
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26
+ contents: read
30
27
 
31
28
  steps:
32
29
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
33
30
  with:
34
31
  # hatch-vcs derives the version from git tags, so we need full history.
35
32
  fetch-depth: 0
33
+ persist-credentials: false
36
34
 
37
35
  - name: Notify Slack (start)
38
- if: ${{ env.SLACK_WEBHOOK_URL != '' }}
36
+ continue-on-error: true
37
+ env:
38
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
39
+ TAG: ${{ github.ref_name }}
40
+ ACTOR: ${{ github.actor }}
39
41
  run: |
40
- curl -s -X POST "$SLACK_WEBHOOK_URL" \
42
+ TEXT="*plain-parser*: Release \`$TAG\` published by *$ACTOR* — building and publishing to PyPI..."
43
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
41
44
  -H 'Content-type: application/json' \
42
- --data "{\"text\":\"*plain-parser*: Release \`${{ github.ref_name }}\` published by *${{ github.actor }}* — building and publishing to PyPI...\"}"
45
+ --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
43
46
 
44
47
  - name: Install uv
45
48
  # uv provisions its own Python (honoring requires-python), so no
46
49
  # separate actions/setup-python step is needed.
47
- run: |
48
- curl -LsSf https://astral.sh/uv/install.sh | sh
49
- echo "$HOME/.local/bin" >> $GITHUB_PATH
50
+ uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
51
+ with:
52
+ version: "0.12.23"
53
+ enable-cache: false
50
54
 
51
55
  - name: Build package
52
56
  # hatch-vcs reads the version straight from the release tag.
@@ -61,22 +65,57 @@ jobs:
61
65
  name: python-package-distributions
62
66
  path: dist/
63
67
 
68
+ - name: Notify Slack (build failure)
69
+ if: failure()
70
+ continue-on-error: true
71
+ env:
72
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
73
+ TAG: ${{ github.ref_name }}
74
+ run: |
75
+ RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
76
+ TEXT="*plain-parser*: Build of \`$TAG\` FAILED :x:. Nothing was published to PyPI. See <$RUN_URL|the run log>."
77
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
78
+ -H 'Content-type: application/json' \
79
+ --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
80
+
81
+ upload-release-assets:
82
+ name: Upload assets to GitHub Release
83
+ needs: build
84
+ runs-on: ubuntu-latest
85
+ permissions:
86
+ contents: write
87
+
88
+ steps:
89
+ - name: Download distribution packages
90
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
91
+ with:
92
+ name: python-package-distributions
93
+ path: dist/
94
+
64
95
  - name: Upload assets to GitHub Release
65
96
  env:
66
97
  GH_TOKEN: ${{ github.token }}
98
+ GH_REPO: ${{ github.repository }}
99
+ TAG: ${{ github.ref_name }}
67
100
  run: |
68
- gh release upload ${{ github.ref_name }} dist/* --clobber
101
+ gh release upload "$TAG" dist/* --clobber
69
102
 
70
- - name: Notify Slack (build failure)
71
- if: ${{ failure() && env.SLACK_WEBHOOK_URL != '' }}
103
+ - name: Notify Slack (upload failure)
104
+ if: failure()
105
+ continue-on-error: true
106
+ env:
107
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
108
+ TAG: ${{ github.ref_name }}
72
109
  run: |
73
- curl -s -X POST "$SLACK_WEBHOOK_URL" \
110
+ RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
111
+ TEXT="*plain-parser*: Uploading \`$TAG\` to the GitHub Release FAILED :x:. Nothing was published to PyPI. See <$RUN_URL|the run log>."
112
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
74
113
  -H 'Content-type: application/json' \
75
- --data "{\"text\":\"*plain-parser*: Build of \`${{ github.ref_name }}\` FAILED :x:. Nothing was published to PyPI. See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
114
+ --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
76
115
 
77
116
  publish-to-pypi:
78
117
  name: Publish to PyPI
79
- needs: build
118
+ needs: [build, upload-release-assets]
80
119
  runs-on: ubuntu-latest
81
120
  environment:
82
121
  name: pypi
@@ -86,9 +125,6 @@ jobs:
86
125
  # authenticate this run — no long-lived API token needed.
87
126
  id-token: write
88
127
 
89
- env:
90
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
91
-
92
128
  steps:
93
129
  - name: Download distribution packages
94
130
  uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -100,8 +136,10 @@ jobs:
100
136
  uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
101
137
 
102
138
  - name: Notify Slack (success)
103
- if: ${{ success() && env.SLACK_WEBHOOK_URL != '' }}
139
+ if: success()
140
+ continue-on-error: true
104
141
  env:
142
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
105
143
  # GitHub marks the release itself as a pre-release; the tag
106
144
  # (v0.2.0rc1) carries the same intent for PEP 440.
107
145
  IS_PRERELEASE: ${{ github.event.release.prerelease }}
@@ -115,13 +153,19 @@ jobs:
115
153
  else
116
154
  TEXT="*plain-parser*: \`$TAG\` published to PyPI :white_check_mark:. Install with \`pip install --upgrade plain-parser\`."
117
155
  fi
118
- curl -s -X POST "$SLACK_WEBHOOK_URL" \
156
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
119
157
  -H 'Content-type: application/json' \
120
158
  --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
121
159
 
122
160
  - name: Notify Slack (failure)
123
- if: ${{ failure() && env.SLACK_WEBHOOK_URL != '' }}
161
+ if: failure()
162
+ continue-on-error: true
163
+ env:
164
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
165
+ TAG: ${{ github.ref_name }}
124
166
  run: |
125
- curl -s -X POST "$SLACK_WEBHOOK_URL" \
167
+ RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
168
+ TEXT="*plain-parser*: Publishing \`$TAG\` to PyPI FAILED :x:. See <$RUN_URL|the run log>."
169
+ curl -sS --fail -X POST "$SLACK_WEBHOOK_URL" \
126
170
  -H 'Content-type: application/json' \
127
- --data "{\"text\":\"*plain-parser*: Publishing \`${{ github.ref_name }}\` to PyPI FAILED :x:. See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
171
+ --data "$(jq -n --arg t "$TEXT" '{text:$t}')"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: plain-parser
3
- Version: 0.1.2.dev6
3
+ Version: 0.1.3
4
4
  Summary: Parser for ***plain specification files
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -1,5 +1,5 @@
1
1
  [build-system]
2
- requires = ["hatchling", "hatch-vcs"]
2
+ requires = ["hatchling>=1.32,<2", "hatch-vcs>=0.5,<0.6"]
3
3
  build-backend = "hatchling.build"
4
4
 
5
5
  [project]
@@ -715,11 +715,13 @@ def process_required_modules(
715
715
  all_required_modules: list[str],
716
716
  modules_trace: list[str],
717
717
  chain: list[tuple[str, dict]],
718
+ module_exports: dict[str, list[mistletoe.block_token.token]],
718
719
  ) -> list[mistletoe.block_token.token]:
719
720
  """Parse and fully validate every required module, deepest first.
720
721
 
721
- Appends ``(module name, marshalled plain source tree)`` to ``chain`` for each module not already in it
722
- and returns the exported definitions of the directly required modules.
722
+ Appends ``(module name, marshalled plain source tree)`` to ``chain`` for each module not already in it,
723
+ records each module's exported definitions in ``module_exports``, and returns the exported definitions
724
+ of the directly required modules.
723
725
  """
724
726
  exported_definitions = list[mistletoe.block_token.token]()
725
727
  for module_name in required_modules:
@@ -727,6 +729,8 @@ def process_required_modules(
727
729
  raise PlainSyntaxError(f"Plain syntax error: Circular required module detected: {module_name}.")
728
730
 
729
731
  if len(all_required_modules) > 0 and module_name == all_required_modules[-1]:
732
+ # Already processed as an earlier entry; its exports are still visible to this module.
733
+ exported_definitions.extend(module_exports[module_name])
730
734
  continue
731
735
 
732
736
  code_variables: dict = {}
@@ -750,8 +754,10 @@ def process_required_modules(
750
754
  all_required_modules,
751
755
  modules_trace + [module_name],
752
756
  chain,
757
+ module_exports,
753
758
  )
754
759
 
760
+ own_exported_definitions = list[mistletoe.block_token.token]()
755
761
  if EXPORTED_CONCEPTS_DIRECTIVE in plain_file_parse_result.plain_source_obj.metadata:
756
762
  exported_concepts = list[str]()
757
763
  for concept in plain_file_parse_result.plain_source_obj.metadata[EXPORTED_CONCEPTS_DIRECTIVE]:
@@ -759,11 +765,13 @@ def process_required_modules(
759
765
 
760
766
  with PlainRenderer() as renderer:
761
767
  for exported_concept in exported_concepts:
762
- exported_definitions.extend(
768
+ own_exported_definitions.extend(
763
769
  concept_utils.find_concept_definitions_in_plain_source(
764
770
  exported_concept, plain_file_parse_result.plain_source, renderer
765
771
  )
766
772
  )
773
+ module_exports[module_name] = own_exported_definitions
774
+ exported_definitions.extend(own_exported_definitions)
767
775
 
768
776
  marshalled_plain_source = validate_and_marshall_module(
769
777
  plain_file_parse_result, module_name, ancestor_exported_definitions, code_variables, template_dirs
@@ -889,6 +897,7 @@ def _parse_module(
889
897
  all_required_modules=[],
890
898
  modules_trace=[],
891
899
  chain=chain,
900
+ module_exports={},
892
901
  )
893
902
 
894
903
  marshalled_plain_source = validate_and_marshall_module(
@@ -0,0 +1,12 @@
1
+ ---
2
+ requires:
3
+ - shared_export_top
4
+ ---
5
+
6
+ ***implementation reqs***
7
+
8
+ - Above implementation requirement.
9
+
10
+ ***functional specs***
11
+
12
+ - An above functionality.
@@ -0,0 +1,16 @@
1
+ ---
2
+ exported_concepts:
3
+ - :KeyStore:
4
+ ---
5
+
6
+ ***definitions***
7
+
8
+ - :KeyStore: holds encryption keys.
9
+
10
+ ***implementation reqs***
11
+
12
+ - Base implementation requirement.
13
+
14
+ ***functional specs***
15
+
16
+ - :KeyStore: stores a key.
@@ -0,0 +1,12 @@
1
+ ---
2
+ requires:
3
+ - shared_export_base
4
+ ---
5
+
6
+ ***implementation reqs***
7
+
8
+ - The functions of :KeyStore: are used to obtain keys.
9
+
10
+ ***functional specs***
11
+
12
+ - A middle functionality.
@@ -0,0 +1,13 @@
1
+ ---
2
+ requires:
3
+ - shared_export_base
4
+ - shared_export_middle
5
+ ---
6
+
7
+ ***implementation reqs***
8
+
9
+ - Keys are read through :KeyStore:.
10
+
11
+ ***functional specs***
12
+
13
+ - A top functionality.