omdev 0.0.0.dev288__tar.gz → 0.0.0.dev290__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 (278) hide show
  1. {omdev-0.0.0.dev288/omdev.egg-info → omdev-0.0.0.dev290}/PKG-INFO +2 -2
  2. omdev-0.0.0.dev288/omdev/ci/github/client.py → omdev-0.0.0.dev290/omdev/ci/github/api/clients.py +172 -209
  3. {omdev-0.0.0.dev288/omdev/ci/github → omdev-0.0.0.dev290/omdev/ci/github/api/v1}/api.py +5 -87
  4. omdev-0.0.0.dev290/omdev/ci/github/api/v1/client.py +171 -0
  5. omdev-0.0.0.dev290/omdev/ci/github/api/v2/api.py +148 -0
  6. omdev-0.0.0.dev290/omdev/ci/github/api/v2/client.py +166 -0
  7. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/github/cache.py +14 -3
  8. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/github/cli.py +1 -1
  9. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/scripts/importtrace.py +3 -3
  10. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/scripts/ci.py +663 -288
  11. omdev-0.0.0.dev290/omdev/tools/git/__init__.py +0 -0
  12. omdev-0.0.0.dev290/omdev/tools/json/__init__.py +0 -0
  13. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/cli.py +2 -2
  14. omdev-0.0.0.dev290/omdev/tools/pawk/__init__.py +0 -0
  15. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290/omdev.egg-info}/PKG-INFO +2 -2
  16. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev.egg-info/SOURCES.txt +8 -2
  17. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev.egg-info/requires.txt +1 -1
  18. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/pyproject.toml +2 -2
  19. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/LICENSE +0 -0
  20. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/MANIFEST.in +0 -0
  21. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/README.rst +0 -0
  22. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/.manifests.json +0 -0
  23. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/__about__.py +0 -0
  24. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/__init__.py +0 -0
  25. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/__init__.py +0 -0
  26. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/__main__.py +0 -0
  27. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/gen.py +0 -0
  28. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/imports.py +0 -0
  29. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/main.py +0 -0
  30. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/manifests.py +0 -0
  31. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/resources.py +0 -0
  32. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/srcfiles.py +0 -0
  33. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/strip.py +0 -0
  34. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/types.py +0 -0
  35. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/amalg/typing.py +0 -0
  36. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/antlr/__init__.py +0 -0
  37. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/antlr/consts.py +0 -0
  38. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/antlr/gen.py +0 -0
  39. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/__init__.py +0 -0
  40. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/__init__.py +0 -0
  41. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/cache.py +0 -0
  42. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/contexts.py +0 -0
  43. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/currents.py +0 -0
  44. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/fns.py +0 -0
  45. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/resolvers.py +0 -0
  46. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/storage.py +0 -0
  47. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/compute/types.py +0 -0
  48. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/__init__.py +0 -0
  49. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/actions.py +0 -0
  50. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/cache.py +0 -0
  51. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/consts.py +0 -0
  52. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/defaults.py +0 -0
  53. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/manifests.py +0 -0
  54. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cache/data/specs.py +0 -0
  55. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cc/__init__.py +0 -0
  56. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cc/__main__.py +0 -0
  57. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cc/cdeps.py +0 -0
  58. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cc/cdeps.toml +0 -0
  59. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cc/cli.py +0 -0
  60. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/__init__.py +0 -0
  61. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_boilerplate.cc +0 -0
  62. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/LICENSE +0 -0
  63. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/__init__.py +0 -0
  64. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/build_ext.py +0 -0
  65. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
  66. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
  67. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/compilers/options.py +0 -0
  68. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
  69. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/dir_util.py +0 -0
  70. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/errors.py +0 -0
  71. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/extension.py +0 -0
  72. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/file_util.py +0 -0
  73. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/modified.py +0 -0
  74. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/spawn.py +0 -0
  75. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/sysconfig.py +0 -0
  76. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/util.py +0 -0
  77. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/_distutils/version.py +0 -0
  78. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/build.py +0 -0
  79. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/cmake.py +0 -0
  80. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/importhook.py +0 -0
  81. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/magic.py +0 -0
  82. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cexts/scan.py +0 -0
  83. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/__init__.py +0 -0
  84. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/__main__.py +0 -0
  85. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/cache.py +0 -0
  86. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/ci.py +0 -0
  87. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/cli.py +0 -0
  88. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/compose.py +0 -0
  89. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/consts.py +0 -0
  90. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/__init__.py +0 -0
  91. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/buildcaching.py +0 -0
  92. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/cache.py +0 -0
  93. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/cacheserved/__init__.py +0 -0
  94. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/cacheserved/cache.py +0 -0
  95. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/cacheserved/manifests.py +0 -0
  96. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/cmds.py +0 -0
  97. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/dataserver.py +0 -0
  98. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/imagepulling.py +0 -0
  99. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/inject.py +0 -0
  100. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/packing.py +0 -0
  101. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/repositories.py +0 -0
  102. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/docker/utils.py +0 -0
  103. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/github/__init__.py +0 -0
  104. {omdev-0.0.0.dev288/omdev/clipboard → omdev-0.0.0.dev290/omdev/ci/github/api}/__init__.py +0 -0
  105. {omdev-0.0.0.dev288/omdev/git → omdev-0.0.0.dev290/omdev/ci/github/api/v1}/__init__.py +0 -0
  106. {omdev-0.0.0.dev288/omdev/home → omdev-0.0.0.dev290/omdev/ci/github/api/v2}/__init__.py +0 -0
  107. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/github/bootstrap.py +0 -0
  108. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/github/env.py +0 -0
  109. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/github/inject.py +0 -0
  110. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/inject.py +0 -0
  111. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/requirements.py +0 -0
  112. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/shell.py +0 -0
  113. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ci/utils.py +0 -0
  114. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/__init__.py +0 -0
  115. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/__main__.py +0 -0
  116. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/_pathhack.py +0 -0
  117. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/clicli.py +0 -0
  118. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/install.py +0 -0
  119. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/main.py +0 -0
  120. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/managers.py +0 -0
  121. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cli/types.py +0 -0
  122. {omdev-0.0.0.dev288/omdev/interp/providers → omdev-0.0.0.dev290/omdev/clipboard}/__init__.py +0 -0
  123. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/clipboard/clipboard.py +0 -0
  124. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/clipboard/darwin_cf.py +0 -0
  125. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/clipboard/linux_x11.py +0 -0
  126. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/cmake.py +0 -0
  127. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/dataserver/__init__.py +0 -0
  128. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/dataserver/handlers.py +0 -0
  129. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/dataserver/http.py +0 -0
  130. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/dataserver/routes.py +0 -0
  131. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/dataserver/server.py +0 -0
  132. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/dataserver/targets.py +0 -0
  133. {omdev-0.0.0.dev288/omdev/interp/pyenv → omdev-0.0.0.dev290/omdev/git}/__init__.py +0 -0
  134. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/git/magic.py +0 -0
  135. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/git/revisions.py +0 -0
  136. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/git/shallow.py +0 -0
  137. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/git/status.py +0 -0
  138. {omdev-0.0.0.dev288/omdev/interp/uv → omdev-0.0.0.dev290/omdev/home}/__init__.py +0 -0
  139. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/home/paths.py +0 -0
  140. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/home/secrets.py +0 -0
  141. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/home/shadow.py +0 -0
  142. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/imgur.py +0 -0
  143. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/__init__.py +0 -0
  144. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/__main__.py +0 -0
  145. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/cli.py +0 -0
  146. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/default.py +0 -0
  147. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/inject.py +0 -0
  148. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/inspect.py +0 -0
  149. {omdev-0.0.0.dev288/omdev/mypy → omdev-0.0.0.dev290/omdev/interp/providers}/__init__.py +0 -0
  150. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/providers/base.py +0 -0
  151. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/providers/inject.py +0 -0
  152. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/providers/running.py +0 -0
  153. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/providers/standalone.py +0 -0
  154. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/providers/system.py +0 -0
  155. {omdev-0.0.0.dev288/omdev/oci → omdev-0.0.0.dev290/omdev/interp/pyenv}/__init__.py +0 -0
  156. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/pyenv/inject.py +0 -0
  157. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/pyenv/install.py +0 -0
  158. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/pyenv/provider.py +0 -0
  159. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/pyenv/pyenv.py +0 -0
  160. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/resolvers.py +0 -0
  161. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/types.py +0 -0
  162. {omdev-0.0.0.dev288/omdev/oci/pack → omdev-0.0.0.dev290/omdev/interp/uv}/__init__.py +0 -0
  163. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/uv/inject.py +0 -0
  164. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/uv/provider.py +0 -0
  165. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/uv/uv.py +0 -0
  166. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/interp/venvs.py +0 -0
  167. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/__init__.py +0 -0
  168. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/__main__.py +0 -0
  169. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/cli.py +0 -0
  170. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/find.py +0 -0
  171. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/magic.py +0 -0
  172. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/prepare.py +0 -0
  173. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/magic/styles.py +0 -0
  174. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/manifests/__init__.py +0 -0
  175. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/manifests/__main__.py +0 -0
  176. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/manifests/build.py +0 -0
  177. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/manifests/dumping.py +0 -0
  178. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/manifests/main.py +0 -0
  179. {omdev-0.0.0.dev288/omdev/packaging → omdev-0.0.0.dev290/omdev/mypy}/__init__.py +0 -0
  180. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/mypy/debug.py +0 -0
  181. {omdev-0.0.0.dev288/omdev/precheck → omdev-0.0.0.dev290/omdev/oci}/__init__.py +0 -0
  182. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/building.py +0 -0
  183. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/compression.py +0 -0
  184. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/data.py +0 -0
  185. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/datarefs.py +0 -0
  186. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/dataserver.py +0 -0
  187. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/loading.py +0 -0
  188. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/media.py +0 -0
  189. {omdev-0.0.0.dev288/omdev/ptk/apps → omdev-0.0.0.dev290/omdev/oci/pack}/__init__.py +0 -0
  190. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/pack/packing.py +0 -0
  191. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/pack/repositories.py +0 -0
  192. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/pack/unpacking.py +0 -0
  193. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/repositories.py +0 -0
  194. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/oci/tars.py +0 -0
  195. {omdev-0.0.0.dev288/omdev/py/scripts → omdev-0.0.0.dev290/omdev/packaging}/__init__.py +0 -0
  196. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/marshal.py +0 -0
  197. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/names.py +0 -0
  198. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/requires.py +0 -0
  199. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/revisions.py +0 -0
  200. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/specifiers.py +0 -0
  201. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/versions.py +0 -0
  202. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/packaging/wheelfile.py +0 -0
  203. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pip.py +0 -0
  204. {omdev-0.0.0.dev288/omdev/py/tools → omdev-0.0.0.dev290/omdev/precheck}/__init__.py +0 -0
  205. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/__main__.py +0 -0
  206. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/base.py +0 -0
  207. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/git.py +0 -0
  208. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/lite.py +0 -0
  209. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/main.py +0 -0
  210. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/manifests.py +0 -0
  211. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/precheck/scripts.py +0 -0
  212. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ptk/__init__.py +0 -0
  213. {omdev-0.0.0.dev288/omdev/pyproject/resources → omdev-0.0.0.dev290/omdev/ptk/apps}/__init__.py +0 -0
  214. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/ptk/apps/ncdu.py +0 -0
  215. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/__init__.py +0 -0
  216. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/attrdocs.py +0 -0
  217. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/bracepy.py +0 -0
  218. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/classdot.py +0 -0
  219. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/findimports.py +0 -0
  220. {omdev-0.0.0.dev288/omdev/tokens → omdev-0.0.0.dev290/omdev/py/scripts}/__init__.py +0 -0
  221. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/scripts/bumpversion.py +0 -0
  222. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/scripts/execstat.py +0 -0
  223. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/srcheaders.py +0 -0
  224. {omdev-0.0.0.dev288/omdev/tools/git → omdev-0.0.0.dev290/omdev/py/tools}/__init__.py +0 -0
  225. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/tools/importscan.py +0 -0
  226. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/py/tools/mkrelimp.py +0 -0
  227. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/__init__.py +0 -0
  228. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/__main__.py +0 -0
  229. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/cexts.py +0 -0
  230. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/cli.py +0 -0
  231. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/configs.py +0 -0
  232. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/inject.py +0 -0
  233. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/pkg.py +0 -0
  234. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/reqs.py +0 -0
  235. {omdev-0.0.0.dev288/omdev/tools/json → omdev-0.0.0.dev290/omdev/pyproject/resources}/__init__.py +0 -0
  236. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/resources/docker-dev.sh +0 -0
  237. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/resources/python.sh +0 -0
  238. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/pyproject/venvs.py +0 -0
  239. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/scripts/__init__.py +0 -0
  240. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/scripts/interp.py +0 -0
  241. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/scripts/pyproject.py +0 -0
  242. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/scripts/slowcat.py +0 -0
  243. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/scripts/tmpexec.py +0 -0
  244. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tagstrings.py +0 -0
  245. {omdev-0.0.0.dev288/omdev/tools/pawk → omdev-0.0.0.dev290/omdev/tokens}/__init__.py +0 -0
  246. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tokens/all.py +0 -0
  247. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tokens/tokenizert.py +0 -0
  248. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tokens/utils.py +0 -0
  249. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/__init__.py +0 -0
  250. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/cloc.py +0 -0
  251. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/diff.py +0 -0
  252. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/doc.py +0 -0
  253. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/docker.py +0 -0
  254. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/git/__main__.py +0 -0
  255. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/git/cli.py +0 -0
  256. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/git/consts.py +0 -0
  257. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/git/messages.py +0 -0
  258. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/intellij.py +0 -0
  259. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/__main__.py +0 -0
  260. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/formats.py +0 -0
  261. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/io.py +0 -0
  262. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/parsing.py +0 -0
  263. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/processing.py +0 -0
  264. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/json/rendering.py +0 -0
  265. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/linehisto.py +0 -0
  266. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/mkenv.py +0 -0
  267. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/notebook.py +0 -0
  268. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/pawk/__main__.py +0 -0
  269. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/pawk/pawk.py +0 -0
  270. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/pip.py +0 -0
  271. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/prof.py +0 -0
  272. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/qr.py +0 -0
  273. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/shadow.py +0 -0
  274. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev/tools/sqlrepl.py +0 -0
  275. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev.egg-info/dependency_links.txt +0 -0
  276. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev.egg-info/entry_points.txt +0 -0
  277. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/omdev.egg-info/top_level.txt +0 -0
  278. {omdev-0.0.0.dev288 → omdev-0.0.0.dev290}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omdev
