rbx.cp 0.14.0__tar.gz → 0.16.0__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 (230) hide show
  1. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/PKG-INFO +2 -1
  2. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/pyproject.toml +6 -1
  3. rbx_cp-0.16.0/rbx/__version__.py +1 -0
  4. rbx_cp-0.16.0/rbx/box/git_utils.py +56 -0
  5. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/presets/__init__.py +79 -14
  6. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/presets/fetch.py +10 -2
  7. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/presets/schema.py +16 -1
  8. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/contest/statement/info.rbx.tex +5 -13
  9. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/preset.rbx.yml +1 -0
  10. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/shared/icpc.sty +2 -2
  11. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/utils.py +45 -0
  12. rbx_cp-0.14.0/rbx/box/git_utils.py +0 -28
  13. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/LICENSE +0 -0
  14. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/README.md +0 -0
  15. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/__init__.py +0 -0
  16. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/annotations.py +0 -0
  17. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/autoenum.py +0 -0
  18. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/__init__.py +0 -0
  19. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/builder.py +0 -0
  20. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/cd.py +0 -0
  21. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/checkers.py +0 -0
  22. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/cli.py +0 -0
  23. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/code.py +0 -0
  24. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/compile.py +0 -0
  25. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/__init__.py +0 -0
  26. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/build_contest_statements.py +0 -0
  27. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/contest_package.py +0 -0
  28. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/contest_utils.py +0 -0
  29. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/main.py +0 -0
  30. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/schema.py +0 -0
  31. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/contest/statements.py +0 -0
  32. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/creation.py +0 -0
  33. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/deferred.py +0 -0
  34. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/download.py +0 -0
  35. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/dump_schemas.py +0 -0
  36. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/environment.py +0 -0
  37. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/extensions.py +0 -0
  38. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/fields.py +0 -0
  39. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/formatting.py +0 -0
  40. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/generators.py +0 -0
  41. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/global_package.py +0 -0
  42. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/header.py +0 -0
  43. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/lang.py +0 -0
  44. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/lazy_importing_main.py +0 -0
  45. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/limits_info.py +0 -0
  46. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/linting.py +0 -0
  47. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/main.py +0 -0
  48. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/naming.py +0 -0
  49. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/package.py +0 -0
  50. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/__init__.py +0 -0
  51. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/boca/__init__.py +0 -0
  52. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/boca/boca_language_utils.py +0 -0
  53. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/boca/boca_outcome_utils.py +0 -0
  54. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/boca/extension.py +0 -0
  55. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/boca/packager.py +0 -0
  56. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/contest_main.py +0 -0
  57. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/importer.py +0 -0
  58. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/main.py +0 -0
  59. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/moj/packager.py +0 -0
  60. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/packager.py +0 -0
  61. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/pkg/packager.py +0 -0
  62. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/polygon/importer.py +0 -0
  63. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/polygon/packager.py +0 -0
  64. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/polygon/polygon_api.py +0 -0
  65. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/polygon/test.py +0 -0
  66. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/polygon/upload.py +0 -0
  67. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/packaging/polygon/xml_schema.py +0 -0
  68. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/presets/lock_schema.py +0 -0
  69. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/remote.py +0 -0
  70. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/retries.py +0 -0
  71. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/sanitizers/issue_stack.py +0 -0
  72. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/sanitizers/warning_stack.py +0 -0
  73. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/schema.py +0 -0
  74. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/setter_config.py +0 -0
  75. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/solutions.py +0 -0
  76. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/state.py +0 -0
  77. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/__init__.py +0 -0
  78. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/build_statements.py +0 -0
  79. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/builders.py +0 -0
  80. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/expander.py +0 -0
  81. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/joiners.py +0 -0
  82. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/latex.py +0 -0
  83. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/latex_jinja.py +0 -0
  84. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/statements/schema.py +0 -0
  85. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/stats.py +0 -0
  86. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/stresses.py +0 -0
  87. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/stressing/__init__.py +0 -0
  88. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/stressing/finder_parser.py +0 -0
  89. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/stressing/generator_parser.py +0 -0
  90. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tasks.py +0 -0
  91. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testcase_extractors.py +0 -0
  92. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testcase_utils.py +0 -0
  93. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testcases/__init__.py +0 -0
  94. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testcases/main.py +0 -0
  95. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testing/__init__.py +0 -0
  96. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testing/testing_package.py +0 -0
  97. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testing/testing_preset.py +0 -0
  98. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/testing/testing_shared.py +0 -0
  99. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/timing.py +0 -0
  100. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/__init__.py +0 -0
  101. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/boca/__init__.py +0 -0
  102. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/boca/debug_utils.py +0 -0
  103. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/boca/main.py +0 -0
  104. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/boca/manual_scrape.py +0 -0
  105. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/boca/scrape.py +0 -0
  106. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/boca/scraper.py +0 -0
  107. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/converter.py +0 -0
  108. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/tooling/main.py +0 -0
  109. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/__init__.py +0 -0
  110. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/captured_log.py +0 -0
  111. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/css/app.tcss +0 -0
  112. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/main.py +0 -0
  113. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/__init__.py +0 -0
  114. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/build.py +0 -0
  115. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/command.py +0 -0
  116. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/differ.py +0 -0
  117. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/error.py +0 -0
  118. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/rich_log_modal.py +0 -0
  119. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/run.py +0 -0
  120. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/run_explorer.py +0 -0
  121. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/run_test_explorer.py +0 -0
  122. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/selector.py +0 -0
  123. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/screens/test_explorer.py +0 -0
  124. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/utils/__init__.py +0 -0
  125. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/utils/run_ui.py +0 -0
  126. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/__init__.py +0 -0
  127. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/diff_box.py +0 -0
  128. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/file_log.py +0 -0
  129. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/interaction_box.py +0 -0
  130. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/rich_log_box.py +0 -0
  131. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/test_output_box.py +0 -0
  132. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/ui/widgets/two_sided_test_output_box.py +0 -0
  133. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/unit.py +0 -0
  134. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/box/validators.py +0 -0
  135. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/config.py +0 -0
  136. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/console.py +0 -0
  137. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/__init__.py +0 -0
  138. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/caching.py +0 -0
  139. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/debug_context.py +0 -0
  140. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/grading_context.py +0 -0
  141. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/__init__.py +0 -0
  142. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/cacher.py +0 -0
  143. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/digester.py +0 -0
  144. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/program.py +0 -0
  145. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/sandbox.py +0 -0
  146. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/sandboxes/__init__.py +0 -0
  147. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/sandboxes/stupid_sandbox.py +0 -0
  148. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/sandboxes/tee.py +0 -0
  149. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/judge/storage.py +0 -0
  150. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/limits.py +0 -0
  151. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/profiling.py +0 -0
  152. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/steps.py +0 -0
  153. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/grading/steps_with_caching.py +0 -0
  154. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/checkers/boilerplate.cpp +0 -0
  155. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/checkers/noop.cpp +0 -0
  156. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/default_config.json +0 -0
  157. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/default_setter_config.mac.yml +0 -0
  158. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/default_setter_config.yml +0 -0
  159. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/envs/default.rbx.yml +0 -0
  160. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/checker.sh +0 -0
  161. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compare.sh +0 -0
  162. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/c +0 -0
  163. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/cc +0 -0
  164. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/cpp +0 -0
  165. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/java +0 -0
  166. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/kt +0 -0
  167. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/py2 +0 -0
  168. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/compile/py3 +0 -0
  169. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/c +0 -0
  170. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/cc +0 -0
  171. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/cpp +0 -0
  172. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/java +0 -0
  173. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/kt +0 -0
  174. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/py2 +0 -0
  175. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactive/py3 +0 -0
  176. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactor_compile.sh +0 -0
  177. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/interactor_run.sh +0 -0
  178. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/bkp +0 -0
  179. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/c +0 -0
  180. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/cc +0 -0
  181. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/cpp +0 -0
  182. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/java +0 -0
  183. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/kt +0 -0
  184. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/py2 +0 -0
  185. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/run/py3 +0 -0
  186. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/safeexec.c +0 -0
  187. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/boca/safeexec_compile.sh +0 -0
  188. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/c/compile.sh +0 -0
  189. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/c/prep.sh +0 -0
  190. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/c/run.sh +0 -0
  191. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/compare.sh +0 -0
  192. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/cpp/compile.sh +0 -0
  193. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/cpp/prep.sh +0 -0
  194. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/cpp/run.sh +0 -0
  195. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/interactor_prep.sh +0 -0
  196. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/interactor_run.sh +0 -0
  197. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/java/compile.sh +0 -0
  198. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/java/prep.sh +0 -0
  199. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/java/run.sh +0 -0
  200. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/py2/compile.sh +0 -0
  201. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/py2/prep.sh +0 -0
  202. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/py2/run.sh +0 -0
  203. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/py3/compile.sh +0 -0
  204. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/py3/prep.sh +0 -0
  205. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/packagers/moj/scripts/py3/run.sh +0 -0
  206. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/contest/.gitignore +0 -0
  207. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
  208. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
  209. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/contest/statement/instructions.tex +0 -0
  210. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/contest/statement/logo.png +0 -0
  211. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/env.rbx.yml +0 -0
  212. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/.gitignore +0 -0
  213. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/gens/gen.cpp +0 -0
  214. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/manual_tests/samples/000.in +0 -0
  215. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/manual_tests/samples/001.in +0 -0
  216. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
  217. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/rbx.h +0 -0
  218. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
  219. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/sols/wa-overflow.cpp +0 -0
  220. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
  221. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/testlib.h +0 -0
  222. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/testplan/random.py +0 -0
  223. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/testplan/random.txt +0 -0
  224. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/validator.cpp +0 -0
  225. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
  226. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/shared/contest_template.rbx.tex +0 -0
  227. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/presets/default/shared/problem_template.rbx.tex +0 -0
  228. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/templates/rbx.h +0 -0
  229. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/resources/templates/template.cpp +0 -0
  230. {rbx_cp-0.14.0 → rbx_cp-0.16.0}/rbx/testing_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.14.0
