comicbox 5.3.0__tar.gz → 5.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 (638) hide show
  1. {comicbox-5.3.0 → comicbox-5.3.2}/.dockerignore +13 -12
  2. {comicbox-5.3.0 → comicbox-5.3.2}/.prettierignore +5 -4
  3. {comicbox-5.3.0 → comicbox-5.3.2}/.readthedocs.yaml +1 -1
  4. {comicbox-5.3.0 → comicbox-5.3.2}/NEWS.md +17 -0
  5. {comicbox-5.3.0 → comicbox-5.3.2}/PKG-INFO +2 -2
  6. comicbox-5.3.2/bin/_lib.sh +50 -0
  7. {comicbox-5.3.0 → comicbox-5.3.2}/bin/ci-reuse-dist.sh +13 -5
  8. {comicbox-5.3.0 → comicbox-5.3.2}/bin/cleanup-pypi-alpha.sh +16 -6
  9. comicbox-5.3.2/bin/dev-module.sh +13 -0
  10. comicbox-5.3.2/bin/docker-compose-exit.sh +7 -0
  11. {comicbox-5.3.0 → comicbox-5.3.2}/bin/docker-tag-latest.sh +9 -11
  12. comicbox-5.3.0/bin/find-sh.sh → comicbox-5.3.2/bin/find-files.sh +35 -7
  13. comicbox-5.3.2/bin/find-sh.sh +21 -0
  14. comicbox-5.3.2/bin/fix-docker.sh +12 -0
  15. {comicbox-5.3.0 → comicbox-5.3.2}/bin/fix.sh +4 -3
  16. {comicbox-5.3.0 → comicbox-5.3.2}/bin/hub_prune_stale.py +6 -1
  17. comicbox-5.3.2/bin/kill-eslint_d.sh +12 -0
  18. comicbox-5.3.2/bin/lint-ci.sh +17 -0
  19. {comicbox-5.3.0 → comicbox-5.3.2}/bin/lint-complexity.sh +0 -4
  20. comicbox-5.3.2/bin/lint-docker.sh +18 -0
  21. {comicbox-5.3.0 → comicbox-5.3.2}/bin/lint-python.sh +1 -1
  22. comicbox-5.3.2/bin/lint.sh +14 -0
  23. {comicbox-5.3.0 → comicbox-5.3.2}/bin/release_info.py +3 -1
  24. {comicbox-5.3.0 → comicbox-5.3.2}/bin/roman.py +10 -1
  25. comicbox-5.3.2/bin/sh-tools.sh +39 -0
  26. {comicbox-5.3.0 → comicbox-5.3.2}/bin/sort-ignore.sh +3 -2
  27. {comicbox-5.3.0 → comicbox-5.3.2}/bin/test-python.sh +5 -2
  28. comicbox-5.3.2/bin/uml.sh +9 -0
  29. comicbox-5.3.2/bin/version-node.sh +17 -0
  30. {comicbox-5.3.0 → comicbox-5.3.2}/bun.lock +51 -76
  31. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/common.mk +11 -5
  32. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/eslint.config.base.js +13 -16
  33. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/gha_std.mk +1 -0
  34. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/help.mk +7 -8
  35. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/node.mk +0 -3
  36. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/python.mk +6 -13
  37. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/rate_gate.py +2 -2
  38. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/sources/base.py +2 -2
  39. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/filename/schema.py +19 -12
  40. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_api/online_source.py +25 -11
  41. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_api/paced_session.py +3 -1
  42. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/online_session.py +39 -15
  43. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/process.py +5 -5
  44. {comicbox-5.3.0 → comicbox-5.3.2}/compose.yaml +1 -0
  45. {comicbox-5.3.0 → comicbox-5.3.2}/docs/NEWS.md +17 -0
  46. comicbox-5.3.2/docs/SCHEMAS.md +181 -0
  47. comicbox-5.3.2/docs/TAGS.md +56 -0
  48. {comicbox-5.3.0 → comicbox-5.3.2}/package.json +11 -12
  49. {comicbox-5.3.0 → comicbox-5.3.2}/pyproject.toml +20 -8
  50. {comicbox-5.3.0 → comicbox-5.3.2}/pyproject.toml.orig +42 -23
  51. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_rename.py +23 -0
  52. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_filename.py +42 -0
  53. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_metron_session_lifecycle.py +1 -1
  54. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_session.py +199 -3
  55. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_paced_session.py +1 -1
  56. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rate_gate_concurrency.py +4 -4
  57. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rate_limits.py +24 -7
  58. {comicbox-5.3.0 → comicbox-5.3.2}/uv.lock +799 -698
  59. comicbox-5.3.0/bin/dev-module.sh +0 -10
  60. comicbox-5.3.0/bin/docker-compose-exit.sh +0 -6
  61. comicbox-5.3.0/bin/fix-docker.sh +0 -11
  62. comicbox-5.3.0/bin/fix-sh.sh +0 -13
  63. comicbox-5.3.0/bin/kill-eslint_d.sh +0 -5
  64. comicbox-5.3.0/bin/lint-ci.sh +0 -12
  65. comicbox-5.3.0/bin/lint-darwin.sh +0 -10
  66. comicbox-5.3.0/bin/lint-docker.sh +0 -12
  67. comicbox-5.3.0/bin/lint-sh.sh +0 -14
  68. comicbox-5.3.0/bin/lint.sh +0 -12
  69. comicbox-5.3.0/bin/type-python.sh +0 -9
  70. comicbox-5.3.0/bin/uml.sh +0 -5
  71. comicbox-5.3.0/bin/version-node.sh +0 -15
  72. {comicbox-5.3.0 → comicbox-5.3.2}/.gitignore +22 -22
  73. {comicbox-5.3.0 → comicbox-5.3.2}/.shellcheckrc +0 -0
  74. {comicbox-5.3.0 → comicbox-5.3.2}/.shellignore +0 -0
  75. {comicbox-5.3.0 → comicbox-5.3.2}/Makefile +0 -0
  76. {comicbox-5.3.0 → comicbox-5.3.2}/README.md +0 -0
  77. {comicbox-5.3.0 → comicbox-5.3.2}/bin/clean-pycache.sh +0 -0
  78. {comicbox-5.3.0 → comicbox-5.3.2}/bin/fix-python.sh +0 -0
  79. {comicbox-5.3.0 → comicbox-5.3.2}/bin/lint-vulture.sh +0 -0
  80. {comicbox-5.3.0 → comicbox-5.3.2}/bin/prettier-nginx.sh +0 -0
  81. {comicbox-5.3.0 → comicbox-5.3.2}/bin/publish-pypi.sh +0 -0
  82. {comicbox-5.3.0 → comicbox-5.3.2}/bin/regenerate-pdf-test-pages.py +0 -0
  83. {comicbox-5.3.0 → comicbox-5.3.2}/bin/release-tag.sh +0 -0
  84. {comicbox-5.3.0 → comicbox-5.3.2}/bin/test-docker.sh +0 -0
  85. {comicbox-5.3.0 → comicbox-5.3.2}/bin/update-deps-node.sh +0 -0
  86. {comicbox-5.3.0 → comicbox-5.3.2}/bin/update-deps-python.sh +0 -0
  87. {comicbox-5.3.0 → comicbox-5.3.2}/bin/version-python.sh +0 -0
  88. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/ci.mk +0 -0
  89. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/docker.mk +0 -0
  90. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/docs.mk +0 -0
  91. {comicbox-5.3.0 → comicbox-5.3.2}/cfg/node_root.mk +0 -0
  92. {comicbox-5.3.0 → comicbox-5.3.2}/check-jsonschema.sh +0 -0
  93. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/__init__.py +0 -0
  94. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/_pdf.py +0 -0
  95. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/_rar.py +0 -0
  96. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/_rar_probe.rar +0 -0
  97. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/__init__.py +0 -0
  98. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/__init__.py +0 -0
  99. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/archive.py +0 -0
  100. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/archiveinfo.py +0 -0
  101. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/filenames.py +0 -0
  102. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/init.py +0 -0
  103. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/mtime.py +0 -0
  104. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/pages.py +0 -0
  105. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/read.py +0 -0
  106. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/sniff.py +0 -0
  107. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/archive/write.py +0 -0
  108. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/__init__.py +0 -0
  109. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/date.py +0 -0
  110. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/identifiers.py +0 -0
  111. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/issue.py +0 -0
  112. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/notes.py +0 -0
  113. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/pages.py +0 -0
  114. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/stamp.py +0 -0
  115. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/stories_title.py +0 -0
  116. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/url_identifiers.py +0 -0
  117. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/computed/urls.py +0 -0
  118. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/dump.py +0 -0
  119. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/dump_files.py +0 -0
  120. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/init.py +0 -0
  121. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/load.py +0 -0
  122. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/merge.py +0 -0
  123. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/metadata.py +0 -0
  124. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/normalize.py +0 -0
  125. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/online_covers.py +0 -0
  126. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/online_lookup.py +0 -0
  127. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/pages/__init__.py +0 -0
  128. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/pages/covers.py +0 -0
  129. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/pages/extract.py +0 -0
  130. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/print.py +0 -0
  131. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/sources.py +0 -0
  132. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/types.py +0 -0
  133. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/validate/__init__.py +0 -0
  134. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/box/validate/guess_format.py +0 -0
  135. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/cli/__init__.py +0 -0
  136. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/cli/__main__.py +0 -0
  137. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/cli/epilog.py +0 -0
  138. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/cli/parser.py +0 -0
  139. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/__init__.py +0 -0
  140. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/computed.py +0 -0
  141. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/formats.py +0 -0
  142. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/online/__init__.py +0 -0
  143. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/online/build.py +0 -0
  144. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/online/settings.py +0 -0
  145. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/online/template.py +0 -0
  146. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/paths.py +0 -0
  147. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/read.py +0 -0
  148. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config/settings.py +0 -0
  149. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/config_default.yaml +0 -0
  150. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/constants.py +0 -0
  151. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/__init__.py +0 -0
  152. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/archives.py +0 -0
  153. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/context.py +0 -0
  154. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/images.py +0 -0
  155. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/online.py +0 -0
  156. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/packages.py +0 -0
  157. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/render.py +0 -0
  158. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/result.py +0 -0
  159. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/doctor/settings.py +0 -0
  160. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/empty.py +0 -0
  161. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/__init__.py +0 -0
  162. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/comet.py +0 -0
  163. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/comicbookinfo.py +0 -0
  164. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/comicbox.py +0 -0
  165. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/comicinfo.py +0 -0
  166. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/generic/__init__.py +0 -0
  167. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/generic/age_rating.py +0 -0
  168. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/generic/role.py +0 -0
  169. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/maps/__init__.py +0 -0
  170. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/maps/age_rating.py +0 -0
  171. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/maps/formats.py +0 -0
  172. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/maps/identifiers.py +0 -0
  173. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/maps/reading_direction.py +0 -0
  174. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/maps/roles.py +0 -0
  175. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/enums/metroninfo.py +0 -0
  176. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/events.py +0 -0
  177. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/exceptions.py +0 -0
  178. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/__init__.py +0 -0
  179. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/_base.py +0 -0
  180. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/__init__.py +0 -0
  181. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/__init__.py +0 -0
  182. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/collection_fields.py +0 -0
  183. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/comicbox.py +0 -0
  184. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/comicinfo.py +0 -0
  185. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/enum_fields.py +0 -0
  186. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/fields.py +0 -0
  187. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/metroninfo.py +0 -0
  188. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/number_fields.py +0 -0
  189. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/pdf.py +0 -0
  190. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/pycountry.py +0 -0
  191. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/time_fields.py +0 -0
  192. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/union.py +0 -0
  193. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/fields/xml_fields.py +0 -0
  194. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/__init__.py +0 -0
  195. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/auto_engage.py +0 -0
  196. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/cli_overrides.py +0 -0
  197. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/cover_hash.py +0 -0
  198. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/credentials.py +0 -0
  199. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/matcher.py +0 -0
  200. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/outcome_stats.py +0 -0
  201. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/profile.py +0 -0
  202. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/prompt.py +0 -0
  203. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/rate_limits.py +0 -0
  204. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/retry.py +0 -0
  205. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/sanitize.py +0 -0
  206. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/selector.py +0 -0
  207. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/series_cache.py +0 -0
  208. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/series_filter.py +0 -0
  209. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/session_state.py +0 -0
  210. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/signals.py +0 -0
  211. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/sources/__init__.py +0 -0
  212. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/transform_helpers.py +0 -0
  213. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/vacuum.py +0 -0
  214. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/online/warn_once.py +0 -0
  215. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/__init__.py +0 -0
  216. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/base.py +0 -0
  217. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/cache.py +0 -0
  218. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/decorators.py +0 -0
  219. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/error_store.py +0 -0
  220. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/json_schemas.py +0 -0
  221. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/xml_schemas.py +0 -0
  222. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/schemas/yaml.py +0 -0
  223. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/__init__.py +0 -0
  224. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/base.py +0 -0
  225. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/identifiers.py +0 -0
  226. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/price.py +0 -0
  227. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/publishing_tags.py +0 -0
  228. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/spec.py +0 -0
  229. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/xml_credits.py +0 -0
  230. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/base/transforms/xml_reprints.py +0 -0
  231. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comet/__init__.py +0 -0
  232. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comet/schema.py +0 -0
  233. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comet/transform/__init__.py +0 -0
  234. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comet/transform/reprints.py +0 -0
  235. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_book_info/__init__.py +0 -0
  236. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_book_info/schema.py +0 -0
  237. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_book_info/transform/__init__.py +0 -0
  238. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_book_info/transform/credits.py +0 -0
  239. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_book_info/transform/rating.py +0 -0
  240. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/__init__.py +0 -0
  241. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/schema.py +0 -0
  242. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/transform/__init__.py +0 -0
  243. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/transform/identifiers.py +0 -0
  244. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/transform/manga.py +0 -0
  245. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/transform/pages.py +0 -0
  246. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comic_info/transform/storyarcs.py +0 -0
  247. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/__init__.py +0 -0
  248. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/README.md +0 -0
  249. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/__init__.py +0 -0
  250. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/cli.py +0 -0
  251. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/identifiers.py +0 -0
  252. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/json_schema.py +0 -0
  253. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/pages.py +0 -0
  254. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/publishing.py +0 -0
  255. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/schema/yaml.py +0 -0
  256. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/transform/__init__.py +0 -0
  257. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/transform/cli.py +0 -0
  258. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/transform/credits.py +0 -0
  259. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/transform/json.py +0 -0
  260. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/transform/name_objs.py +0 -0
  261. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicbox/transform/yaml.py +0 -0
  262. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicvine_api/__init__.py +0 -0
  263. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicvine_api/online_source.py +0 -0
  264. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicvine_api/schema.py +0 -0
  265. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/comicvine_api/transform.py +0 -0
  266. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/filename/__init__.py +0 -0
  267. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/filename/transform.py +0 -0
  268. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_api/__init__.py +0 -0
  269. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_api/schema.py +0 -0
  270. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_api/transform.py +0 -0
  271. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/__init__.py +0 -0
  272. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/__init__.py +0 -0
  273. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/credits.py +0 -0
  274. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/identifiers.py +0 -0
  275. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/price.py +0 -0
  276. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/publishing.py +0 -0
  277. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/rating.py +0 -0
  278. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/schema/resource.py +0 -0
  279. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/__init__.py +0 -0
  280. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/const.py +0 -0
  281. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/credits.py +0 -0
  282. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/identified_name.py +0 -0
  283. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/identifier_attribute.py +0 -0
  284. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/identifiers.py +0 -0
  285. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/publishing_tags.py +0 -0
  286. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/rating.py +0 -0
  287. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/reprints.py +0 -0
  288. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/metron_info/transform/resources.py +0 -0
  289. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/pdf/__init__.py +0 -0
  290. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/pdf/schema.py +0 -0
  291. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/pdf/transform/__init__.py +0 -0
  292. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/pdf/transform/credits.py +0 -0
  293. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/formats/sources.py +0 -0
  294. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/identifiers/__init__.py +0 -0
  295. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/identifiers/identifiers.py +0 -0
  296. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/identifiers/other.py +0 -0
  297. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/identifiers/urns.py +0 -0
  298. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/logger.py +0 -0
  299. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/merge/__init__.py +0 -0
  300. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/merge/mergedeep.py +0 -0
  301. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/online_estimate.py +0 -0
  302. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/predict.py +0 -0
  303. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/print.py +0 -0
  304. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/py.typed +0 -0
  305. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/run.py +0 -0
  306. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/CoMet-v1.1.xsd +0 -0
  307. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/ComicInfo-v2.1-Draft.xsd +0 -0
  308. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/MetronInfo-v1.1.xsd +0 -0
  309. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/comic-book-info-v1.0.schema.json +0 -0
  310. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v1.0/comicbox-v1.0.schema.json +0 -0
  311. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v1.0/page.schema.json +0 -0
  312. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v1.0/reprint.schema.json +0 -0
  313. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v1.0/series.schema.json +0 -0
  314. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v1.0/volume.schema.json +0 -0
  315. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/comicbox-v2.0.schema.json +0 -0
  316. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/comicbox.example.yaml +0 -0
  317. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/credit.schema.json +0 -0
  318. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/date.schema.json +0 -0
  319. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/identified-object.schema.json +0 -0
  320. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/identified-objects.schema.json +0 -0
  321. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/identifiers.schema.json +0 -0
  322. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/named-identified-object.schema.json +0 -0
  323. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/page.schema.json +0 -0
  324. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/reprint.schema.json +0 -0
  325. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/series.schema.json +0 -0
  326. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v2.0/volume.schema.json +0 -0
  327. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/alternative-name.schema.json +0 -0
  328. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/comicbox-v3.0.schema.json +0 -0
  329. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/comicbox.example.yaml +0 -0
  330. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/credit.schema.json +0 -0
  331. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/date.schema.json +0 -0
  332. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/identified-object.schema.json +0 -0
  333. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/identified-objects.schema.json +0 -0
  334. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/identifiers.schema.json +0 -0
  335. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/named-identified-object.schema.json +0 -0
  336. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/page.schema.json +0 -0
  337. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/reprint.schema.json +0 -0
  338. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/role.schema.json +0 -0
  339. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/series.schema.json +0 -0
  340. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/schemas/v3.0/volume.schema.json +0 -0
  341. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/validate/__init__.py +0 -0
  342. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/validate/base.py +0 -0
  343. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/validate/json_validator.py +0 -0
  344. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/validate/spec.py +0 -0
  345. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/validate/xml_validator.py +0 -0
  346. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/validate/yaml_validator.py +0 -0
  347. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/version.py +0 -0
  348. {comicbox-5.3.0 → comicbox-5.3.2}/comicbox/write.py +0 -0
  349. {comicbox-5.3.0 → comicbox-5.3.2}/docs/README.md +0 -0
  350. {comicbox-5.3.0 → comicbox-5.3.2}/docs/requirements.txt +0 -0
  351. {comicbox-5.3.0 → comicbox-5.3.2}/docs/style.css +0 -0
  352. {comicbox-5.3.0 → comicbox-5.3.2}/docs/style.mkdocs.css +0 -0
  353. {comicbox-5.3.0 → comicbox-5.3.2}/eslint.config.js +0 -0
  354. {comicbox-5.3.0 → comicbox-5.3.2}/generate-schema/gen-schema-docs.sh +0 -0
  355. {comicbox-5.3.0 → comicbox-5.3.2}/generate-schema/gen-schema.sh +0 -0
  356. {comicbox-5.3.0 → comicbox-5.3.2}/generate-schema/mjs.py +0 -0
  357. {comicbox-5.3.0 → comicbox-5.3.2}/mkdocs.yml +0 -0
  358. {comicbox-5.3.0 → comicbox-5.3.2}/tests/__init__.py +0 -0
  359. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/.gitignore +0 -0
  360. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/README.md +0 -0
  361. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/__init__.py +0 -0
  362. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/_harness_helpers.py +0 -0
  363. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/bootstrap.py +0 -0
  364. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/compare.py +0 -0
  365. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/debug_search.py +0 -0
  366. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/fixtures.example.json +0 -0
  367. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/label_metron.py +0 -0
  368. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/run.py +0 -0
  369. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/sample.py +0 -0
  370. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/summarize.py +0 -0
  371. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_bootstrap.py +0 -0
  372. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_compare.py +0 -0
  373. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_harness.py +0 -0
  374. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_harness_checkpoint.py +0 -0
  375. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_harness_diagnostics.py +0 -0
  376. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_harness_filter.py +0 -0
  377. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_harness_resume.py +0 -0
  378. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_label_metron.py +0 -0
  379. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_sample.py +0 -0
  380. {comicbox-5.3.0 → comicbox-5.3.2}/tests/calibration/test_summarize.py +0 -0
  381. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/__init__.py +0 -0
  382. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_doctor.py +0 -0
  383. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_exit_code.py +0 -0
  384. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_export.py +0 -0
  385. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_extract.py +0 -0
  386. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_online.py +0 -0
  387. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_print.py +0 -0
  388. {comicbox-5.3.0 → comicbox-5.3.2}/tests/cli/test_cli_write.py +0 -0
  389. {comicbox-5.3.0 → comicbox-5.3.2}/tests/conftest.py +0 -0
  390. {comicbox-5.3.0 → comicbox-5.3.2}/tests/const.py +0 -0
  391. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001 (1950) The Beginning - multi.cbz +0 -0
  392. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001 (1950) The Beginning - nothing.cbz +0 -0
  393. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001-cbi.cbr +0 -0
  394. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001-cix-cbi.cbr +0 -0
  395. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001-cix.cbt +0 -0
  396. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001-cix.cbz +0 -0
  397. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001-comet.cbz +0 -0
  398. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001-metron.cbz +0 -0
  399. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001.cb7 +0 -0
  400. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science #001.cbz +0 -0
  401. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/CaptainScience#1_01.jpg +0 -0
  402. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/CaptainScience#1_02.jpg +0 -0
  403. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/CaptainScience#1_03.jpg +0 -0
  404. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/CaptainScience#1_04.jpg +0 -0
  405. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/CaptainScience#1_05.jpg +0 -0
  406. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/CoMet.xml +0 -0
  407. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/comic-book-info.json +0 -0
  408. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/comicinfo-original.xml +0 -0
  409. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/comicinfo.xml +0 -0
  410. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/metroninfo-full.xml +0 -0
  411. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/Captain Science 001/metroninfo.xml +0 -0
  412. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/comicbox-cli.cbz +0 -0
  413. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/comicbox.cbz +0 -0
  414. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/create-archive.sh +0 -0
  415. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/create_cs_archives.py +0 -0
  416. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/create_macos_resource_fork.py +0 -0
  417. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/empty.cbz +0 -0
  418. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/examples/comic-book-info-example.json +0 -0
  419. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/examples/metroninfo-v1.1-valid.xml +0 -0
  420. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/comet.xml +0 -0
  421. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/comic-book-info.json +0 -0
  422. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/comicbox-cli.yaml +0 -0
  423. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/comicbox.json +0 -0
  424. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/comicbox.yaml +0 -0
  425. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/comicinfo.xml +0 -0
  426. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/create-export-archive.sh +0 -0
  427. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/metroninfo.xml +0 -0
  428. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/mupdf.json +0 -0
  429. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export/pdf-metadata.xml +0 -0
  430. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/export.cbz +0 -0
  431. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/list_recurse_output.txt +0 -0
  432. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/macos_resource_fork.cbz +0 -0
  433. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comet-cover-path-list.xml +0 -0
  434. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comet-write.xml +0 -0
  435. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comet.xml +0 -0
  436. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comic-book-info-example.json +0 -0
  437. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comic-book-info.json +0 -0
  438. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox-cli.yaml +0 -0
  439. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox-filename.txt +0 -0
  440. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox-write.json +0 -0
  441. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox-write.yaml +0 -0
  442. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox.json +0 -0
  443. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox.xml +0 -0
  444. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicbox.yaml +0 -0
  445. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-bad-multiple.xml +0 -0
  446. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-cover-path-list.xml +0 -0
  447. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-ids-from-tags.xml +0 -0
  448. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-metron-origin.xml +0 -0
  449. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-notes-date.xml +0 -0
  450. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-validation.xml +0 -0
  451. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo-write.xml +0 -0
  452. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/comicinfo.xml +0 -0
  453. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/create-archives.sh +0 -0
  454. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/metroninfo-no-primary-id.xml +0 -0
  455. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/metroninfo-v1.1-valid.xml +0 -0
  456. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/metroninfo-write.xml +0 -0
  457. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/metroninfo.xml +0 -0
  458. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/mupdf-nested.json +0 -0
  459. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/mupdf.json +0 -0
  460. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/pdf-cix.xml +0 -0
  461. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/pdf-nested.xml +0 -0
  462. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/metadata/pdf.xml +0 -0
  463. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/comet.xml +0 -0
  464. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/comic-book-info.json +0 -0
  465. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/comicbox-filename.txt +0 -0
  466. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/comicbox.json +0 -0
  467. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/comicbox.yaml +0 -0
  468. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/comicinfo.xml +0 -0
  469. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/multi/create-multi-archive.sh +0 -0
  470. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/patchme.cbz +0 -0
  471. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/pdf/0.pdf +0 -0
  472. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/pdf/1.pdf +0 -0
  473. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/pdf/2.pdf +0 -0
  474. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/pdf/3.pdf +0 -0
  475. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/test_cix.pdf +0 -0
  476. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/test_pdf.pdf +0 -0
  477. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/test_pdf_legacy_keywords.pdf +0 -0
  478. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/xml.cbz +0 -0
  479. {comicbox-5.3.0 → comicbox-5.3.2}/tests/files/yaml.cbz +0 -0
  480. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/__init__.py +0 -0
  481. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_cbi.py +0 -0
  482. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_cix.py +0 -0
  483. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_comet.py +0 -0
  484. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_json.py +0 -0
  485. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_json_schema_drift.py +0 -0
  486. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_metron.py +0 -0
  487. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_multi.py +0 -0
  488. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_pdf_json.py +0 -0
  489. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_pdf_xml.py +0 -0
  490. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_validation.py +0 -0
  491. {comicbox-5.3.0 → comicbox-5.3.2}/tests/schemas/test_yaml.py +0 -0
  492. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/.gitignore +0 -0
  493. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/README.md +0 -0
  494. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/__init__.py +0 -0
  495. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/jobs_accuracy.py +0 -0
  496. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/prompt_ux.py +0 -0
  497. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/run.py +0 -0
  498. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/test_jobs_accuracy.py +0 -0
  499. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/test_prompt_ux.py +0 -0
  500. {comicbox-5.3.0 → comicbox-5.3.2}/tests/stress/test_run.py +0 -0
  501. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_codex_api.py +0 -0
  502. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_compute.py +0 -0
  503. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_convert_pdf.py +0 -0
  504. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_extract.py +0 -0
  505. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_import_export.py +0 -0
  506. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_mtime.py +0 -0
  507. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_pages.py +0 -0
  508. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_stories_title.py +0 -0
  509. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_validate_testfiles.py +0 -0
  510. {comicbox-5.3.0 → comicbox-5.3.2}/tests/test_writing.py +0 -0
  511. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/__init__.py +0 -0
  512. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/cover_hash_golden.json +0 -0
  513. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_archive_errors.py +0 -0
  514. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_archive_read.py +0 -0
  515. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_archiveinfo_mtime.py +0 -0
  516. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_auto_engage.py +0 -0
  517. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_box_cache_invalidation.py +0 -0
  518. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_cbi_rating_normalize.py +0 -0
  519. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_cli_choices_enum_drift.py +0 -0
  520. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_cli_dest_folds.py +0 -0
  521. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_cli_dest_template_drift.py +0 -0
  522. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_comicinfo_alternates.py +0 -0
  523. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_comicinfo_series_groups.py +0 -0
  524. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_comicvine.py +0 -0
  525. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_comicvine_client.py +0 -0
  526. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_comicvine_session_lifecycle.py +0 -0
  527. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_computed_pipeline.py +0 -0
  528. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_computed_reprints.py +0 -0
  529. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_container_inputs.py +0 -0
  530. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_defaults_drift.py +0 -0
  531. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_enum_inputs.py +0 -0
  532. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_env_tree.py +0 -0
  533. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_errors.py +0 -0
  534. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_file_option.py +0 -0
  535. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_layering.py +0 -0
  536. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_no_path_guard.py +0 -0
  537. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_online_leaf.py +0 -0
  538. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_config_online_sources.py +0 -0
  539. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_cover_hash.py +0 -0
  540. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_cover_hash_parity.py +0 -0
  541. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_credit_primary.py +0 -0
  542. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_defer_prompts.py +0 -0
  543. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_destination_occupied_error.py +0 -0
  544. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_archives.py +0 -0
  545. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_images.py +0 -0
  546. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_online.py +0 -0
  547. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_online_verify.py +0 -0
  548. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_packages.py +0 -0
  549. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_render.py +0 -0
  550. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_doctor_settings.py +0 -0
  551. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_error_store_visibility.py +0 -0
  552. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_exceptions.py +0 -0
  553. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_identifiers.py +0 -0
  554. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_lazy_startup.py +0 -0
  555. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_library_logging.py +0 -0
  556. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_list_field_dedupe.py +0 -0
  557. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_list_field_sort_key_types.py +0 -0
  558. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_manga_and_age_rating.py +0 -0
  559. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_manga_volume.py +0 -0
  560. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_merge_mode_config.py +0 -0
  561. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_merge_order.py +0 -0
  562. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_merge_precedence.py +0 -0
  563. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_mergedeep.py +0 -0
  564. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_metron_community_rating.py +0 -0
  565. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_metron_id_attribute_fallback.py +0 -0
  566. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_metron_prefetch.py +0 -0
  567. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_metron_source.py +0 -0
  568. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_metron_transform.py +0 -0
  569. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online.py +0 -0
  570. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_abort_propagation.py +0 -0
  571. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_degradation.py +0 -0
  572. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_estimate.py +0 -0
  573. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_events.py +0 -0
  574. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_lookup.py +0 -0
  575. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_matcher.py +0 -0
  576. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_matcher_resolution.py +0 -0
  577. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_matcher_scoring.py +0 -0
  578. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_prompt.py +0 -0
  579. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_prompt_loops.py +0 -0
  580. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_result_contract.py +0 -0
  581. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_retry.py +0 -0
  582. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_selector.py +0 -0
  583. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_online_session_state.py +0 -0
  584. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_outcome_stats.py +0 -0
  585. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_parse_decimal.py +0 -0
  586. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_parse_issue.py +0 -0
  587. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_pdf_date_field.py +0 -0
  588. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_pdf_import_guard.py +0 -0
  589. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_pdf_pages_help.py +0 -0
  590. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_process.py +0 -0
  591. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_process_archive_errors.py +0 -0
  592. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_prompt_dedup.py +0 -0
  593. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_quota_reserved_skip.py +0 -0
  594. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rar_time_overflow.py +0 -0
  595. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rar_tool_probe.py +0 -0
  596. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rate_gate.py +0 -0
  597. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_read_events.py +0 -0
  598. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_refresh_cache.py +0 -0
  599. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rename_and_convert_safety.py +0 -0
  600. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_reprints_and_alternative_names.py +0 -0
  601. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_rich_transforms.py +0 -0
  602. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_role_vocabulary.py +0 -0
  603. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_run_parallel.py +0 -0
  604. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_run_recurse.py +0 -0
  605. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_series_cache.py +0 -0
  606. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_series_filter.py +0 -0
  607. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_series_single_flight.py +0 -0
  608. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_session_series_batching.py +0 -0
  609. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_single_valued_tags.py +0 -0
  610. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_sniff.py +0 -0
  611. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_sources.py +0 -0
  612. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_to_metron_age_rating.py +0 -0
  613. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_transform_spec_dest_collisions.py +0 -0
  614. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_transform_spec_missing_keys.py +0 -0
  615. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_transform_spec_scope_phases.py +0 -0
  616. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_urls_and_identifiers.py +0 -0
  617. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_vacuum.py +0 -0
  618. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_validate.py +0 -0
  619. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_write_api.py +0 -0
  620. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_write_destination_prediction.py +0 -0
  621. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_write_destination_safety.py +0 -0
  622. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_write_order_and_claims.py +0 -0
  623. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_xml_cdata_fields.py +0 -0
  624. {comicbox-5.3.0 → comicbox-5.3.2}/tests/unit/test_yes_no_field.py +0 -0
  625. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/__init__.py +0 -0
  626. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/compare.py +0 -0
  627. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/cover_images.py +0 -0
  628. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/diff.py +0 -0
  629. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/metadata.py +0 -0
  630. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/metron_transport.py +0 -0
  631. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/online_client.py +0 -0
  632. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/online_matcher.py +0 -0
  633. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/online_prompt.py +0 -0
  634. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/parser.py +0 -0
  635. {comicbox-5.3.0 → comicbox-5.3.2}/tests/util/tmp.py +0 -0
  636. {comicbox-5.3.0 → comicbox-5.3.2}/tests/validate_cli.py +0 -0
  637. {comicbox-5.3.0 → comicbox-5.3.2}/validate-schema.sh +0 -0
  638. {comicbox-5.3.0 → comicbox-5.3.2}/vulture_ignorelist.py +0 -0