3
- Version: 0.0.0.dev288
3
+ Version: 0.0.0.dev290
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Operating System :: POSIX
13
13
  Requires-Python: >=3.12
14
14
  License-File: LICENSE
15
- Requires-Dist: omlish==0.0.0.dev288
15
+ Requires-Dist: omlish==0.0.0.dev290
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=25.1; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -1,8 +1,9 @@
1
- # ruff: noqa: TC003 UP006 UP007
1
+ # ruff: noqa: UP006 UP007
2
2
  import abc
3
3
  import asyncio
4
4
  import dataclasses as dc
5
5
  import http.client
6
+ import itertools
6
7
  import json
7
8
  import os
8
9
  import typing as ta
@@ -10,20 +11,21 @@ import urllib.parse
10
11
  import urllib.request
11
12
 
12
13
  from omlish.asyncs.asyncio.utils import asyncio_wait_concurrent
14
+ from omlish.http.urllib import NonRaisingUrllibErrorProcessor
13
15
  from omlish.lite.check import check
14
16
  from omlish.lite.json import json_dumps_compact
15
17
  from omlish.lite.logs import log
16
18
  from omlish.lite.timing import log_timing_context
17
19
 
18
- from ..consts import CI_CACHE_VERSION
19
- from .api import GithubCacheServiceV1
20
- from .env import register_github_env_var
20
+ from ...consts import CI_CACHE_VERSION
21
+ from ..env import register_github_env_var
21
22
 
22
23
 
23
24
  ##
24
25
 
25
26
 
26
27
  class GithubCacheClient(abc.ABC):
28
+ @dc.dataclass(frozen=True)
27
29
  class Entry(abc.ABC): # noqa
28
30
  pass
29
31
 
@@ -46,18 +48,21 @@ class GithubCacheClient(abc.ABC):
46
48
  ##
47
49
 
48
50
 
49
- class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
50
- BASE_URL_ENV_VAR = register_github_env_var('ACTIONS_CACHE_URL')
51
+ class BaseGithubCacheClient(GithubCacheClient, abc.ABC):
51
52
  AUTH_TOKEN_ENV_VAR = register_github_env_var('ACTIONS_RUNTIME_TOKEN') # noqa
52
53
 
53
54
  KEY_SUFFIX_ENV_VAR = register_github_env_var('GITHUB_RUN_ID')
54
55
 
56
+ DEFAULT_CONCURRENCY = 4
57
+ DEFAULT_CHUNK_SIZE = 64 * 1024 * 1024
58
+
55
59
  #
56
60
 
57
61
  def __init__(
58
62
  self,
59
63
  *,
60
- base_url: ta.Optional[str] = None,
64
+ service_url: str,
65
+
61
66
  auth_token: ta.Optional[str] = None,
62
67
 
63
68
  key_prefix: ta.Optional[str] = None,
@@ -66,14 +71,15 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
66
71
  cache_version: int = CI_CACHE_VERSION,
67
72
 
68
73
  loop: ta.Optional[asyncio.AbstractEventLoop] = None,
74
+
75
+ concurrency: int = DEFAULT_CONCURRENCY,
76
+ chunk_size: int = DEFAULT_CHUNK_SIZE,
69
77
  ) -> None:
70
78
  super().__init__()
71
79
 
72
80
  #
73
81
 
74
- if base_url is None:
75
- base_url = check.non_empty_str(self.BASE_URL_ENV_VAR())
76
- self._service_url = GithubCacheServiceV1.get_service_url(base_url)
82
+ self._service_url = check.non_empty_str(service_url)
77
83
 
78
84
  if auth_token is None:
79
85
  auth_token = self.AUTH_TOKEN_ENV_VAR()
@@ -95,7 +101,16 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
95
101
 
96
102
  self._given_loop = loop
97
103
 
98
- #
104
+ #
105
+
106
+ check.arg(concurrency > 0)
107
+ self._concurrency = concurrency
108
+
109
+ check.arg(chunk_size > 0)
110
+ self._chunk_size = chunk_size
111
+
112
+ ##
113
+ # misc
99
114
 
100
115
  def _get_loop(self) -> asyncio.AbstractEventLoop:
101
116
  if (loop := self._given_loop) is not None:
@@ -104,21 +119,25 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
104
119
 
105
120
  #
106
121
 
107
- def build_request_headers(
122
+ def _load_json_bytes(self, b: ta.Optional[bytes]) -> ta.Optional[ta.Any]:
123
+ if not b:
124
+ return None
125
+ return json.loads(b.decode('utf-8-sig'))
126
+
127
+ ##
128
+ # requests
129
+
130
+ def _build_request_headers(
108
131
  self,
109
132
  headers: ta.Optional[ta.Mapping[str, str]] = None,
110
133
  *,
134
+ no_auth: bool = False,
111
135
  content_type: ta.Optional[str] = None,
112
136
  json_content: bool = False,
113
137
  ) -> ta.Dict[str, str]:
114
- dct = {
115
- 'Accept': ';'.join([
116
- 'application/json',
117
- f'api-version={GithubCacheServiceV1.API_VERSION}',
118
- ]),
119
- }
120
-
121
- if (auth_token := self._auth_token):
138
+ dct = {}
139
+
140
+ if not no_auth and (auth_token := self._auth_token):
122
141
  dct['Authorization'] = f'Bearer {auth_token}'
123
142
 
124
143
  if content_type is None and json_content:
@@ -133,19 +152,13 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
133
152
 
134
153
  #
135
154
 
136
- def load_json_bytes(self, b: ta.Optional[bytes]) -> ta.Optional[ta.Any]:
137
- if not b:
138
- return None
139
- return json.loads(b.decode('utf-8-sig'))
140
-
141
- #
142
-
143
- async def send_url_request(
155
+ async def _send_urllib_request(
144
156
  self,
145
157
  req: urllib.request.Request,
146
158
  ) -> ta.Tuple[http.client.HTTPResponse, ta.Optional[bytes]]:
147
159
  def run_sync():
148
- with urllib.request.urlopen(req) as resp: # noqa
160
+ opener = urllib.request.build_opener(NonRaisingUrllibErrorProcessor)
161
+ with opener.open(req) as resp: # noqa
149
162
  body = resp.read()
150
163
  return (resp, body)
151
164
 
@@ -161,18 +174,32 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
161
174
  def __str__(self) -> str:
162
175
  return repr(self)
163
176
 
164
- async def send_service_request(
177
+ async def _send_request(
165
178
  self,
166
- path: str,
167
179
  *,
180
+ url: ta.Optional[str] = None,
181
+ path: ta.Optional[str] = None,
182
+
168
183
  method: ta.Optional[str] = None,
184
+
169
185
  headers: ta.Optional[ta.Mapping[str, str]] = None,
186
+ no_auth: bool = False,
170
187
  content_type: ta.Optional[str] = None,
188
+
171
189
  content: ta.Optional[bytes] = None,
172
190
  json_content: ta.Optional[ta.Any] = None,
191
+
173
192
  success_status_codes: ta.Optional[ta.Container[int]] = None,
193
+
194
+ retry_status_codes: ta.Optional[ta.Container[int]] = None,
195
+ num_retries: int = 0,
196
+ retry_sleep: ta.Optional[float] = None,
174
197
  ) -> ta.Optional[ta.Any]:
175
- url = f'{self._service_url}/{path}'
198
+ if url is not None and path is not None:
199
+ raise RuntimeError('Must not pass both url and path')
200
+ elif path is not None:
201
+ url = f'{self._service_url}/{path}'
202
+ url = check.non_empty_str(url)
176
203
 
177
204
  if content is not None and json_content is not None:
178
205
  raise RuntimeError('Must not pass both content and json_content')
@@ -185,33 +212,52 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
185
212
  if method is None:
186
213
  method = 'POST' if content is not None else 'GET'
187
214
 
215
+ headers = self._build_request_headers(
216
+ headers,
217
+ no_auth=no_auth,
218
+ content_type=content_type,
219
+ json_content=header_json_content,
220
+ )
221
+
188
222
  #
189
223
 
190
- req = urllib.request.Request( # noqa
191
- url,
192
- method=method,
193
- headers=self.build_request_headers(
194
- headers,
195
- content_type=content_type,
196
- json_content=header_json_content,
197
- ),
198
- data=content,
199
- )
224
+ for n in itertools.count():
225
+ req = urllib.request.Request( # noqa
226
+ url,
227
+ method=method,
228
+ headers=headers,
229
+ data=content,
230
+ )
200
231
 
201
- resp, body = await self.send_url_request(req)
232
+ resp, body = await self._send_urllib_request(req)
202
233
 
203
- #
234
+ #
204
235
 
205
- if success_status_codes is not None:
206
- is_success = resp.status in success_status_codes
207
- else:
208
- is_success = (200 <= resp.status <= 300)
209
- if not is_success:
210
- raise self.ServiceRequestError(resp.status, body)
236
+ if success_status_codes is not None:
237
+ is_success = resp.status in success_status_codes
238
+ else:
239
+ is_success = (200 <= resp.status < 300)
240
+ if is_success:
241
+ return self._load_json_bytes(body)
211
242
 
212
- return self.load_json_bytes(body)
243
+ #
213
244
 
214
- #
245
+ log.debug(f'Request to url {url} got unsuccessful status code {resp.status}') # noqa
246
+
247
+ if not (
248
+ retry_status_codes is not None and
249
+ resp.status in retry_status_codes and
250
+ n < num_retries
251
+ ):
252
+ raise self.ServiceRequestError(resp.status, body)
253
+
254
+ if retry_sleep is not None:
255
+ await asyncio.sleep(retry_sleep)
256
+
257
+ raise RuntimeError('Unreachable')
258
+
259
+ ##
260
+ # keys
215
261
 
216
262
  KEY_PART_SEPARATOR = '---'
217
263
 
@@ -222,73 +268,8 @@ class GithubCacheServiceV1BaseClient(GithubCacheClient, abc.ABC):
222
268
  ('' if partial_suffix else self._key_suffix),
223
269
  ])
224
270
 
225
- #
226
-
227
- @dc.dataclass(frozen=True)
228
- class Entry(GithubCacheClient.Entry):
229
- artifact: GithubCacheServiceV1.ArtifactCacheEntry
230
-
231
- def get_entry_url(self, entry: GithubCacheClient.Entry) -> ta.Optional[str]:
232
- entry1 = check.isinstance(entry, self.Entry)
233
- return entry1.artifact.archive_location
234
-
235
- #
236
-
237
- def build_get_entry_url_path(self, *keys: str) -> str:
238
- qp = dict(
239
- keys=','.join(urllib.parse.quote_plus(k) for k in keys),
240
- version=str(self._cache_version),
241
- )
242
-
243
- return '?'.join([
244
- 'cache',
245
- '&'.join([
246
- f'{k}={v}'
247
- for k, v in qp.items()
248
- ]),
249
- ])
250
-
251
- GET_ENTRY_SUCCESS_STATUS_CODES = (200, 204)
252
-
253
-
254
- ##
255
-
256
-
257
- class GithubCacheServiceV1Client(GithubCacheServiceV1BaseClient):
258
- DEFAULT_CONCURRENCY = 4
259
-
260
- DEFAULT_CHUNK_SIZE = 32 * 1024 * 1024
261
-
262
- def __init__(
263
- self,
264
- *,
265
- concurrency: int = DEFAULT_CONCURRENCY,
266
- chunk_size: int = DEFAULT_CHUNK_SIZE,
267
- **kwargs: ta.Any,
268
- ) -> None:
269
- super().__init__(**kwargs)
270
-
271
- check.arg(concurrency > 0)
272
- self._concurrency = concurrency
273
-
274
- check.arg(chunk_size > 0)
275
- self._chunk_size = chunk_size
276
-
277
- #
278
-
279
- async def get_entry(self, key: str) -> ta.Optional[GithubCacheServiceV1BaseClient.Entry]:
280
- obj = await self.send_service_request(
281
- self.build_get_entry_url_path(self.fix_key(key, partial_suffix=True)),
282
- )
283
- if obj is None:
284
- return None
285
-
286
- return self.Entry(GithubCacheServiceV1.dataclass_from_json(
287
- GithubCacheServiceV1.ArtifactCacheEntry,
288
- obj,
289
- ))
290
-
291
- #
271
+ ##
272
+ # downloading
292
273
 
293
274
  @dc.dataclass(frozen=True)
294
275
  class _DownloadChunk:
@@ -306,7 +287,7 @@ class GithubCacheServiceV1Client(GithubCacheServiceV1BaseClient):
306
287
  },
307
288
  )
308
289
 
309
- _, buf_ = await self.send_url_request(req)
290
+ _, buf_ = await self._send_urllib_request(req)
310
291
 
311
292
  buf = check.not_none(buf_)
312
293
  check.equal(len(buf), chunk.size)
@@ -349,7 +330,7 @@ class GithubCacheServiceV1Client(GithubCacheServiceV1BaseClient):
349
330
  #
350
331
  # status_code = check.isinstance(curl_res['response_code'], int)
351
332
  #
352
- # if not (200 <= status_code <= 300):
333
+ # if not (200 <= status_code < 300):
353
334
  # raise RuntimeError(f'Curl chunk download {chunk} failed: {curl_res}')
354
335
 
355
336
  async def _download_file_chunk(self, chunk: _DownloadChunk) -> None:
@@ -361,11 +342,17 @@ class GithubCacheServiceV1Client(GithubCacheServiceV1BaseClient):
361
342
  ):
362
343
  await self._download_file_chunk_urllib(chunk)
363
344
 
364
- async def _download_file(self, entry: GithubCacheServiceV1BaseClient.Entry, out_file: str) -> None:
365
- key = check.non_empty_str(entry.artifact.cache_key)
366
- url = check.non_empty_str(entry.artifact.archive_location)
345
+ async def _download_file_chunks(
346
+ self,
347
+ *,
348
+ key: str,
349
+ url: str,
350
+ out_file: str,
351
+ ) -> None:
352
+ check.non_empty_str(key)
353
+ check.non_empty_str(url)
367
354
 
