blockwatch-cli 0.16.0__tar.gz → 0.16.1__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 (303) hide show
  1. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/CHANGELOG.md +12 -0
  2. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/Cargo.lock +1 -1
  3. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/Cargo.toml +1 -1
  4. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/PKG-INFO +1 -1
  5. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/README.md +5 -4
  6. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/blockwatch.toml +1 -1
  7. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/ci.md +2 -2
  8. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/cli.md +3 -3
  9. blockwatch_cli-0.16.1/docs/symbols.md +482 -0
  10. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/setup.py +1 -1
  11. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/config.rs +5 -3
  12. blockwatch_cli-0.16.1/src/language_parsers/c.rs +1179 -0
  13. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/cpp.rs +4 -2
  14. blockwatch_cli-0.16.1/src/language_parsers/go.rs +635 -0
  15. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/javascript.rs +9 -2
  16. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/json.rs +2 -0
  17. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/markdown.rs +6 -5
  18. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/mdx.rs +5 -4
  19. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/mod.rs +63 -12
  20. blockwatch_cli-0.16.1/src/language_parsers/python.rs +635 -0
  21. blockwatch_cli-0.16.1/src/language_parsers/rust.rs +517 -0
  22. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/starlark.rs +9 -2
  23. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/toml.rs +6 -4
  24. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/tsx.rs +9 -2
  25. blockwatch_cli-0.16.1/src/language_parsers/typescript.rs +686 -0
  26. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/yaml.rs +6 -4
  27. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/lib.rs +3 -0
  28. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/scan.rs +6 -5
  29. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/skill.md +76 -2
  30. blockwatch_cli-0.16.1/src/symbols/code.rs +716 -0
  31. blockwatch_cli-0.16.0/src/symbols.rs → blockwatch_cli-0.16.1/src/symbols/mod.rs +192 -117
  32. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/mod.rs +31 -10
  33. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/virtual_blocks.rs +11 -6
  34. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/general.rs +2 -2
  35. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/symbol_references.rs +70 -0
  36. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/pattern.py +2 -2
  37. blockwatch_cli-0.16.1/tests/testdata/check_lua/pattern_many_matches.py +6 -0
  38. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/pattern_no_match.py +1 -1
  39. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/custom_file_extension.python +1 -1
  40. blockwatch_cli-0.16.1/tests/testdata/symbol_references/bzl_source.rs +3 -0
  41. blockwatch_cli-0.16.1/tests/testdata/symbol_references/bzl_target.bzl +1 -0
  42. blockwatch_cli-0.16.1/tests/testdata/symbol_references/c_source.rs +3 -0
  43. blockwatch_cli-0.16.1/tests/testdata/symbol_references/c_target.c +1 -0
  44. blockwatch_cli-0.16.1/tests/testdata/symbol_references/cpp_source.rs +3 -0
  45. blockwatch_cli-0.16.1/tests/testdata/symbol_references/cpp_target.cpp +1 -0
  46. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/escapes_source.rs +4 -4
  47. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/filter_source.rs +2 -2
  48. blockwatch_cli-0.16.1/tests/testdata/symbol_references/go_source.rs +3 -0
  49. blockwatch_cli-0.16.1/tests/testdata/symbol_references/go_target.go +3 -0
  50. blockwatch_cli-0.16.1/tests/testdata/symbol_references/h_source.rs +3 -0
  51. blockwatch_cli-0.16.1/tests/testdata/symbol_references/h_target.h +1 -0
  52. blockwatch_cli-0.16.1/tests/testdata/symbol_references/js_source.rs +3 -0
  53. blockwatch_cli-0.16.1/tests/testdata/symbol_references/js_target.js +1 -0
  54. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/json_source.rs +2 -2
  55. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/jsonc_source.rs +2 -2
  56. blockwatch_cli-0.16.1/tests/testdata/symbol_references/markdown_source.rs +3 -0
  57. blockwatch_cli-0.16.1/tests/testdata/symbol_references/md_source.rs +3 -0
  58. blockwatch_cli-0.16.1/tests/testdata/symbol_references/mdx_source.rs +3 -0
  59. blockwatch_cli-0.16.1/tests/testdata/symbol_references/mixed_list_source.rs +6 -0
  60. blockwatch_cli-0.16.1/tests/testdata/symbol_references/py_source.rs +3 -0
  61. blockwatch_cli-0.16.1/tests/testdata/symbol_references/py_target.py +1 -0
  62. blockwatch_cli-0.16.1/tests/testdata/symbol_references/rs_source.rs +3 -0
  63. blockwatch_cli-0.16.1/tests/testdata/symbol_references/rs_target.rs +1 -0
  64. blockwatch_cli-0.16.1/tests/testdata/symbol_references/toml_source.rs +3 -0
  65. blockwatch_cli-0.16.1/tests/testdata/symbol_references/ts_source.rs +3 -0
  66. blockwatch_cli-0.16.1/tests/testdata/symbol_references/ts_target.ts +1 -0
  67. blockwatch_cli-0.16.1/tests/testdata/symbol_references/tsx_source.rs +3 -0
  68. blockwatch_cli-0.16.1/tests/testdata/symbol_references/tsx_target.tsx +1 -0
  69. blockwatch_cli-0.16.1/tests/testdata/symbol_references/yaml_source.rs +3 -0
  70. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/yml_source.rs +2 -2
  71. blockwatch_cli-0.16.0/docs/symbols.md +0 -238
  72. blockwatch_cli-0.16.0/src/language_parsers/c.rs +0 -85
  73. blockwatch_cli-0.16.0/src/language_parsers/go.rs +0 -239
  74. blockwatch_cli-0.16.0/src/language_parsers/python.rs +0 -79
  75. blockwatch_cli-0.16.0/src/language_parsers/rust.rs +0 -126
  76. blockwatch_cli-0.16.0/src/language_parsers/typescript.rs +0 -117
  77. blockwatch_cli-0.16.0/tests/testdata/check_lua/pattern_many_matches.py +0 -6
  78. blockwatch_cli-0.16.0/tests/testdata/symbol_references/markdown_source.rs +0 -3
  79. blockwatch_cli-0.16.0/tests/testdata/symbol_references/md_source.rs +0 -3
  80. blockwatch_cli-0.16.0/tests/testdata/symbol_references/mdx_source.rs +0 -3
  81. blockwatch_cli-0.16.0/tests/testdata/symbol_references/mixed_list_source.rs +0 -6
  82. blockwatch_cli-0.16.0/tests/testdata/symbol_references/toml_source.rs +0 -3
  83. blockwatch_cli-0.16.0/tests/testdata/symbol_references/yaml_source.rs +0 -3
  84. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.agents/.claude-plugin/plugin.json +0 -0
  85. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.agents/skills/blockwatch/SKILL.md +0 -0
  86. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.claude-plugin/marketplace.json +0 -0
  87. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/dependabot.yml +0 -0
  88. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/blockwatch.yml +0 -0
  89. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/codeql.yml +0 -0
  90. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/markdownlint.yml +0 -0
  91. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/pypi.yml +0 -0
  92. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/release.yml +0 -0
  93. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/rust.yml +0 -0
  94. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.github/workflows/trusted-checks.yml +0 -0
  95. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.gitignore +0 -0
  96. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.markdownlint-cli2.yaml +0 -0
  97. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.pre-commit-config.yaml +0 -0
  98. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/.pre-commit-hooks.yaml +0 -0
  99. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/AGENTS.md +0 -0
  100. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/CLAUDE.md +0 -0
  101. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/LICENSE +0 -0
  102. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/SECURITY.md +0 -0
  103. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/clippy.toml +0 -0
  104. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/codecov.yml +0 -0
  105. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/demo.gif +0 -0
  106. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/dist-workspace.toml +0 -0
  107. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/agents.md +0 -0
  108. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/README.md +0 -0
  109. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/affects.md +0 -0
  110. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/check-ai.md +0 -0
  111. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/check-lua.md +0 -0
  112. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/keep-sorted.md +0 -0
  113. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/keep-unique.md +0 -0
  114. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/line-count.md +0 -0
  115. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/line-pattern.md +0 -0
  116. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/docs/validators/same-as.md +0 -0
  117. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/pypi/pyproject.toml +0 -0
  118. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/pyproject.toml +0 -0
  119. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/release.toml +0 -0
  120. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/scripts/check_language_count.lua +0 -0
  121. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/scripts/check_latest_gpt_nano_model.lua +0 -0
  122. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/block_parser.rs +0 -0
  123. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/blocks.rs +0 -0
  124. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/cli.rs +0 -0
  125. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/diff_parser.rs +0 -0
  126. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/explain.rs +0 -0
  127. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/flags.rs +0 -0
  128. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/fs.rs +0 -0
  129. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/bash.rs +0 -0
  130. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/c_sharp.rs +0 -0
  131. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/cmake.rs +0 -0
  132. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/css.rs +0 -0
  133. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/dart.rs +0 -0
  134. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/dockerfile.rs +0 -0
  135. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/elixir.rs +0 -0
  136. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/graphql.rs +0 -0
  137. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/groovy.rs +0 -0
  138. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/hcl.rs +0 -0
  139. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/html.rs +0 -0
  140. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/java.rs +0 -0
  141. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/json.scm +0 -0
  142. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/kotlin.rs +0 -0
  143. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/lean.rs +0 -0
  144. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/lua.rs +0 -0
  145. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/makefile.rs +0 -0
  146. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/nix.rs +0 -0
  147. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/ocaml.rs +0 -0
  148. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/php.rs +0 -0
  149. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/proto.rs +0 -0
  150. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/ruby.rs +0 -0
  151. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/scala.rs +0 -0
  152. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/sql.rs +0 -0
  153. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/swift.rs +0 -0
  154. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/language_parsers/xml.rs +0 -0
  155. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/main.rs +0 -0
  156. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/path_arguments.rs +0 -0
  157. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/paths_glob.rs +0 -0
  158. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/repo_path.rs +0 -0
  159. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/report.rs +0 -0
  160. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/sarif.rs +0 -0
  161. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/settings.rs +0 -0
  162. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/symbol_path.rs +0 -0
  163. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/tag_parser.rs +0 -0
  164. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/target_reference.rs +0 -0
  165. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/affects.rs +0 -0
  166. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/check_ai.rs +0 -0
  167. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/check_lua.rs +0 -0
  168. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/keep_sorted.rs +0 -0
  169. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/keep_unique.rs +0 -0
  170. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/line_count.rs +0 -0
  171. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/line_pattern.rs +0 -0
  172. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/validators/same_as.rs +0 -0
  173. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/src/violation_address.rs +0 -0
  174. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/affects.rs +0 -0
  175. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/check_ai.rs +0 -0
  176. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/check_lua.rs +0 -0
  177. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/common/empty.toml +0 -0
  178. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/common/mod.rs +0 -0
  179. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/config.rs +0 -0
  180. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/encoding.rs +0 -0
  181. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/explain.rs +0 -0
  182. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/keep_sorted.rs +0 -0
  183. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/keep_unique.rs +0 -0
  184. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/line_count.rs +0 -0
  185. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/line_pattern.rs +0 -0
  186. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/list.rs +0 -0
  187. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/path_arguments.rs +0 -0
  188. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/repository_root.rs +0 -0
  189. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/same_as.rs +0 -0
  190. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/sarif.rs +0 -0
  191. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/skill.rs +0 -0
  192. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/suppressions.rs +0 -0
  193. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/cross_file_source.rs +0 -0
  194. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/cross_file_target.md +0 -0
  195. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/custom_ext_source.javascript +0 -0
  196. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/custom_ext_target.javascript +0 -0
  197. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/dangling.md +0 -0
  198. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/missing_symbol.rs +0 -0
  199. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/more_added_than_deleted.py +0 -0
  200. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/multiline_tag_source.rs +0 -0
  201. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/multiline_tag_target.rs +0 -0
  202. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/nested_mapping_source.rs +0 -0
  203. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/nested_mapping_target.yaml +0 -0
  204. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/sibling.md +0 -0
  205. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/symbol_source.rs +0 -0
  206. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/symbol_target.json +0 -0
  207. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/table_source.rs +0 -0
  208. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/table_target.toml +0 -0
  209. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/tag_and_content_source.ts +0 -0
  210. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/tag_and_content_target.ts +0 -0
  211. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/whole_file_source.rs +0 -0
  212. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/affects/whole_file_target.json +0 -0
  213. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_ai/two_blocks.py +0 -0
  214. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/affects.lua +0 -0
  215. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/affects.py +0 -0
  216. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/affects_drift.py +0 -0
  217. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/blocking_io.lua +0 -0
  218. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/blocking_io.py +0 -0
  219. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/echo.lua +0 -0
  220. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/fail.lua +0 -0
  221. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/mode.py +0 -0
  222. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/os.lua +0 -0
  223. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/pathfmt/report_path.lua +0 -0
  224. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/pathfmt/source.py +0 -0
  225. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/success.lua +0 -0
  226. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/check_lua/success_and_failure.py +0 -0
  227. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/config/glob_target/config.toml +0 -0
  228. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/config/glob_target/package.json +0 -0
  229. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/config/glob_target/plugins/blue/package.json +0 -0
  230. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/config/glob_target/plugins/green/package.json +0 -0
  231. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/config/glob_target/plugins/red/package.json +0 -0
  232. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/explain/a.py +0 -0
  233. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/explain/check.lua +0 -0
  234. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/block_selection.py +0 -0
  235. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/custom_file_extension.javascript +0 -0
  236. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/disable_enable.py +0 -0
  237. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/paths/invalid.py +0 -0
  238. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/paths/subdir/nested_invalid.py +0 -0
  239. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/paths/valid.py +0 -0
  240. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/general/severity.py +0 -0
  241. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/hidden/.github/workflows/ci.yml +0 -0
  242. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/keep_sorted/orderings.py +0 -0
  243. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/keep_unique/basic_and_pattern.py +0 -0
  244. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/line_count/equality_and_greater_than.py +0 -0
  245. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/line_pattern/forbidden_text.py +0 -0
  246. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/line_pattern/hex_and_word_patterns.py +0 -0
  247. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/list/.hg/.gitkeep +0 -0
  248. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/list/a.py +0 -0
  249. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/list/b.py +0 -0
  250. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/positions/unicode_columns.py +0 -0
  251. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/custom_ext_source.javascript +0 -0
  252. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/custom_ext_target.javascript +0 -0
  253. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/package.json +0 -0
  254. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/paths/alpha/item.txt +0 -0
  255. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/paths/beta/item.txt +0 -0
  256. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/paths_and_block_source.md +0 -0
  257. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/paths_source.md +0 -0
  258. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/sibling.rs +0 -0
  259. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/source.rs +0 -0
  260. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/split_table_source.rs +0 -0
  261. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/split_table_target.toml +0 -0
  262. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/symbol_mismatch_source.rs +0 -0
  263. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/symbol_source.rs +0 -0
  264. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/target.md +0 -0
  265. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/whole_file_mismatch_source.rs +0 -0
  266. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/whole_file_source.rs +0 -0
  267. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/same_as/whole_file_target.json +0 -0
  268. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/sarif/advisory.py +0 -0
  269. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/sarif/clean.py +0 -0
  270. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/sarif/sorted.py +0 -0
  271. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/sarif/unnamed.py +0 -0
  272. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/commit_msg.txt +0 -0
  273. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/commit_msg_gone_a.txt +0 -0
  274. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/commit_msg_gone_b.txt +0 -0
  275. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/commit_msg_lowercase_trailer.txt +0 -0
  276. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/commit_msg_malformed.txt +0 -0
  277. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/commit_msg_with_noise.txt +0 -0
  278. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/dangling.py +0 -0
  279. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/sorted.py +0 -0
  280. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/symbol.py +0 -0
  281. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/symbol_target.json +0 -0
  282. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/two_rules.py +0 -0
  283. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/suppressions/unnamed.py +0 -0
  284. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/escapes_target.json +0 -0
  285. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/filter_target.yaml +0 -0
  286. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/json_target.json +0 -0
  287. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/jsonc_target.jsonc +0 -0
  288. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/markdown_target.markdown +0 -0
  289. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/md_target.md +0 -0
  290. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/mdx_target.mdx +0 -0
  291. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/mixed_list_target.json +0 -0
  292. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/toml_target.toml +0 -0
  293. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/yaml_target.yaml +0 -0
  294. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/symbol_references/yml_target.yml +0 -0
  295. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/affects/pair.py +0 -0
  296. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/clean/counted.py +0 -0
  297. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/clean/noop.py +0 -0
  298. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/clean/notes.txt +0 -0
  299. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/clean/sorted.py +0 -0
  300. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/diff/two_blocks.py +0 -0
  301. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/failing/unsorted.py +0 -0
  302. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/testdata/verbosity/mixed/both_kinds.py +0 -0
  303. {blockwatch_cli-0.16.0 → blockwatch_cli-0.16.1}/tests/verbosity.rs +0 -0