@@ -1,22 +1,23 @@
1
- .claude
2
- .coverage*
3
- .env*
4
- .git
5
- .picopt_timestamp
6
- .ropeproject
7
- .venv*
8
- **/__pycache__
9
- **/.*cache
10
- **/.DS_Store
11
1
  **/*.egg-info
12
2
  **/*.py[co]
13
3
  **/*~
4
+ **/.*cache
5
+ **/.DS_Store
6
+ **/__pycache__
14
7
  **/node_modules
15
8
  **/test-results
16
9
  *Dockerfile
17
- docker-compose*
10
+ .claude/settings.local.json
11
+ .claude/worktrees
12
+ .coverage*
13
+ .env*
14
+ .git
15
+ .picopt_timestamp
16
+ .ropeproject
17
+ .venv*
18
18
  MANIFEST
19
- monkeytype.sqlite3
20
19
  NEWS
21
20
  TODO.md
21
+ docker-compose*
22
+ monkeytype.sqlite3
22
23
  version.sh
@@ -1,9 +1,10 @@
1
- __pycache__
2
- .*cache
3
- .claude
4
- .git
5
1
  *.sh
6
2
  *Dockerfile
3
+ .*cache
4
+ .claude/settings.local.json
5
+ .claude/worktrees/
6
+ .git
7
+ __pycache__
7
8
  bun.lock