368
- head_resp, _ = await self.send_url_request(urllib.request.Request( # noqa
355
+ head_resp, _ = await self._send_urllib_request(urllib.request.Request( # noqa
369
356
  url,
370
357
  method='HEAD',
371
358
  ))
@@ -394,74 +381,68 @@ class GithubCacheServiceV1Client(GithubCacheServiceV1BaseClient):
394
381
 
395
382
  await asyncio_wait_concurrent(download_tasks, self._concurrency)
396
383
 
397
- async def download_file(self, entry: GithubCacheClient.Entry, out_file: str) -> None:
398
- entry1 = check.isinstance(entry, self.Entry)
399
- with log_timing_context(
400
- 'Downloading github cache '
401
- f'key {entry1.artifact.cache_key} '
402
- f'version {entry1.artifact.cache_version} '
403
- f'to {out_file}',
404
- ):
405
- await self._download_file(entry1, out_file)
384
+ ##
385
+ # uploading
406
386
 
407
- #
387
+ @dc.dataclass(frozen=True)
388
+ class _UploadChunk:
389
+ url: str
390
+ key: str
391
+ in_file: str
392
+ offset: int
393
+ size: int
408
394
 
409
- async def _upload_file_chunk(
410
- self,
411
- key: str,
412
- cache_id: int,
413
- in_file: str,
414
- offset: int,
415
- size: int,
416
- ) -> None:
417
- with log_timing_context(
418
- f'Uploading github cache {key} '
419
- f'file {in_file} '
420
- f'chunk {offset} - {offset + size}',
421
- ):
422
- with open(in_file, 'rb') as f: # noqa
423
- f.seek(offset)
424
- buf = f.read(size)
425
-
426
- check.equal(len(buf), size)
427
-
428
- await self.send_service_request(
429
- f'caches/{cache_id}',
430
- method='PATCH',
431
- content_type='application/octet-stream',
432
- headers={
433
- 'Content-Range': f'bytes {offset}-{offset + size - 1}/*',
434
- },
435
- content=buf,
436
- success_status_codes=[204],
437
- )
395
+ UPLOAD_CHUNK_NUM_RETRIES = 10
396
+ UPLOAD_CHUNK_RETRY_SLEEP = .5
438
397
 
439
- async def _upload_file(self, key: str, in_file: str) -> None:
440
- fixed_key = self.fix_key(key)
398
+ async def _upload_file_chunk_(self, chunk: _UploadChunk) -> None:
399
+ with open(chunk.in_file, 'rb') as f: # noqa
400
+ f.seek(chunk.offset)
401
+ buf = f.read(chunk.size)
441
402
 
442
- check.state(os.path.isfile(in_file))
403
+ check.equal(len(buf), chunk.size)
443
404
 
444
- file_size = os.stat(in_file).st_size
405
+ await self._send_request(
406
+ url=chunk.url,
445
407
 
446
- #
408
+ method='PATCH',
447
409
 
448
- reserve_req = GithubCacheServiceV1.ReserveCacheRequest(
449
- key=fixed_key,
450
- cache_size=file_size,
451
- version=str(self._cache_version),
452
- )
453
- reserve_resp_obj = await self.send_service_request(
454
- 'caches',
455
- json_content=GithubCacheServiceV1.dataclass_to_json(reserve_req),
456
- success_status_codes=[201],
457
- )
458
- reserve_resp = GithubCacheServiceV1.dataclass_from_json( # noqa
459
- GithubCacheServiceV1.ReserveCacheResponse,
460
- reserve_resp_obj,
410
+ headers={
411
+ 'Content-Range': f'bytes {chunk.offset}-{chunk.offset + chunk.size - 1}/*',
412
+ },
413
+ no_auth=True,
414
+ content_type='application/octet-stream',
415
+
416
+ content=buf,
417
+
418
+ success_status_codes=[204],
419
+
420
+ # retry_status_codes=[405],
421
+ num_retries=self.UPLOAD_CHUNK_NUM_RETRIES,
422
+ retry_sleep=self.UPLOAD_CHUNK_RETRY_SLEEP,
461
423
  )
462
- cache_id = check.isinstance(reserve_resp.cache_id, int)
463
424
 
464
- log.debug(f'Github cache file {os.path.basename(in_file)} got id {cache_id}') # noqa
425
+ async def _upload_file_chunk(self, chunk: _UploadChunk) -> None:
426
+ with log_timing_context(
427
+ f'Uploading github cache {chunk.key} '
428
+ f'file {chunk.in_file} '
429
+ f'chunk {chunk.offset} - {chunk.offset + chunk.size}',
430
+ ):
431
+ await self._upload_file_chunk_(chunk)
432
+
433
+ async def _upload_file_chunks(
434
+ self,
435
+ *,
436
+ in_file: str,
437
+ url: str,
438
+ key: str,
439
+
440
+ file_size: ta.Optional[int] = None,
441
+ ) -> None:
442
+ check.state(os.path.isfile(in_file))
443
+
444
+ if file_size is None:
445
+ file_size = os.stat(in_file).st_size
465
446
 
466
447
  #
467
448
 
@@ -470,30 +451,12 @@ class GithubCacheServiceV1Client(GithubCacheServiceV1BaseClient):
470
451
  for i in range((file_size // chunk_size) + (1 if file_size % chunk_size else 0)):
471
452
  offset = i * chunk_size
472
453
  size = min(chunk_size, file_size - offset)
473
- upload_tasks.append(self._upload_file_chunk(
474
- fixed_key,
475
- cache_id,
476
- in_file,
477
- offset,
478
- size,
479
- ))
454
+ upload_tasks.append(self._upload_file_chunk(self._UploadChunk(
455
+ url=url,
456
+ key=key,
457
+ in_file=in_file,
458
+ offset=offset,
459
+ size=size,
460
+ )))
480
461
 
481
462
  await asyncio_wait_concurrent(upload_tasks, self._concurrency)
482
-
483
- #
484
-
485
- commit_req = GithubCacheServiceV1.CommitCacheRequest(
486
- size=file_size,
487
- )
488
- await self.send_service_request(
489
- f'caches/{cache_id}',
490
- json_content=GithubCacheServiceV1.dataclass_to_json(commit_req),
491
- success_status_codes=[204],
492
- )
493
-
494
- async def upload_file(self, key: str, in_file: str) -> None:
495
- with log_timing_context(
496
- f'Uploading github cache file {os.path.basename(in_file)} '
497
- f'key {key}',
498
- ):
499
- await self._upload_file(key, in_file)
@@ -49,6 +49,11 @@ T = ta.TypeVar('T')
49
49
 
50
50
 
51
51
  class GithubCacheServiceV1:
52
+ def __new__(cls, *args, **kwargs): # noqa
53
+ raise TypeError
54
+
55
+ #
56
+
52
57
  API_VERSION = '6.0-preview.1'
53
58
 
54
59
  @classmethod
@@ -117,90 +122,3 @@ class GithubCacheServiceV1:
117
122
  compression_method: ta.Optional[str] # CompressionMethod
118
123
  enable_cross_os_archive: ta.Optional[bool]
119
124
  cache_size: ta.Optional[int]
120
-
121
-
122
- class GithubCacheServiceV2:
123
- SERVICE_NAME = 'github.actions.results.api.v1.CacheService'
124
-
125
- @dc.dataclass(frozen=True)
126
- class Method:
127
- name: str
128
- request: type
129
- response: type
130
-
131
- #
132
-
133
- class CacheScopePermission:
134
- READ = 1
135
- WRITE = 2
136
- ALL = READ | WRITE
137
-
138
- @dc.dataclass(frozen=True)
139
- class CacheScope:
140
- scope: str
141
- permission: int # CacheScopePermission
142
-
143
- @dc.dataclass(frozen=True)
144
- class CacheMetadata:
145
- repository_id: int
146
- scope: ta.Sequence['GithubCacheServiceV2.CacheScope']
147
-
148
- #
149
-
150
- @dc.dataclass(frozen=True)
151
- class CreateCacheEntryRequest:
152
- key: str
153
- version: str
154
- metadata: ta.Optional['GithubCacheServiceV2.CacheMetadata'] = None
155
-
156
- @dc.dataclass(frozen=True)
157
- class CreateCacheEntryResponse:
158
- ok: bool
159
- signed_upload_url: str
160
-
161
- CREATE_CACHE_ENTRY_METHOD = Method(
162
- 'CreateCacheEntry',
163
- CreateCacheEntryRequest,
164
- CreateCacheEntryResponse,
165
- )
166
-
167
- #
168
-
169
- @dc.dataclass(frozen=True)
170
- class FinalizeCacheEntryUploadRequest:
171
- key: str
172
- size_bytes: int
173
- version: str
174
- metadata: ta.Optional['GithubCacheServiceV2.CacheMetadata'] = None
175
-
176
- @dc.dataclass(frozen=True)
177
- class FinalizeCacheEntryUploadResponse:
178
- ok: bool
179
- entry_id: str
180
-
181
- FINALIZE_CACHE_ENTRY_METHOD = Method(
182
- 'FinalizeCacheEntryUpload',
183
- FinalizeCacheEntryUploadRequest,
184
- FinalizeCacheEntryUploadResponse,
185
- )
186
-
187
- #
188
-
189
- @dc.dataclass(frozen=True)
190
- class GetCacheEntryDownloadUrlRequest:
191
- key: str
192
- restore_keys: ta.Sequence[str]
193
- version: str
194
- metadata: ta.Optional['GithubCacheServiceV2.CacheMetadata'] = None
195
-
196
- @dc.dataclass(frozen=True)
197
- class GetCacheEntryDownloadUrlResponse:
198
- ok: bool
199
- signed_download_url: str
200
- matched_key: str
201
-
202
- GET_CACHE_ENTRY_DOWNLOAD_URL_METHOD = Method(
203
- 'GetCacheEntryDownloadURL',
204
- GetCacheEntryDownloadUrlRequest,
205
- GetCacheEntryDownloadUrlResponse,
206
- )