@@ -12,6 +12,18 @@ Releases up to and including v0.3.11 predate this file. Their notes live on the
12
12
 
13
13
  ## [Unreleased] - ReleaseDate
14
14
 
15
+ ## [0.16.1] - 2026-10-28
16
+
17
+ ### Added
18
+
19
+ - Symbols in Go, C, C++, Python, Starlark, Rust, TypeScript and JavaScript files. `consts.go#/MaxPorts` points at a
20
+ top-level constant, variable, type or function, and `limits.h#/MAX_PORTS` at a macro. A value is the initializer as
21
+ written, such as `20 * 1024 * 1024`, so `same-as` can compare it with a constant in another file without a
22
+ `target-pattern`. A syntax error stops the run only for the names near it. See [Code files](docs/symbols.md#code-files),
23
+ [Go](docs/symbols.md#go), [C and C++](docs/symbols.md#c-and-c),
24
+ [Python and Starlark](docs/symbols.md#python-and-starlark), [Rust](docs/symbols.md#rust) and
25
+ [TypeScript and JavaScript](docs/symbols.md#typescript-and-javascript).
26
+
15
27
  ## [0.16.0] - 2026-10-24
16
28
 
17
29
  ### Changed
@@ -274,7 +274,7 @@ checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
274
274
 
275
275
  [[package]]
276
276
  name = "blockwatch"
277
- version = "0.16.0"
277
+ version = "0.16.1"
278
278
  dependencies = [
279
279
  "anyhow",
280
280
  "assert-json-diff",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "blockwatch"
3
- version = "0.16.0"
3
+ version = "0.16.1"
4
4
  edition = "2024"
5
5
  repository = "https://github.com/mennanov/blockwatch"
6
6
  description = "Language agnostic linter that keeps your code and documentation in sync and valid"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blockwatch-cli
3
- Version: 0.16.0
3
+ Version: 0.16.1
4
4
  Summary: Language agnostic linter that keeps your code and documentation in sync and valid
5
5
  Keywords: linter,sync,drift,comments,agents
6
6
  Home-Page: https://github.com/mennanov/blockwatch
@@ -88,9 +88,10 @@ Two validators work across files:
88
88
  - `affects` fails when a diff touches a block without also changing what it points to.
89
89
  - `same-as` fails when a block and its target hold different values. It needs no diff.
90
90
 
91
- Both can point to a block, a whole file, a specific value in a file like `package.json#/version`, or a section of a
92
- Markdown file (see [Symbols](docs/symbols.md)). The other validators check a single block on their own: the things
93
- you'd otherwise have to nitpick in code review.
91
+ Both can point to a block, a whole file, a specific value in a file like `package.json#/version`, a section of a
92
+ Markdown file, or a constant in a Go, C, C++, Python, Rust, TypeScript or JavaScript file (see
93
+ [Symbols](docs/symbols.md)). The other validators check a single block on their own: the things you'd otherwise have to
94
+ nitpick in code review.
94
95
 
95
96
  <!-- <block name="available-validators"
96
97
  same-as="src/validators/mod.rs:validator-registry, docs/validators/README.md:validators-index"
@@ -218,7 +219,7 @@ exclusions, and custom extension mappings.
218
219
 
219
220
  ```yaml
220
221
  - repo: https://github.com/mennanov/blockwatch
221
- rev: v0.16.0 # Use latest release
222
+ rev: v0.16.1 # Use latest release
222
223
  hooks:
223
224
  - id: blockwatch
224
225
  ```
@@ -50,4 +50,4 @@ same-as-pattern = '^\|\s*`(?P<value>[a-z-]+)`'
50
50
  [[block]]
51
51
  target = 'src/skill.md#/blockwatch/Symbols/Files with symbols'
52
52
  name = 'extensions-with-symbols'
53
- same-as-pattern = '`\.?(?P<value>[A-Za-z]+)`'
53
+ same-as-pattern = '`\.?(?P<value>[A-Za-z.]+)`'
@@ -19,7 +19,7 @@ To use [pre-commit](https://pre-commit.com), add the hook to `.pre-commit-config
19
19
 
20
20
  ```yaml
21
21
  - repo: https://github.com/mennanov/blockwatch
22
- rev: v0.16.0 # Use latest release
22
+ rev: v0.16.1 # Use latest release
23
23
  hooks:
24
24
  - id: blockwatch
25
25
  ```
@@ -59,7 +59,7 @@ The `blockwatch` hook runs before the commit message exists, so it cannot see a
59
59
 
60
60
  ```yaml
61
61
  - repo: https://github.com/mennanov/blockwatch
62
- rev: v0.16.0 # Use latest release
62
+ rev: v0.16.1 # Use latest release
63
63
  hooks:
64
64
  - id: blockwatch-commit-msg
65
65
  ```
@@ -557,15 +557,15 @@ Nothing else about the run changes: the same violations are found, and the exit
557
557
  "tool": {
558
558
  "driver": {
559
559
  "name": "blockwatch",
560
- "version": "0.16.0",
561
- "semanticVersion": "0.16.0",
560
+ "version": "0.16.1",
561
+ "semanticVersion": "0.16.1",
562
562
  "informationUri": "https://github.com/mennanov/blockwatch",
563
563
  "rules": [
564
564
  {
565
565
  "id": "keep-sorted",
566
566
  "name": "keep-sorted",
567
567
  "shortDescription": { "text": "Requires the lines of a block to stay in order." },
568
- "helpUri": "https://github.com/mennanov/blockwatch/blob/v0.16.0/docs/validators/keep-sorted.md"
568
+ "helpUri": "https://github.com/mennanov/blockwatch/blob/v0.16.1/docs/validators/keep-sorted.md"
569
569
  }
570
570
  ]
571
571
  }
@@ -0,0 +1,482 @@
1
+ # Symbols
2
+
3
+ A **symbol** is one value inside a file, such as the `version` key in `package.json`. A block points at a symbol with
4
+ a target like `package.json#/version`. The part after `#` is the symbol's **path**. A target like `#/version` points
5
+ into the block's own file.
6
+
7
+ ```rust
8
+ // <block same-as="package.json#/version">
9
+ pub const VERSION: &str = "1.4.2";
10
+ // </block>
11
+ ```
12
+
13
+ Three validators use symbols:
14
+
15
+ - [`same-as`](validators/same-as.md#symbols-as-targets) compares a block with a symbol's value.
16
+ - [`affects`](validators/affects.md#symbols) counts a symbol as changed only when the diff touches it.
17
+ - [`check-lua`](validators/check-lua.md) gives a script the value of each symbol the block's `affects` points at.
18
+
19
+ A [virtual block](cli.md#blocks-in-the-config-file) can wrap a symbol too. It is a block that the config file
20
+ declares, instead of tags in a comment.
21
+
22
+ ## Files with symbols
23
+
24
+ <!-- <block name="extensions-with-symbols" same-as="src/language_parsers/mod.rs:extensions-with-symbols"
25
+ same-as-pattern="`\.?(?P<value>[A-Za-z.]+)`"> -->
26
+
27
+ | Language | Files | Paths |
28
+ |------------|--------------------------------------------------------------------------------|---------------------------------------------------------|
29
+ | JSON | `.json`, `.jsonc`, `.webmanifest` | [JSON](#json) |
30
+ | TOML | `.toml`, `Pipfile` | [TOML](#toml) |
31
+ | YAML | `.yaml`, `.yml`, `.cff` | [YAML](#yaml) |
32
+ | Markdown | `.md`, `.markdown`, `.mdx` | [Markdown](#markdown) |
33
+ | Go | `.go` | [Go](#go) |
34
+ | C, C++ | `.c`, `.h`, `.cc`, `.cpp`, `.cxx`, `.hh`, `.hpp`, `.hxx` | [C and C++](#c-and-c) |
35
+ | Python | `.py`, `.pyi`, `.pyw` | [Python and Starlark](#python-and-starlark) |
36
+ | Starlark | `.bzl`, `.bazel`, `.bzlmod`, `.star`, `BUILD`, `BUCK`, `WORKSPACE`, `Tiltfile` | [Python and Starlark](#python-and-starlark) |
37
+ | Rust | `.rs` | [Rust](#rust) |
38
+ | TypeScript | `.ts`, `.mts`, `.cts`, `.d.ts`, `.tsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
39
+ | JavaScript | `.js`, `.mjs`, `.cjs`, `.jsx` | [TypeScript and JavaScript](#typescript-and-javascript) |
40
+
41
+ <!-- </block> -->
42
+
43
+ Other files have no symbols yet. blockwatch still reads their blocks: see
44
+ [Supported Languages](../README.md#supported-languages). A path into one of them stops the run.
45
+
46
+ A file you map to a language with `-E` gets that language's symbols. With `-E avsc=json`, `user.avsc#/name` works.
47
+
48
+ ## Writing a path
49
+
50
+ Paths follow [RFC 6901](https://www.rfc-editor.org/rfc/rfc6901), also called JSON Pointer:
51
+
52
+ - `/` separates keys: `#/dependencies/inngest`.
53
+ - An array item is its position, counted from 0: `#/files/0`.
54
+
55
+ Some characters must be escaped when a key contains them:
56
+
57
+ | Character | Escape | Why |
58
+ |-----------|--------|---------------------------------------|
59
+ | `/` | `~1` | it separates keys |
60
+ | `~` | `~0` | it starts an escape |
61
+ | `,` | `%2C` | it separates targets |
62
+ | `:` | `%3A` | it separates a file from a block name |
63
+ | `%` | `%25` | it starts an escape |
64
+
65
+ For example, the key `@types/node` is `#/dependencies/@types~1node`.
66
+
67
+ ## Picking an item by a key's value
68
+
69
+ A position breaks when someone adds an item above the one you mean. A **filter** picks the item by what it holds
70
+ instead: `~[key=value]` is the one item whose `key` holds `value`.
71
+
72
+ ```yaml
73
+ services:
74
+ - name: web
75
+ port: 8080
76
+ - name: worker
77
+ port: 9090
78
+ ```
79
+
80
+ | Path | Points at |
81
+ |----------------------------------|-----------|
82
+ | `#/services/1/port` | `9090` |
83
+ | `#/services/~[name=worker]/port` | `9090` |
84
+
85
+ - **Exactly one item must match.** No match is like a missing key. When the items have the key, the message suggests
86
+ the values that only one item holds: `did you mean: /services/~[name=worker]/port`. Several matches are a violation
87
+ too: `2 items match ~[name=web], at 2:5, 6:5`.
88
+ - **The value compares as a symbol reads it:** a string without its quotes, any other value as written. So
89
+ `~[port=8080]` matches `port: 8080` and `port: "8080"`.
90
+ - **Only a key right under the item counts.** A `name` deeper inside the item does not make it match.
91
+ - **A filter picks a map entry too.** In `{"a": {"name": "x"}}`, `#/~[name=x]` is `#/a`.
92
+ - **A path can hold several filters**, such as `#/groups/~[name=api]/services/~[name=web]/port`. A filter can come
93
+ first, in a file that is a list: `#/~[name=web]`.
94
+ - **The value starts after the first `=` and ends at the last `]`,** so it can hold both. The key can't hold `=`.
95
+ Inside a filter, escape the key and the value like any key: `/` as `~1`, `,` as `%2C`, and so on.
96
+
97
+ Keys that look like filters still work. `[python]`, as in VS Code settings, needs no escape. A key that starts with
98
+ `~[` is written `~0[`, as RFC 6901 already requires.
99
+
100
+ ## When a path does not resolve
101
+
102
+ - **A missing key is a violation.** The message suggests similar paths: `symbol not found; did you mean: /version`.
103
+ - **A broken file stops the run.** blockwatch does not guess what a broken file meant. In a code file, only a path to
104
+ a name near the error stops it: see [Code files](#code-files).
105
+ - **A missing file stops the run**, and so does a file without symbols.
106
+
107
+ A virtual block's target is stricter: a missing key, or a key written twice, stops the run too. Without one symbol to
108
+ wrap, the block has no content.
109
+
110
+ ## JSON
111
+
112
+ <!-- <block name="json-paths"> -->
113
+
114
+ Every key and every array item is a symbol:
115
+
116
+ ```json
117
+ {
118
+ "name": "app",
119
+ "files": ["dist", "README.md"],
120
+ "scripts": { "build": "tsc" }
121
+ }
122
+ ```
123
+
124
+ | Path | Points at |
125
+ |-------------------|-----------------|
126
+ | `#/name` | `"app"` |
127
+ | `#/files` | the whole array |
128
+ | `#/files/1` | `"README.md"` |
129
+ | `#/scripts/build` | `"tsc"` |
130
+
131
+ - **A file can be an array.** Then `#/0` is its first item.
132
+ - **A comment is not an array item.** It does not shift the positions of the items after it.
133
+ - **Comments are allowed** in `.json` and `.jsonc` alike. A trailing comma is an error in both, so it stops the run.
134
+ - **A key written twice is a violation**, because blockwatch can't tell which copy you mean. The message shows where
135
+ each copy is: `ambiguous symbol, defined at 2:3, 5:3`.
136
+
137
+ <!-- </block> -->
138
+
139
+ ## TOML
140
+
141
+ <!-- <block name="toml-paths"> -->
142
+
143
+ Every key, every table and every array item is a symbol. A path follows the keys, however the file writes them:
144
+
145
+ ```python
146
+ # <block same-as="pyproject.toml#/project/version" same-as-pattern="\d+\.\d+\.\d+">
147
+ __version__ = "0.8.4"
148
+ # </block>
149
+ ```
150
+
151
+ This works whether `pyproject.toml` has `version = "0.8.4"` under `[project]`, or `project.version = "0.8.4"` at the
152
+ top.
153
+
154
+ - **Headers and dotted keys make one path.** `[tool.ruff]` with `line-length = 88` below it is
155
+ `#/tool/ruff/line-length`, and so is `tool.ruff.line-length = 88`.
156
+ - **A quoted key is one part of the path**, dots and all. Under `[a]`, `"b.c" = 1` is `#/a/b.c`.
157
+ - **Each `[[bin]]` entry has a position**, counted from 0: `#/bin/0/name`. Entries of other arrays, written in between,
158
+ don't count.
159
+ - **A sub-table belongs to the entry above it.** `[fruits.physical]` after the first `[[fruits]]` is
160
+ `#/fruits/0/physical`.
161
+ - **A table covers every place it is written.** `#/package` covers `[package]` and `[package.metadata.docs]`, even
162
+ with other tables in between.
163
+ - **A key written twice breaks the file.** TOML does not allow it, so it stops the run.
164
+
165
+ <!-- </block> -->
166
+
167
+ ## YAML
168
+
169
+ <!-- <block name="yaml-paths"> -->
170
+
171
+ Every key and every list item is a symbol. Block style and flow style give the same paths:
172
+
173
+ ```yaml
174
+ jobs:
175
+ test:
176
+ runs-on: ubuntu-latest
177
+ steps:
178
+ - uses: actions/checkout@v4
179
+ - run: cargo test
180
+ ```
181
+
182
+ | Path | Points at |
183
+ |---------------------------|------------------|
184
+ | `#/jobs/test/runs-on` | `ubuntu-latest` |
185
+ | `#/jobs/test/steps` | the whole list |
186
+ | `#/jobs/test/steps/1/run` | `cargo test` |
187
+
188
+ - **A string counts as the text it holds.** Quotes and escapes are removed. A string written on several lines, `|` and
189
+ `>` blocks included, counts as YAML reads it.
190
+ - **Tags and anchors are not part of a value.** `!!str 123` gives `123`, and `&default 5` gives `5`.
191
+ - **An empty value**, as after `key:`, is an empty string.
192
+ - **An alias (`*name`) is not a symbol.** What it stands for is written elsewhere, so a path to it or through it is not
193
+ found. In a list, an alias still takes its position. `<<` is an ordinary key.
194
+ - **A key that is a list or a mapping,** such as `? [a, b]`, is skipped with everything under it.
195
+ - **A key written twice is a violation**, because blockwatch can't tell which copy you mean.
196
+ - **A file with several documents stops the run.** A path can't say which document it means. Put the value in a named
197
+ block instead.
198
+
199
+ <!-- </block> -->
200
+
201
+ ## Markdown
202
+
203
+ <!-- <block name="markdown-paths"> -->
204
+
205
+ Every section is a symbol. A section is a heading and everything up to the next heading of the same or a higher level.
206
+ Its path is the text of each heading it is under, then its own:
207
+
208
+ ```markdown
209
+ # Guide
210
+
211
+ ## Install
212
+
213
+ Run `cargo install blockwatch`.
214
+
215
+ ### From source
216
+
217
+ Clone the repository.
218
+ ```
219
+
220
+ | Path | Points at |
221
+ |-------------------------------|---------------------------------------------|
222
+ | `#/Guide` | everything below `# Guide` |
223
+ | `#/Guide/Install` | `Run …` and the whole `From source` section |
224
+ | `#/Guide/Install/From source` | `Clone the repository.` |
225
+
226
+ - **The top `#` title is part of every path**, as above.
227
+ - **A section holds its subsections.** `affects` counts a change to any of its lines, the heading included.
228
+ - **A section's value is its text without the heading line.** `same-as` compares that text. The blank lines around it
229
+ don't count.
230
+ - **A heading counts as a reader sees it.** ``## The `--diff` flag`` is `#/The --diff flag`. Code, emphasis and links
231
+ lose their markup.
232
+ - **Headings underlined with `===` or `---` count.** A `#` line in a code block doesn't. Neither does a heading in a
233
+ quote, a list item or an HTML block.
234
+ - **The same heading twice under one parent is a violation**, because blockwatch can't tell which one you mean. Two
235
+ `### Example` sections under different `##` headings are fine.
236
+ - **Escape a heading like any key.** `## Input/Output` is `#/Input~1Output`, and `## Step 1: build` is
237
+ `#/Step 1%3A build`.
238
+ - **An `.mdx` file gets the same paths.** The text of a JSX element in a heading counts, and so does the code in
239
+ braces: `## Red <Badge>new</Badge> {version}` is `#/Red new version`. A heading inside a JSX element doesn't count.
240
+ A file that isn't valid MDX stops the run.
241
+
242
+ <!-- </block> -->
243
+
244
+ ## Code files
245
+
246
+ <!-- <block name="code-files"> -->
247
+
248
+ In a code file, each top-level name is a symbol: a constant, a variable, a type, a function or a macro. Its path is
249
+ `#/NAME`.
250
+ With `const MaxPorts = 8` in `consts.go`, `consts.go#/MaxPorts` points at `8`.
251
+
252
+ - **A value is the initializer as written.** blockwatch never works it out: `20 * 1024 * 1024` stays as it is, and so
253
+ does `0x10`. Use `same-as-pattern` to take the part you need.
254
+ - **A string counts as the text it holds.** Quotes and escapes are removed.
255
+ - **Parentheses around the whole value are removed.** `(32)` is `32`. In `(1) + (2)`, they stay.
256
+ - **A name without a value**, such as a function or a type, gives the text of its whole definition.
257
+ - **A symbol covers its own definition**, keywords included, but not the comments above it. `affects` counts a change
258
+ to that text only.
259
+ - **A name defined twice is a violation**, because blockwatch can't tell which copy you mean.
260
+ - **A syntax error stops the run only for the names near it**: a name whose definition holds the error, and any name in
261
+ the text that the parser had to skip. Other names in the file still resolve. The message shows where the error is.
262
+ - **A string that blockwatch can't decode stops the run** for its name only.
263
+ - **Members are not symbols yet**, such as a method or a field.
264
+
265
+ <!-- </block> -->
266
+
267
+ ## Go
268
+
269
+ <!-- <block name="go-paths"> -->
270
+
271
+ ```go
272
+ const ExprStatusBits = 4
273
+
274
+ const (
275
+ DNSPortsMax = 8
276
+ ModeA Mode = iota
277
+ ModeB
278
+ )
279
+
280
+ var Name, Port = "web", 8080
281
+
282
+ type Server struct{ port int }
283
+
284
+ func Helper() {}
285
+ ```
286
+
287
+ | Path | Points at |
288
+ |--------------------|--------------------------------------------|
289
+ | `#/ExprStatusBits` | `4` |
290
+ | `#/DNSPortsMax` | `8` |
291
+ | `#/ModeB` | `ModeB`, its line, as it has no value |
292
+ | `#/Port` | `8080` |
293
+ | `#/Server` | the whole `type Server struct{ port int }` |
294
+ | `#/Helper` | the whole function |
295
+
296
+ - **In a group, such as `const ( ... )`, a name covers only its own line.** Outside a group, it covers the whole
297
+ declaration, `const` included.
298
+ - **Names get their values by position.** In `var x, y = f()`, one call gives both names, so neither has a value.
299
+ - **A type is not part of a value.** `const X Mode = 3` is `3`.
300
+ - **Strings follow Go's escapes.** `"\xc3\xa9"` is `é`. A raw string loses its carriage returns. A rune, such as `'r'`,
301
+ stays as written. A string whose bytes are not UTF-8 text stops the run for its name.
302
+ - **Methods, `func init` and `_` are not symbols.**
303
+ - **`go.mod`, `go.sum` and `go.work` have no symbols.**
304
+
305
+ <!-- </block> -->
306
+
307
+ ## C and C++
308
+
309
+ <!-- <block name="c-paths"> -->
310
+
311
+ ```c
312
+ #define DNS_PORTS_MAX 8
313
+ #define FLAGS (1u << 4) // bits
314
+ #define NAME "ab" "cd"
315
+
316
+ static const int Retries = 3;
317
+
318
+ typedef enum throttle_mode { THROTTLE_A, THROTTLE_B = 2 } throttle_mode_t;
319
+
320
+ int helper(void) { return 0; }
321
+ ```
322
+
323
+ | Path | Points at |
324
+ |---------------------|--------------------------------------------------|
325
+ | `#/DNS_PORTS_MAX` | `8` |
326
+ | `#/FLAGS` | `1u << 4` |
327
+ | `#/NAME` | `abcd` |
328
+ | `#/Retries` | `3` |
329
+ | `#/throttle_mode_t` | the whole `typedef`, as does `#/throttle_mode` |
330
+ | `#/THROTTLE_B` | `2` |
331
+ | `#/helper` | the whole function |
332
+
333
+ - **A macro is a symbol wherever it is defined**, even inside an `#if` or a function. Its body reads like a variable's
334
+ value, without comments. A body over several lines keeps its backslashes. A body that is not one value, such as
335
+ `static inline`, is kept as written. `#define FOO_H` is the empty string. A macro with parameters has no value.
336
+ - **A macro defined in each branch of an `#if` is defined twice.** Wrap the copy you mean in a block instead.
337
+ - **A `/* */` comment inside a macro, such as `#define X 1 /* c */ + 2`, stops the run for that macro.** The parser
338
+ reads the rest of the line as code. A comment at the end of the line is fine.
339
+ - **The enumerators of a plain `enum` are top-level names**, as in C. Those of an `enum class` are not.
340
+ - **In `int a = 1, b = 2;`, a name covers only its own part.** Otherwise a name covers the whole declaration.
341
+ - **Prototypes and `extern` variables are not symbols.** The definition is.
342
+ - **`template <...>` and `extern "C"` are part of the definition.** The contents of `extern "C" { ... }` are top-level.
343
+ - **Strings follow C's escapes, and strings written one after the other are joined.** A raw string, `R"(...)"`, is its
344
+ text. `L`, `u` and `U` strings and character literals stay as written.
345
+ - **Namespaces, class members and names such as `Foo::bar` are not symbols yet.**
346
+
347
+ <!-- </block> -->
348
+
349
+ ## Python and Starlark
350
+
351
+ <!-- <block name="python-paths"> -->
352
+
353
+ ```python
354
+ PYTHON_VERSION = "3.12"
355
+ TIMEOUT: Final[int] = 30
356
+ A = B = 5
357
+
358
+ if TYPE_CHECKING:
359
+ MODE = "check"
360
+ else:
361
+ MODE = "run"
362
+
363
+ @dataclass
364
+ class Point:
365
+ x: int = 0
366
+
367
+ def load(path):
368
+ return path
369
+ ```
370
+
371
+ | Path | Points at |
372
+ |--------------------|--------------------------------------------|
373
+ | `#/PYTHON_VERSION` | `3.12` |
374
+ | `#/TIMEOUT` | `30` |
375
+ | `#/B` | `5`, as does `#/A` |
376
+ | `#/MODE` | a violation, as `MODE` is defined twice |
377
+ | `#/Point` | the whole class, `@dataclass` included |
378
+ | `#/load` | the whole function |
379
+
380
+ - **The bodies of a top-level `if`, `try` or `with` are top-level too**, as Python treats them. So a name defined in
381
+ two branches is defined twice. The bodies of `for`, `while` and `match` don't count.
382
+ - **`A = B = 5` gives both names the whole statement.** `X: int` has no value. `X += [...]` doesn't change the value
383
+ of `X`.
384
+ - **A decorator is part of the definition.**
385
+ - **Imports, `as` targets, `a, b = 1, 2`, `obj.x = 1` and `_` are not symbols.** A type alias is one, without a
386
+ value: `type Pair[T] = tuple[T, T]` is `#/Pair`.
387
+ - **Strings follow Python's escapes.** `"\xe9"` is `é`. An escape Python doesn't know, such as `\d`, stays as written.
388
+ A raw string is its text. An f-string without a field is its text, with `{{` as `{`. An f-string with a field and
389
+ bytes stay as written. A `\N{...}` escape stops the run for its name.
390
+ - **Starlark files, such as `BUILD` and `.bzl`, follow the same rules.** A rule call, such as
391
+ `cc_library(name = "lib")`, is not a symbol.
392
+ - **Class members are not symbols yet.**
393
+
394
+ <!-- </block> -->
395
+
396
+ ## Rust
397
+
398
+ <!-- <block name="rust-paths"> -->
399
+
400
+ ```rust
401
+ pub(crate) const MAX_MESSAGE_SIZE: usize = 20 * 1024 * 1024;
402
+ static NAMES: [&str; 2] = ["a", "b"];
403
+
404
+ #[cfg(unix)]
405
+ const PLATFORM: &str = "unix";
406
+ #[cfg(windows)]
407
+ const PLATFORM: &str = "windows";
408
+
409
+ #[derive(Debug)]
410
+ pub enum LogLevel {
411
+ Error,
412
+ }
413
+
414
+ fn run() {}
415
+ ```
416
+
417
+ | Path | Points at |
418
+ |----------------------|-----------------------------------------------|
419
+ | `#/MAX_MESSAGE_SIZE` | `20 * 1024 * 1024` |
420
+ | `#/NAMES` | `["a", "b"]` |
421
+ | `#/PLATFORM` | a violation, as `PLATFORM` is defined twice |
422
+ | `#/LogLevel` | the whole enum, `#[derive(Debug)]` included |
423
+ | `#/run` | the whole function |
424
+
425
+ - **Constants, statics, functions, types, traits, `macro_rules!` macros and modules are symbols.** A type is not part
426
+ of a value: `const X: u8 = 3` is `3`.
427
+ - **The attributes above an item are part of it**, such as `#[cfg(...)]`. Its doc comments are not.
428
+ - **A module with a body, such as `mod tests { ... }`, is a symbol, but the items in it are not yet.** `mod file;` is
429
+ not a symbol.
430
+ - **`impl` blocks, `use`, `extern` blocks, `const _` and items that a macro makes, such as in `lazy_static!`, are not
431
+ symbols.**
432
+ - **Strings follow Rust's escapes.** `"\u{e9}"` is `é`. A backslash at the end of a line also skips the spaces that
433
+ start the next line. A raw string is its text. Byte strings, C strings and characters stay as written.
434
+
435
+ <!-- </block> -->
436
+
437
+ ## TypeScript and JavaScript
438
+
439
+ <!-- <block name="typescript-paths"> -->
440
+
441
+ ```ts
442
+ export const MAX_RETRIES = 5;
443
+ const MODE = "dev" as const;
444
+ const A = 1, B = 2;
445
+
446
+ @sealed
447
+ export class Point {}
448
+
449
+ type Mode = "dev" | "prod";
450
+
451
+ function normalize(text: string): string {
452
+ return text;
453
+ }
454
+ ```
455
+
456
+ | Path | Points at |
457
+ |------------------|--------------------------------------------|
458
+ | `#/MAX_RETRIES` | `5` |
459
+ | `#/MODE` | `dev` |
460
+ | `#/B` | `2`, and covers only `B = 2` |
461
+ | `#/Point` | the whole class, `@sealed` included |
462
+ | `#/Mode` | the whole type |
463
+ | `#/normalize` | the whole function |
464
+
465
+ - **`const`, `let`, `var`, functions, classes, enums, interfaces, type aliases and namespaces are symbols.**
466
+ `export default function main() {}` is `#/main`.
467
+ - **Type syntax is not part of a value.** `"dev" as const` is `dev`, `x satisfies T` is `x`, and `x!` is `x`.
468
+ - **A function with overloads is its implementation**, the one with a body.
469
+ - **`declare const`, `declare function`, `declare module "x"` and `declare global` are not symbols.** They only state
470
+ types. A `declare class`, `enum` or `namespace` is one.
471
+ - **Imports, `export { ... }`, `const { a } = b`, `module.exports`, an anonymous `export default` and `_` are not
472
+ symbols.**
473
+ - **Strings follow JavaScript's escapes.** `"\uD83D\uDE00"` is `😀`. A template without `${...}` is its text. A template
474
+ with a field and a tagged template, such as ``String.raw`a` ``, stay as written. A legacy escape, such as `\07`,
475
+ stops the run for its name.
476
+ - **Enum members, class members and the contents of a namespace are not symbols yet.**
477
+
478
+ <!-- </block> -->
479
+
480
+ ---
481
+
482
+ [← Return to README](../README.md)
@@ -6,7 +6,7 @@ setup(
6
6
  name='blockwatch-pre-commit-placeholder',
7
7
  version='0.0.0',
8
8
  # <block name="blockwatch-cli-version" same-as-pattern="blockwatch-cli==(?P<value>\d+\.\d+\.\d+)">
9
- install_requires=['blockwatch-cli==0.16.0'],
9
+ install_requires=['blockwatch-cli==0.16.1'],
10
10
  # </block>
11
11
  # Without it, setuptools takes the directories under src/ for Python packages.
12
12
  packages=[],
@@ -9,7 +9,7 @@ use crate::paths_glob::{GLOB_CHARACTERS, PathsGlob};
9
9
  use crate::repo_path::RepoPath;
10
10
  use crate::settings::RawSettings;
11
11
  use crate::symbol_path::SymbolPath;
12
- use crate::symbols::{self, Symbol};
12
+ use crate::symbols::Symbols;
13
13
  use crate::target_reference::TargetReference;
14
14
  use crate::virtual_blocks::{ConfigEntry, Locator, TargetPattern, VirtualBlock};
15
15
  use anyhow::{Context, anyhow, bail};
@@ -249,13 +249,15 @@ fn reject_duplicate_blocks(blocks: &[VirtualBlock]) -> anyhow::Result<()> {
249
249
  fn is_entry_modified(
250
250
  text: &str,
251
251
  lines: &LineIndex,
252
- symbols: &[Symbol],
252
+ symbols: &Symbols,
253
253
  index: usize,
254
254
  line_changes: &LineChanges,
255
255
  ) -> anyhow::Result<bool> {
256
256
  // The symbol covers every line of the entry. The span that serde gives covers only its header.
257
257
  let path = SymbolPath::parse(&format!("/block/{index}"))?;
258
- let symbol = symbols::resolve(symbols, &path).map_err(|error| anyhow!(error.reason(text)))?;
258
+ let symbol = symbols
259
+ .resolve(&path)
260
+ .map_err(|error| anyhow!(error.reason(text)))?;
259
261
  Ok(symbol
260
262
  .def_byte_ranges
261
263
  .iter()