8
9
  comicbox/schemas/*Info*.xsd
9
10
  dist
@@ -1,5 +1,5 @@
1
1
  build:
2
- os: ubuntu-24.04
2
+ os: ubuntu-lts-latest
3
3
  tools:
4
4
  python: "3"
5
5
  mkdocs:
@@ -1,5 +1,22 @@
1
1
  # 📰 News
2
2
 
3
+ ## v5.3.2
4
+
5
+ - Fixes
6
+ - Renamed files no longer contain colons or other characters Windows and SMB
7
+ shares can't store.
8
+ - Metron API tokens are used alone: leftover username/password settings no
9
+ longer warn, and `~/.netrc` no longer overrides them.
10
+ - Dependencies
11
+ - Requires mokkari 4.10.
12
+
13
+ ## v5.3.1
14
+
15
+ - Fixes
16
+ - `OnlineSession` accepts `MatchMode.ASK` when a prompt handler or deferred
17
+ prompts can resolve its prompts, so an embedding app can review every
18
+ match.
19
+
3
20
  ## v5.3.0
4
21
 
5
22
  - Breaking Changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comicbox
3
- Version: 5.3.0
3
+ Version: 5.3.2
4
4
  Summary: Comic book archive multi format metadata read/write/transform tool and image extractor.
5
5
  Keywords: cb7,cbr,cbt,cbz,comet,comic,comicbookinfo,comicinfo,metroninfo,pdf
6
6
  Author: AJ Slater
@@ -22,7 +22,7 @@ Requires-Dist: keyring~=25.6
22
22
  Requires-Dist: loguru~=0.7
23
23
  Requires-Dist: marshmallow-union>=0.1.15.post1
24
24
  Requires-Dist: marshmallow~=4.3
25
- Requires-Dist: mokkari~=4.9.0
25
+ Requires-Dist: mokkari~=4.10.0
26
26
  Requires-Dist: nh3>=0.3.5
27
27
  Requires-Dist: packaging>=24.0
28
28
  Requires-Dist: pillow>=12.2.0
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env bash
2
+ # Shared helpers for bin/ scripts. Source it, do not run it.
3
+ # Bash 3.2 safe, as that is macOS's /bin/bash: no mapfile, namerefs or ${x^^}.
4
+
5
+ # Print an error and exit 1.
6
+ die() {
7
+ echo "ERROR: $*" >&2
8
+ exit 1
9
+ }
10
+
11
+ warn() {
12
+ echo "WARNING: $*" >&2
13
+ }
14
+
15
+ is_darwin() {
16
+ [[ $(uname) == Darwin ]]
17
+ }
18
+
19
+ # Succeed when the tool is on PATH. Otherwise say so and how to install it, and
20
+ # fail, so a caller can skip that tool visibly instead of silently. In CI (CI
21
+ # set, as GitHub sets it) a missing tool is an error instead, so a green CI
22
+ # run means every tool ran.
23
+ need() {
24
+ if command -v "$1" >/dev/null 2>&1; then
25
+ return 0
26
+ fi
27
+ if [[ -n ${CI:-} ]]; then
28
+ die "$1 not installed. CI must install it: brew install $1, or add it to the Dockerfile's CI stage"
29
+ fi
30
+ echo "skipped: $1 not installed (brew install $1)" >&2
31
+ return 1
32
+ }
33
+
34
+ # Run a command and read its NUL-delimited output into the global array files.
35
+ # Fails with the command's status, so a broken finder cannot pass for zero
36
+ # files. A temp file stands in for mapfile -d '' and wait on a process
37
+ # substitution, which both need bash 4.4.
38
+ load_files() {
39
+ local out file status=0
40
+ out=$(mktemp)
41
+ "$@" >"$out" || status=$?
42
+ files=()
43
+ if ((status == 0)); then
44
+ while IFS= read -r -d '' file; do
45
+ files+=("$file")
46
+ done <"$out"
47
+ fi
48
+ rm -f "$out"
49
+ return "$status"
50
+ }
@@ -10,28 +10,36 @@
10
10
  # Runs from fork pull requests are ignored: a fork controls its own workflow
11
11
  # and could upload a forged marker for a tree it can predict.
12
12
  #
13
- # Any failure falls through to a full lint, test and build.
13
+ # Any lookup or download failure falls through to a full lint, test and build:
14
+ # each one runs as an `if` condition, where set -e never aborts.
14
15
  #
15
16
  # Environment: GH_REPO, GH_TOKEN, GITHUB_OUTPUT, GITHUB_RUN_ID
16
17
  # Outputs: dist_found=true and source_run_id=<run id> on reuse.
17
18
  set -euo pipefail
18
19
 
19
- TREE=$(git rev-parse 'HEAD^{tree}')
20
- MARKER="ci-passed-$TREE"
21
20
  CONTINUE="Continue with Lint, Test & Build."
22
21
 
22
+ if ! TREE=$(git rev-parse 'HEAD^{tree}'); then
23
+ echo "::warning::Could not read the git tree of HEAD. $CONTINUE"
24
+ exit 0
25
+ fi
26
+ MARKER="ci-passed-$TREE"
27
+
23
28
  if ! ARTIFACTS=$(gh api "repos/$GH_REPO/actions/artifacts?name=$MARKER&per_page=100"); then
24
29
  echo "::warning::Could not list artifacts for tree $TREE. $CONTINUE"
25
30
  exit 0
26
31
  fi
27
32
 
28
- RUN_ID=$(jq -r --argjson run "${GITHUB_RUN_ID:-0}" '
33
+ if ! RUN_ID=$(jq -r --argjson run "${GITHUB_RUN_ID:-0}" '
29
34
  [.artifacts[]
30
35
  | select(.expired | not)
31
36
  | select(.workflow_run.head_repository_id == .workflow_run.repository_id)
32
37
  | select(.workflow_run.id != $run)]
33
38
  | max_by(.created_at)
34
- | .workflow_run.id // empty' <<<"$ARTIFACTS")
39
+ | .workflow_run.id // empty' <<<"$ARTIFACTS"); then
40
+ echo "::warning::Could not read the artifact list for tree $TREE. $CONTINUE"
41
+ exit 0
42
+ fi
35
43
 
36
44
  if [[ -z $RUN_ID ]]; then
37
45
  echo "No earlier run passed on tree $TREE. $CONTINUE"
@@ -14,18 +14,28 @@ set -euo pipefail
14
14
  PACKAGE="${1:-}"
15
15
  MODE="${2:-}"
16
16
 
17
- if [ "$PACKAGE" = "" ]; then
17
+ usage() {
18
18
  echo "Usage: $0 <package> [--do-it]" >&2
19
19
  exit 2
20
+ }
21
+
22
+ if [ "$PACKAGE" = "" ]; then
23
+ usage
20
24
  fi
21
25
 
22
26
  # PEP 440 alpha suffix: 1.2.3a1, 1.2.3.alpha1, etc.
23
27
  PATTERN='.*a\d+$'
24
28
 
25
- if [ "$MODE" = "--do-it" ]; then
29
+ # uv run uses the pypi-cleanup pinned in the dev dependency group.
30
+ case $MODE in
31
+ --do-it)
26
32
  : "${PYPI_USERNAME:?set PYPI_USERNAME}"
27
33
  : "${PYPI_CLEANUP_PASSWORD:?set PYPI_CLEANUP_PASSWORD}"
28
- uvx pypi-cleanup -p "$PACKAGE" -r "$PATTERN" -u "$PYPI_USERNAME" --do-it -y
29
- else
30
- uvx pypi-cleanup -p "$PACKAGE" -r "$PATTERN" --query-only
31
- fi
34
+ uv run pypi-cleanup -p "$PACKAGE" -r "$PATTERN" -u "$PYPI_USERNAME" --do-it -y
35
+ ;;
36
+ '')
37
+ uv run pypi-cleanup -p "$PACKAGE" -r "$PATTERN" --query-only
38
+ ;;
39
+ # Anything else may be a typo of --do-it, which must not pass for a query.
40
+ *) usage ;;
41
+ esac
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ # Run a main method in an arbitrary module
3
+ set -euxo pipefail
4
+ ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
5
+ export PYTHONPATH="$ROOT${PYTHONPATH:+:$PYTHONPATH}"
6
+ # Only an unset DEBUG defaults on; DEBUG= or DEBUG=0 turns it off.
7
+ export DEBUG="${DEBUG-1}"
8
+ case $DEBUG in
9
+ '' | 0 | false | False) ;;
10
+ *) export PYTHONDEVMODE=1 ;;
11
+ esac
12
+ export PYTHONDONTWRITEBYTECODE=1
13
+ uv run python3 "$@"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Run one docker compose service and exit with its exit code, e.g. for CI
3
+ # Usage: bin/docker-compose-exit.sh <service>
4
+ set -euo pipefail
5
+ SERVICE=${1:?usage: bin/docker-compose-exit.sh <service>}
6
+ # docker compose without the dash doesn't have the exit-code-from param
7
+ docker compose up --exit-code-from "$SERVICE" "$SERVICE"
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env bash
2
- # Tag old version as latest
2
+ # Point an image's latest tag at an existing version, on the registry, without pulling
3
+ # Usage: DOCKER_USER=... DOCKER_PASS=... bin/docker-tag-latest.sh <registry> <image_name> <version_tag>
3
4
  set -euo pipefail
4
5
 
5
6
  if [[ $# -lt 3 ]]; then
6
- echo "Usage: $0 <registry> <image_name> <version_tag>"
7
- echo "Example: $0 ghcr.io ajslater/codex 1.10.3"
7
+ echo "Usage: $0 <registry> <image_name> <version_tag>" >&2
8
+ echo "Example: $0 ghcr.io ajslater/codex 1.10.3" >&2
8
9
  exit 1
9
10
  fi
10
11
 
@@ -15,8 +16,8 @@ SOURCE_TAG=$3
15
16
  TARGET_TAG="latest"
16
17
 
17
18
  # Ensure DOCKER_PASS and DOCKER_USER are set in your environment
18
- if [[ -z $DOCKER_PASS || -z $DOCKER_USER ]]; then
19
- echo "Error: DOCKER_PASS and DOCKER_USER environment variables must be set."
19
+ if [[ -z ${DOCKER_PASS:-} || -z ${DOCKER_USER:-} ]]; then
20
+ echo "Error: DOCKER_PASS and DOCKER_USER environment variables must be set." >&2
20
21
  exit 1
21
22
  fi
22
23
 
@@ -27,14 +28,11 @@ echo "$DOCKER_PASS" | docker login "$REGISTRY" -u "$DOCKER_USER" --password-stdi
27
28
  # 2. Retag the multi-arch image
28
29
  # This creates a new manifest on the registry side without downloading image layers
29
30
  echo "Tagging $IMAGE_NAME:$SOURCE_TAG as $TARGET_TAG..."
30
- docker buildx imagetools create \
31
+ if docker buildx imagetools create \
31
32
  --tag "$REGISTRY/$IMAGE_NAME:$TARGET_TAG" \
32
- "$REGISTRY/$IMAGE_NAME:$SOURCE_TAG"
33
-
34
- # shellcheck disable=SC2181
35
- if [ $? -eq 0 ]; then
33
+ "$REGISTRY/$IMAGE_NAME:$SOURCE_TAG"; then
36
34
  echo "Successfully updated $TARGET_TAG"
37
35
  else
38
- echo "Failed to update tag."
36
+ echo "Failed to update tag." >&2
39
37
  exit 1
40
38
  fi
@@ -1,11 +1,16 @@
1
1
  #!/usr/bin/env bash
2
- # List shell scripts to fix and lint, honoring .shellignore, NUL-delimited
2
+ # List files to fix and lint, minus an ignore file's patterns, NUL-delimited
3
3
  #
4
- # Prints every regular *.sh file under the current directory as `find` prints
5
- # it (./path/to/file.sh), sorted bytewise, each followed by a NUL. Skips what
6
- # the optional ./.shellignore excludes. A missing file excludes nothing.
4
+ # Usage: bin/find-files.sh [-i IGNOREFILE] [-- PREDICATE...]
5
+ # e.g. bin/find-files.sh -- -name '*Dockerfile'
7
6
  #
8
- # .shellignore holds one pattern per line:
7
+ # Prints every regular file under the current directory that the find
8
+ # PREDICATEs match (every file without any) as `find` prints it
9
+ # (./path/to/file), sorted bytewise, each followed by a NUL. Skips what
10
+ # IGNOREFILE excludes, ./.shellignore by default. A missing default file
11
+ # excludes nothing; a missing -i file is an error.
12
+ #
13
+ # The ignore file holds one pattern per line:
9
14
  # - Blank lines and lines starting with # are ignored.
10
15
  # - A leading ! re-includes what an earlier pattern excluded.
11
16
  # - A leading ./ or / and a trailing / are stripped.
@@ -20,10 +25,29 @@
20
25
  # and everything in it.
21
26
  #
22
27
  # Portable to BSD and GNU find: only -mindepth -name -path -prune -type
23
- # -print0 -o ! and parentheses.
28
+ # -print0 -o ! and parentheses, plus whatever PREDICATEs the caller passes.
24
29
  set -euo pipefail
25
30
 
31
+ usage() {
32
+ echo "usage: $0 [-i IGNOREFILE] [-- PREDICATE...]" >&2
33
+ exit 2
34
+ }
35
+
26
36
  ignore_file=.shellignore
37
+ while getopts i: opt; do
38
+ case $opt in
39
+ i)
40
+ ignore_file=$OPTARG
41
+ if [[ ! -f $ignore_file ]]; then
42
+ echo "$0: no ignore file $ignore_file" >&2
43
+ exit 2
44
+ fi
45
+ ;;
46
+ *) usage ;;
47
+ esac
48
+ done
49
+ shift $((OPTIND - 1))
50
+
27
51
  ignore_tests=()
28
52
  keep_tests=()
29
53
 
@@ -74,6 +98,10 @@ if ((${#ignore_tests[@]})); then
74
98
  fi
75
99
  find_args+=(\( "${prune[@]}" \) -prune -o)
76
100
  fi
77
- find_args+=(-type f -name '*.sh' -print0)
101
+ find_args+=(-type f)
102
+ if (($#)); then
103
+ find_args+=(\( "$@" \))
104
+ fi
105
+ find_args+=(-print0)
78
106
 
79
107
  find "${find_args[@]}" | LC_ALL=C sort -z
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ # List shell scripts to fix and lint, honoring .shellignore, NUL-delimited
3
+ #
4
+ # Prints every regular *.sh file, and every extensionless file whose first
5
+ # line is a sh or bash shebang (such as bin/pm), under the current directory
6
+ # as find prints it (./path/to/file.sh), sorted bytewise, each followed by a
7
+ # NUL. Skips what the optional ./.shellignore excludes; find-files.sh
8
+ # describes its syntax.
9
+ set -euo pipefail
10
+
11
+ shebang='^#![[:space:]]*([^[:space:]]*/)?(env[[:space:]]+)?(ba)?sh([[:space:]]|$)'
12
+
13
+ "$(dirname "${BASH_SOURCE[0]}")/find-files.sh" -- -name '*.sh' -o ! -name '*.*' |
14
+ while IFS= read -r -d '' file; do
15
+ if [[ $file != *.sh ]]; then
16
+ line=''
17
+ IFS= read -r line <"$file" || true
18
+ [[ $line =~ $shebang ]] || continue
19
+ fi
20
+ printf '%s\0' "$file"
21
+ done
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+ # Fix Dockerfile formatting
3
+ set -euxo pipefail
4
+
5
+ bin=$(dirname "${BASH_SOURCE[0]}")
6
+ # shellcheck source=bin/_lib.sh
7
+ . "$bin/_lib.sh"
8
+
9
+ load_files "$bin/find-files.sh" -- -name '*Dockerfile'
10
+ if ((${#files[@]})) && need dockerfmt; then
11
+ dockerfmt --write "${files[@]}"
12
+ fi
@@ -5,7 +5,7 @@ set -euxo pipefail
5
5
  #####################
6
6
  ###### Makefile #####
7
7
  #####################
8
- uv run mbake format Makefile cfg/*.mk
8
+ uvx mbake@latest format Makefile cfg/*.mk
9
9
 
10
10
  ################
11
11
  # Ignore files #
@@ -15,9 +15,10 @@ bin/sort-ignore.sh
15
15
  ############################################
16
16
  ##### Javascript, JSON, Markdown, YAML #####
17
17
  ############################################
18
- bun run fix
18
+ # node_root merges a fix script; a project without node_root may have none.
19
+ bun run --if-present fix
19
20
 
20
21
  ###################
21
22
  ###### Shell ######
22
23
  ###################
23
- bin/fix-sh.sh
24
+ bin/sh-tools.sh --fix
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env python3
2
+ # Delete stale Docker Hub manifests: uv run bin/hub_prune_stale.py NAMESPACE/REPO [--execute]
3
+ # /// script
4
+ # requires-python = ">=3.10"
5
+ # dependencies = ["requests"]
6
+ # ///
2
7
  """
3
8
  Delete stale images and image indexes from a Docker Hub repository.
4
9
 
@@ -507,7 +512,7 @@ def main() -> None:
507
512
  args = build_parser().parse_args()
508
513
  try:
509
514
  sys.exit(prune(args.repository, args.min_age, execute=args.execute))
510
- except PruneError as exc:
515
+ except (PruneError, requests.RequestException) as exc:
511
516
  print(f"error: {exc}", file=sys.stderr)
512
517
  sys.exit(1)
513
518
  except KeyboardInterrupt:
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+ # eslint_d can get into a bad state if git switches branches underneath it
3
+ set -euo pipefail
4
+ # The project's own eslint_d only: bunx would download one just to stop it.
5
+ # A daemon in a bad state may not stop cleanly; pkill gets it then.
6
+ if [[ -x node_modules/.bin/eslint_d ]]; then
7
+ node_modules/.bin/eslint_d stop || true
8
+ fi
9
+ # Any daemon left, by the title eslint_d gives itself or by its script's path.
10
+ # A bare -f eslint_d would also match this script and make kill-eslint_d.
11
+ pkill -f '^eslint_d - |node_modules/eslint_d/' || true
12
+ rm -f .eslintcache
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # Lint checks for ci
3
+ set -euxo pipefail
4
+
5
+ # shellcheck source=bin/_lib.sh
6
+ . "$(dirname "${BASH_SOURCE[0]}")/_lib.sh"
7
+
8
+ # Every workflow, so ci.yml's calls into the devenv-* workflows are checked.
9
+ # The files are named: bare actionlint finds them by a .git entry, and the CI
10
+ # image has none (.dockerignore). Given .git, named files are checked the same
11
+ # way, calls into local reusable workflows included; without it that one check
12
+ # is skipped.
13
+ shopt -s nullglob
14
+ files=(.github/workflows/*.yml .github/workflows/*.yaml)
15
+ if ((${#files[@]})) && need actionlint; then
16
+ actionlint "${files[@]}"
17
+ fi
@@ -1,10 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # Lint complexity
3
3
  set -euo pipefail
4
- if [ "$(uname)" != "Darwin" ]; then
5
- exit 0
6
- fi
7
-
8
4
  uv run --group lint complexipy
9
5
  uv run --group lint radon mi --min B .
10
6
  uv run --group lint radon cc --min C .
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ # Lint checks for docker
3
+ set -euxo pipefail
4
+
5
+ bin=$(dirname "${BASH_SOURCE[0]}")
6
+ # shellcheck source=bin/_lib.sh
7
+ . "$bin/_lib.sh"
8
+
9
+ load_files "$bin/find-files.sh" -- -name '*Dockerfile'
10
+ if ((${#files[@]} == 0)); then
11
+ exit 0
12
+ fi
13
+ if need hadolint; then
14
+ hadolint "${files[@]}"
15
+ fi
16
+ if need dockerfmt; then
17
+ dockerfmt --check "${files[@]}"
18
+ fi
@@ -7,7 +7,7 @@ set -euxo pipefail
7
7
  ####################
8
8
  uv run --group lint ruff check .
9
9
  uv run --group lint ruff format --check .
10
- make typecheck
10
+ uv run --group lint --group test --group build basedpyright .
11
11
  bin/lint-vulture.sh
12
12
  bin/lint-complexity.sh
13
13
  uv run --group lint codespell .
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ # Lint checks
3
+ set -euxo pipefail
4
+
5
+ uvx mbake@latest validate Makefile cfg/*.mk
6
+
7
+ # Javascript, JSON, Markdown, YAML #####
8
+ # node_root merges a lint script; a project without node_root may have none.
9
+ bun run --if-present lint
10
+
11
+ bin/sh-tools.sh --lint
12
+
13
+ # Not .prettierignore: it lists *.sh, which would hide every script from roman.
14
+ uv run bin/roman.py -i .shellignore .
@@ -46,7 +46,9 @@ class ReleaseInfoError(Exception):
46
46
  """The release content is missing, ambiguous or inconsistent."""
47
47
 
48
48
 
49
- @dataclass(frozen=True, slots=True)
49
+ # No slots=True: that needs Python 3.10, and this runs on any python3, down to
50
+ # macOS's /usr/bin/python3 3.9.
51
+ @dataclass(frozen=True)
50
52
  class ReleaseInfo:
51
53
  """What a release is called and what its notes say."""
52
54
 
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env python3
2
+ # uv run reads this block, so pathspec arrives without the lint group.
3
+ # /// script
4
+ # requires-python = ">=3.10"
5
+ # dependencies = ["pathspec~=1.1"]
6
+ # ///
2
7
  """
3
8
  Check shell scripts recursively for a descriptive comment on line 2.
4
9
 
@@ -24,7 +29,11 @@ if TYPE_CHECKING:
24
29
  # Constants
25
30
  # ---------------------------------------------------------------------------
26
31
 
27
- SHELL_SHEBANG_PATTERN: re.Pattern[str] = re.compile(r"^#!.*sh")
32
+ # The interpreter, or the command after env and its options, is a shell like
33
+ # sh, bash or zsh. Matching "sh" anywhere would catch paths like .local/share.
34
+ SHELL_SHEBANG_PATTERN: re.Pattern[str] = re.compile(
35
+ r"^#!\s*(?:\S*/)?(?:env\s+(?:-\S+\s+)*(?:\S*/)?)?[a-z]*sh(?:\s|$)"
36
+ )
28
37
 
29
38
  # Patterns that are always excluded regardless of an ignore file.
30
39
  DEFAULT_EXCLUDE_PATTERNS: list[str] = [
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # Fix or lint the shell scripts find-sh.sh lists: bin/sh-tools.sh --fix|--lint
3
+ # Both modes live here so the shellharden and shfmt flags cannot drift apart.
4
+ # A tool that is not installed is skipped with a message on stderr.
5
+ set -euxo pipefail
6
+
7
+ bin=$(dirname "${BASH_SOURCE[0]}")
8
+ # shellcheck source=bin/_lib.sh
9
+ . "$bin/_lib.sh"
10
+
11
+ case ${1:-} in
12
+ --fix)
13
+ harden=--replace
14
+ format=--write
15
+ ;;
16
+ --lint)
17
+ harden=--check
18
+ format=--diff
19
+ ;;
20
+ *)
21
+ echo "usage: $0 --fix|--lint" >&2
22
+ exit 2
23
+ ;;
24
+ esac
25
+
26
+ load_files "$bin/find-sh.sh"
27
+ if ((${#files[@]} == 0)); then
28
+ exit 0
29
+ fi
30
+
31
+ if [[ $1 == --lint ]] && need shellcheck; then
32
+ shellcheck "${files[@]}"
33
+ fi
34
+ if need shellharden; then
35
+ shellharden "$harden" "${files[@]}"
36
+ fi
37
+ if need shfmt; then
38
+ shfmt --simplify --indent 2 "$format" "${files[@]}"
39
+ fi
@@ -4,8 +4,9 @@
4
4
  # prettier let the last matching line win, so a negation only works after the
5
5
  # patterns it overrides.
6
6
  set -euo pipefail
7
- # Set locale to make output deterministic across shells
8
- export LC_ALL=en_US.UTF-8
7
+ # Bytewise order: every machine has the C locale, and it is the codepoint
8
+ # order merge_dotfiles.py sorts in, so the two never reorder each other.
9
+ export LC_ALL=C
9
10
  sorted=$(mktemp)
10
11
  trap 'rm -f "$sorted"' EXIT
11
12
  for f in .*ignore; do
@@ -2,6 +2,9 @@
2
2
  # Run all tests
3
3
  set -euxo pipefail
4
4
  mkdir -p test-results
5
- LOGLEVEL=DEBUG uv run --group test pytest "$@"
6
- # pytest-cov leaves .coverage.$HOST.$PID.$RAND files around while coverage itself doesn't
5
+ status=0
6
+ LOGLEVEL=DEBUG uv run --group test pytest "$@" || status=$?
7
+ # pytest-cov leaves .coverage.$HOST.$PID.$RAND files around while coverage
8
+ # itself doesn't, so erase them whether or not the tests passed.
7
9
  uv run --group test coverage erase || true
10
+ exit "$status"
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # Create UML diagrams of the project's package in test-results/uml
3
+ set -euo pipefail
4
+ NAME=$(uv run toml get --toml-path=pyproject.toml project.name)
5
+ # pyreverse wants the import name, which has _ where the project name has -.
6
+ PACKAGE=${NAME//-/_}
7
+ OUTPUT_DIR=test-results/uml
8
+ mkdir -p "$OUTPUT_DIR"
9
+ uvx --from pylint pyreverse --output png --output-directory "$OUTPUT_DIR" "$PACKAGE"
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # Get or set the node version: frontend/package.json if there is one, else ./package.json
3
+ set -euo pipefail
4
+ VERSION="${1:-}"
5
+ if [[ -d frontend ]]; then
6
+ cd frontend
7
+ fi
8
+ if [[ ! -f package.json ]]; then
9
+ echo "ERROR: no package.json in $PWD" >&2
10
+ exit 1
11
+ fi
12
+ if [[ $VERSION == "" ]]; then
13
+ bun pm pkg get name version
14
+ else
15
+ # pkg set, unlike bun pm version, never commits or tags.
16
+ bun pm pkg set "version=$VERSION"
17
+ fi