3
+ Version: 0.16.0
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9.1,<4.0.0
@@ -40,6 +40,7 @@ Requires-Dist: requests (>=2.32.3,<3.0.0)
40
40
  Requires-Dist: rich (>=13.9.4,<14.0.0)
41
41
  Requires-Dist: ruamel-yaml (>=0.18.14,<0.19.0)
42
42
  Requires-Dist: ruyaml (>=0.91.0,<0.92.0)
43
+ Requires-Dist: semver (>=3.0.4,<4.0.0)
43
44
  Requires-Dist: sqlitedict (>=2.1.0,<3.0.0)
44
45
  Requires-Dist: syncer (>=2.0.3,<3.0.0)
45
46
  Requires-Dist: textual (>=3.1.1,<4.0.0)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "rbx.cp"
3
- version = "0.14.0"
3
+ version = "0.16.0"
4
4
  description = ""
5
5
  packages = [
6
6
  {include = "rbx"}
@@ -52,6 +52,7 @@ iso639-lang = "^2.6.1"
52
52
  sqlitedict = "^2.1.0"
53
53
  throttlex = "^1.0.0"
54
54
  typing-extensions = "^4.14.1"
55
+ semver = "^3.0.4"
55
56
 
56
57
  [tool.poetry.scripts]
57
58
  rbx = "rbx.box.main:app"
@@ -83,6 +84,10 @@ version_provider = "poetry"
83
84
  update_changelog_on_bump = true
84
85
  major_version_zero = true
85
86
  annotated_tag = true
87
+ version_files = [
88
+ "rbx/__version__.py",
89
+ "rbx/resources/presets/default/preset.rbx.yml:^version",
90
+ ]
86
91
 
87
92
  [build-system]
88
93
  requires = ["poetry-core"]
@@ -0,0 +1 @@
1
+ __version__ = '0.16.0'
@@ -0,0 +1,56 @@
1
+ import pathlib
2
+ import subprocess
3
+ from typing import List, Optional
4
+
5
+ import git
6
+ import semver
7
+
8
+
9
+ def get_repo_or_nil(
10
+ root: pathlib.Path = pathlib.Path(), search_parent_directories: bool = False
11
+ ) -> Optional[git.Repo]:
12
+ try:
13
+ return git.Repo(root, search_parent_directories=search_parent_directories)
14
+ except git.InvalidGitRepositoryError:
15
+ return None
16
+
17
+
18
+ def is_repo(path: pathlib.Path) -> bool:
19
+ return get_repo_or_nil(path, search_parent_directories=False) is not None
20
+
21
+
22
+ def is_within_repo(path: pathlib.Path) -> bool:
23
+ return get_repo_or_nil(path, search_parent_directories=True) is not None
24
+
25
+
26
+ def get_any_remote(repo: git.Repo) -> Optional[git.Remote]:
27
+ for remote in repo.remotes:
28
+ if remote.exists():
29
+ return remote
30
+ return None
31
+
32
+
33
+ def _parse_tag_from_ref(ref: str) -> str:
34
+ return ref.split('/')[-1].split('^{}')[0]
35
+
36
+
37
+ def ls_remote_tags(uri: str) -> List[str]:
38
+ completed_process = subprocess.run(
39
+ ['git', 'ls-remote', '--tags', uri],
40
+ check=True,
41
+ capture_output=True,
42
+ text=True,
43
+ )
44
+ return [
45
+ _parse_tag_from_ref(line.split('\t')[1])
46
+ for line in completed_process.stdout.split('\n')
47
+ if line
48
+ ]
49
+
50
+
51
+ def latest_remote_tag(uri: str) -> str:
52
+ tags = ls_remote_tags(uri)
53
+ valid_tags = [tag for tag in tags if semver.Version.is_valid(tag)]
54
+ if not valid_tags:
55
+ raise ValueError(f'No valid tags found for {uri}')
56
+ return sorted(valid_tags, key=semver.VersionInfo.parse)[-1]
@@ -1,15 +1,23 @@
1
+ import functools
1
2
  import os
2
3
  import pathlib
3
4
  import shutil
4
5
  import tempfile
5
6
  from typing import Annotated, Iterable, List, Optional, Sequence, Set, Tuple, Union
6
7
 
8
+ import questionary
7
9
  import ruyaml
10
+ import semver
8
11
  import typer
9
12
 
10
13
  from rbx import console, utils
11
14
  from rbx.box import cd
12
- from rbx.box.presets.fetch import PresetFetchInfo, get_preset_fetch_info
15
+ from rbx.box.git_utils import latest_remote_tag
16
+ from rbx.box.presets.fetch import (
17
+ PresetFetchInfo,
18
+ get_preset_fetch_info,
19
+ get_remote_uri_from_tool_preset,
20
+ )
13
21
  from rbx.box.presets.lock_schema import LockedAsset, PresetLock, SymlinkInfo
14
22
  from rbx.box.presets.schema import Preset, TrackedAsset
15
23
  from rbx.config import get_default_app_path
@@ -17,7 +25,7 @@ from rbx.grading.judge.digester import digest_cooperatively
17
25
 
18
26
  app = typer.Typer(no_args_is_help=True)
19
27
 
20
- _FALLBACK_PRESET_URI = 'rsalesc/rbx/rbx/resources/presets/default'
28
+ _FALLBACK_PRESET_NAME = 'default'
21
29
 
22
30
 
23
31
  def find_preset_yaml(root: pathlib.Path = pathlib.Path()) -> Optional[pathlib.Path]:
@@ -27,6 +35,30 @@ def find_preset_yaml(root: pathlib.Path = pathlib.Path()) -> Optional[pathlib.Pa
27
35
  return None
28
36
 
29
37
 
38
+ @functools.cache
39
+ def _check_preset_compatibility(preset_name: str, preset_version: str) -> None:
40
+ compatibility = utils.check_version_compatibility(preset_version)
41
+ if compatibility == utils.SemVerCompatibility.OUTDATED:
42
+ console.console.print(
43
+ f'[error]Preset [item]{preset_name}[/item] requires rbx at version [item]{preset_version}[/item], but the current version is [item]{utils.get_version()}[/item].[/error]'
44
+ )
45
+ console.console.print(
46
+ f'[error]Please update rbx.cp to the latest compatible version using [item]{utils.get_upgrade_command(preset_version)}[/item].[/error]'
47
+ )
48
+ raise typer.Exit(1)
49
+ if compatibility == utils.SemVerCompatibility.BREAKING_CHANGE:
50
+ console.console.print(
51
+ f'[error]Preset [item]{preset_name}[/item] requires rbx at version [item]{preset_version}[/item], but the current version is [item]{utils.get_version()}[/item].[/error]'
52
+ )
53
+ console.console.print(
54
+ '[error]rbx version is newer, but is in a later major version, which might have introduced breaking changes.[/error]'
55
+ )
56
+ console.console.print(
57
+ '[error]If you are sure that the preset is compatible with the current rbx version, you can change the [item]min_version[/item] field in the preset file ([item].local.rbx/preset.rbx.yml)[/item] to the current version.[/error]'
58
+ )
59
+ raise typer.Exit(1)
60
+
61
+
30
62
  def get_preset_yaml(root: pathlib.Path = pathlib.Path()) -> Preset:
31
63
  found = find_preset_yaml(root)
32
64
  if not found:
@@ -34,7 +66,9 @@ def get_preset_yaml(root: pathlib.Path = pathlib.Path()) -> Preset:
34
66
  f'[error][item]preset.rbx.yml[/item] not found in [item]{root.absolute()}[/item][/error]'
35
67
  )
36
68
  raise typer.Exit(1)
37
- return utils.model_from_yaml(Preset, found.read_text())
69
+ preset = utils.model_from_yaml(Preset, found.read_text())
70
+ _check_preset_compatibility(preset.name, preset.min_version)
71
+ return preset
38
72
 
39
73
 
40
74
  def _find_preset_lock(root: pathlib.Path = pathlib.Path()) -> Optional[pathlib.Path]:
@@ -478,7 +512,7 @@ def get_preset_fetch_info_with_fallback(
478
512
  # Use active preset if any, otherwise use the default preset.
479
513
  if get_active_preset_or_null() is not None:
480
514
  return None
481
- default_preset = get_preset_fetch_info(_FALLBACK_PRESET_URI)
515
+ default_preset = get_preset_fetch_info(_FALLBACK_PRESET_NAME)
482
516
  if default_preset is None:
483
517
  console.console.print(
484
518
  '[error]Internal error: could not find [item]default[/item] preset.[/error]'
@@ -527,6 +561,15 @@ def install_preset_from_dir(
527
561
  f'[error]Preset [item]{preset.name}[/item] does not have a problem package definition.[/error]'
528
562
  )
529
563
  raise typer.Exit(1)
564
+
565
+ try:
566
+ _check_preset_compatibility(preset.name, preset.min_version)
567
+ except Exception:
568
+ console.console.print(
569
+ f'[error]Error updating preset [item]{preset.name}[/item] to its latest version.[/error]'
570
+ )
571
+ raise
572
+
530
573
  dest.parent.mkdir(parents=True, exist_ok=True)
531
574
  copy_tree_normalizing_gitdir(src, dest, update=update)
532
575
 
@@ -614,6 +657,29 @@ def _install_preset_from_resources(
614
657
  yaml_path = rsrc_preset_path / 'preset.rbx.yml'
615
658
  if not yaml_path.is_file():
616
659
  return False
660
+ preset_uri = get_remote_uri_from_tool_preset(fetch_info.name)
661
+ remote_fetch_info = get_preset_fetch_info(preset_uri)
662
+ if remote_fetch_info is None or remote_fetch_info.fetch_uri is None:
663
+ console.console.print(
664
+ f'[error]Preset [item]{fetch_info.name}[/item] not found.[/error]'
665
+ )
666
+ raise typer.Exit(1)
667
+
668
+ # Check if the latest release has breaking changes.
669
+ latest_tag = latest_remote_tag(remote_fetch_info.fetch_uri)
670
+ latest_version = semver.VersionInfo.parse(latest_tag)
671
+ if latest_version.major > utils.get_semver().major:
672
+ console.console.print(
673
+ f'[error]You are not in rbx.cp latest major version ({latest_version.major}), but are installing a built-in preset from rbx.cp.[/error]'
674
+ )
675
+ console.console.print(
676
+ f'[error]To allow for a better experience for users that clone your repository, please update rbx.cp to the latest major version using [item]{utils.get_upgrade_command(latest_version)}[/item].[/error]'
677
+ )
678
+ if not questionary.confirm(
679
+ 'If you want to proceed anyway, press [y]', default=False
680
+ ).ask():
681
+ raise typer.Exit(1)
682
+
617
683
  console.console.print(
618
684
  f'Installing preset [item]{fetch_info.name}[/item] from resources...'
619
685
  )
@@ -622,7 +688,7 @@ def _install_preset_from_resources(
622
688
  dest,
623
689
  ensure_contest,
624
690
  ensure_problem,
625
- override_uri=str(utils.abspath(rsrc_preset_path)),
691
+ override_uri=preset_uri,
626
692
  update=update,
627
693
  )
628
694
  return True
@@ -653,15 +719,14 @@ def _install_preset_from_fetch_info(
653
719
  update=update,
654
720
  )
655
721
  return
656
- # NOTE: Disabled for now.
657
- # if _install_preset_from_resources(
658
- # fetch_info,
659
- # dest,
660
- # ensure_contest=ensure_contest,
661
- # ensure_problem=ensure_problem,
662
- # update=update,
663
- # ):
664
- # return
722
+ if _install_preset_from_resources(
723
+ fetch_info,
724
+ dest,
725
+ ensure_contest=ensure_contest,
726
+ ensure_problem=ensure_problem,
727
+ update=update,
728
+ ):
729
+ return
665
730
  console.console.print(
666
731
  f'[error]Preset [item]{fetch_info.name}[/item] not found.[/error]'
667
732
  )
@@ -25,6 +25,14 @@ class PresetFetchInfo(BaseModel):
25
25
  return bool(self.inner_dir) and not self.is_remote()
26
26
 
27
27
 
28
+ def get_inner_dir_from_tool_preset(tool_preset: str) -> str:
29
+ return f'rbx/resources/presets/{tool_preset}'
30
+
31
+
32
+ def get_remote_uri_from_tool_preset(tool_preset: str) -> str:
33
+ return f'rsalesc/rbx/{get_inner_dir_from_tool_preset(tool_preset)}'
34
+
35
+
28
36
  def get_preset_fetch_info(uri: Optional[str]) -> Optional[PresetFetchInfo]:
29
37
  if uri is None:
30
38
  return None
@@ -64,7 +72,7 @@ def get_preset_fetch_info(uri: Optional[str]) -> Optional[PresetFetchInfo]:
64
72
  return None
65
73
  return PresetFetchInfo(name=path.name, inner_dir=str(path))
66
74
 
67
- def get_local_fetch_info(s: str) -> Optional[PresetFetchInfo]:
75
+ def get_tool_fetch_info(s: str) -> Optional[PresetFetchInfo]:
68
76
  pattern = r'[\w\-]+'
69
77
  compiled = re.compile(pattern)
70
78
  match = compiled.match(s)
@@ -76,7 +84,7 @@ def get_preset_fetch_info(uri: Optional[str]) -> Optional[PresetFetchInfo]:
76
84
  get_github_fetch_info,
77
85
  get_short_github_fetch_info,
78
86
  get_local_dir_fetch_info,
79
- get_local_fetch_info,
87
+ get_tool_fetch_info,
80
88
  ]
81
89
 
82
90
  for extract in extractors:
@@ -1,8 +1,9 @@
1
1
  import pathlib
2
2
  from typing import List, Optional
3
3
 
4
+ import semver
4
5
  import typer
5
- from pydantic import BaseModel, Field
6
+ from pydantic import BaseModel, Field, field_validator
6
7
 
7
8
  from rbx import console
8
9
  from rbx.box.presets.fetch import PresetFetchInfo, get_preset_fetch_info
@@ -42,6 +43,9 @@ class Preset(BaseModel):
42
43
  # Should usually be a GitHub repository.
43
44
  uri: str
44
45
 
46
+ # Minimum version of rbx.cp required to use this preset.
47
+ min_version: str = '0.14.0'
48
+
45
49
  # Path to the environment file that will be installed with this preset.
46
50
  # When copied to the box environment, the environment will be named `name`.
47
51
  env: Optional[pathlib.Path] = None
@@ -57,6 +61,17 @@ class Preset(BaseModel):
57
61
  # package changes in the preset, or when a latex template is changed.
58
62
  tracking: Tracking = Field(default_factory=Tracking)
59
63
 
64
+ @field_validator('min_version')
65
+ @classmethod
66
+ def validate_min_version(cls, value: str) -> str:
67
+ try:
68
+ semver.Version.parse(value)
69
+ except ValueError as err:
70
+ raise ValueError(
71
+ "min_version must be a valid SemVer string (e.g., '1.2.3' or '1.2.3-rc.1')"
72
+ ) from err
73
+ return value
74
+
60
75
  @property
61
76
  def fetch_info(self) -> PresetFetchInfo:
62
77
  res = get_preset_fetch_info(self.uri)
@@ -1,14 +1,6 @@
1
- \documentclass{article}
2
- \usepackage[a4paper, margin=1in]{geometry}
3
- \usepackage{multirow}
4
- \usepackage{multicol}
5
- \usepackage{graphicx}
6
- \usepackage{amsfonts}
7
- \usepackage[brazil]{babel}
8
- \usepackage[utf8]{inputenc}
9
- \usepackage[T1]{fontenc}
10
-
11
- \usepackage[utf8]{inputenc}
1
+ \documentclass[a4paper, 11pt]{article}
2
+
3
+ \def\lang{\VAR{lang}}
12
4
  \usepackage{icpc}
13
5
 
14
6
  %\pagestyle{myheadings}
@@ -35,7 +27,7 @@
35
27
 
36
28
  \begin{center}
37
29
  \begin{tabular}{c|ccc|c}
38
- & \multicolumn{3}{c|}{\strTimeLimit (ms)} & \multirow{2}{*}{\strMemoryLimit (MiB)} \\
30
+ & \multicolumn{3}{c|}{{\strTimeLimit} (ms)} & \multirow{2}{*}{{\strMemoryLimit} (MiB)} \\
39
31
  %\cline{2-4}
40
32
  {\sf \strProblem} & {\sf C/C++} &{\sf Java} & {\sf Python3} & \\
41
33
  \hline
@@ -51,4 +43,4 @@
51
43
  \end{center}
52
44
  \vspace*{\fill}
53
45
  \end{titlepage}
54
- \end{document}
46
+ \end{document}
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  # yaml-language-server: $schema=https://rsalesc.github.io/rbx/schemas/Preset.json
3
3
  name: "default"
4
+ min_version: "0.15.0"
4
5
  uri: "rsalesc/rbx/rbx/resources/presets/default"
5
6
  problem: "problem"
6
7
  contest: "contest"
@@ -308,7 +308,7 @@
308
308
  \newcommand{\InsertTitlePage}
309
309
  {
310
310
  \pagestyle{myheadings}
311
- \markright{\Title -- \Year}
311
+ \markright{{\Title} -- \Year}
312
312
 
313
313
  %%% Title Page
314
314
  \begin{titlepage}
@@ -347,7 +347,7 @@
347
347
  \newcommand{\InsertEditorialTitlePage}
348
348
  {
349
349
  \pagestyle{myheadings}
350
- \markright{\Title -- \Year}
350
+ \markright{{\Title} -- \Year}
351
351
 
352
352
  %%% Title Page
353
353
  \begin{titlepage}
@@ -1,4 +1,5 @@
1
1
  import contextlib
2
+ import enum
2
3
  import fcntl
3
4
  import functools
4
5
  import json
@@ -17,19 +18,63 @@ import rich.markup
17
18
  import rich.prompt
18
19
  import rich.status
19
20
  import ruyaml
21
+ import semver
20
22
  import typer
21
23
  import yaml
22
24
  from pydantic import BaseModel
23
25
  from rich import text
24
26
  from rich.highlighter import JSONHighlighter
25
27
 
28
+ from rbx import __version__
26
29
  from rbx.console import console
27
30
 
28
31
  T = TypeVar('T', bound=BaseModel)
29
32
  APP_NAME = 'rbx'
33
+ PIP_NAME = 'rbx.cp'
30
34
  PathOrStr = Union[pathlib.Path, str]
31
35
 
32
36
 
37
+ class SemVerCompatibility(enum.Enum):
38
+ COMPATIBLE = 'compatible'
39
+ OUTDATED = 'outdated'
40
+ BREAKING_CHANGE = 'breaking_change'
41
+
42
+
43
+ def get_version() -> str:
44
+ return __version__.__version__
45
+
46
+
47
+ def get_semver() -> semver.VersionInfo:
48
+ return semver.VersionInfo.parse(get_version())
49
+
50
+
51
+ def get_upgrade_command(
52
+ version: Optional[Union[str, semver.VersionInfo]] = None,
53
+ ) -> str:
54
+ parsed_version = (
55
+ semver.VersionInfo.parse(version) if isinstance(version, str) else version
56
+ ) or get_semver()
57
+ return f'pipx install --upgrade {PIP_NAME}@{parsed_version.major}'
58
+
59
+
60
+ def check_version_compatibility_between(
61
+ installed: str,
62
+ required: str,
63
+ ) -> SemVerCompatibility:
64
+ installed_version = semver.VersionInfo.parse(installed)
65
+ required_version = semver.VersionInfo.parse(required)
66
+ if installed_version < required_version:
67
+ return SemVerCompatibility.OUTDATED
68
+ if installed_version.major > required_version.major:
69
+ return SemVerCompatibility.BREAKING_CHANGE
70
+ return SemVerCompatibility.COMPATIBLE
71
+
72
+
73
+ def check_version_compatibility(required: str) -> SemVerCompatibility:
74
+ installed = get_version()
75
+ return check_version_compatibility_between(installed, required)
76
+
77
+
33
78
  def create_and_write(path: pathlib.Path, *args, **kwargs):
34
79
  path.parent.mkdir(parents=True, exist_ok=True)
35
80
  path.write_text(*args, **kwargs)
@@ -1,28 +0,0 @@
1
- import pathlib
2
- from typing import Optional
3
-
4
- import git
5
-
6
-
7
- def get_repo_or_nil(
8
- root: pathlib.Path = pathlib.Path(), search_parent_directories: bool = False
9
- ) -> Optional[git.Repo]:
10
- try:
11
- return git.Repo(root, search_parent_directories=search_parent_directories)
12
- except git.InvalidGitRepositoryError:
13
- return None
14
-
15
-
16
- def is_repo(path: pathlib.Path) -> bool:
17
- return get_repo_or_nil(path, search_parent_directories=False) is not None
18
-
19
-
20
- def is_within_repo(path: pathlib.Path) -> bool:
21
- return get_repo_or_nil(path, search_parent_directories=True) is not None
22
-
23
-
24
- def get_any_remote(repo: git.Repo) -> Optional[git.Remote]:
25
- for remote in repo.remotes:
26
- if remote.exists():
27
- return remote
28
- return None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes