rbx.cp 0.5.36__tar.gz → 0.5.38__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.
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/PKG-INFO +1 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/pyproject.toml +1 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/annotations.py +0 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/builder.py +5 -2
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/statements.py +3 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/generators.py +19 -319
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/generators_test.py +1 -1
- rbx_cp-0.5.38/rbx/box/lazy_importing_main.py +7 -0
- rbx_cp-0.5.38/rbx/box/lazy_importing_test.py +25 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/main.py +12 -3
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/contest_main.py +5 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/main.py +7 -3
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/presets/__init__.py +6 -2
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/schema.py +8 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/setter_config.py +0 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/solutions.py +3 -2
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/solutions_test.py +1 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/build_statements.py +3 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/builders.py +7 -6
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/joiners.py +7 -6
- rbx_cp-0.5.38/rbx/box/testcase_extractors.py +348 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/testcase_utils.py +10 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/testcases/main.py +4 -2
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/validators.py +61 -33
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/config.py +8 -2
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/sandboxes/stupid_sandbox.py +0 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testing_utils.py +0 -1
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/utils.py +1 -4
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/LICENSE +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/README.md +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/autoenum.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/cd.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/checkers.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/code.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/compile.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/conftest.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/build_contest_statements.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/contest_package.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/contest_utils.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/main.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/contest/schema.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/creation.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/deferred.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/download.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/environment.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/extensions.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/formatting.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/package.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/boca/extension.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/boca/packager.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/packager.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/polygon/packager.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/polygon/test.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/packaging/polygon/xml_schema.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/presets/fetch.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/presets/lock_schema.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/presets/schema.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/retries.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/sanitizers/warning_stack.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/state.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/latex.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/latex_jinja.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/statements/schema.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/stresses.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/stressing/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/stressing/finder_parser.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/stressing/generator_parser.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/testcases/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/ui/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/ui/captured_log.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/ui/css/app.tcss +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/ui/main.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/ui/run.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/box/validators_test.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/checker.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/clone.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/conftest.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/console.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/create.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/edit.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/caching.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/conftest.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/cacher.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/digester.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/sandbox.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/sandboxes/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/sandboxes/isolate.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/sandboxes/timeit.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/storage.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/test.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/judge/testiso.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/steps.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/steps_with_caching.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading/steps_with_caching_run_test.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/grading_utils.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/hydration.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/main.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/metadata.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/providers/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/providers/codeforces.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/providers/provider.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/checkers/boilerplate.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/default_config.json +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/default_setter_config.mac.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/default_setter_config.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/envs/default.rbx.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/envs/isolate.rbx.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/checker.sh +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compare +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/c +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/cc +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/java +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/kt +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/pas +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/py2 +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/compile/py3 +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/c +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/cc +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/java +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/kt +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/py2 +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/packagers/boca/run/py3 +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/preset.rbx.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/.gitignore +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/gen.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/random.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/random.txt +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/validator.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/resources/templates/template.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/run.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/schema.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/submit.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/submitors/__init__.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/submitors/codeforces.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/submitors/submitor.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/test.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testcase.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testcase_rendering.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/gen1.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/gen2.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/genScript.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/hard-tle.sol.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/ole.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/problem.rbx.yml +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/re.sol.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/sol.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/tests/1.in +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/tle.sol.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/validator.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/box1/wa.sol.cpp +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/caching/executable.py +0 -0
- {rbx_cp-0.5.36 → rbx_cp-0.5.38}/rbx/testdata/compatible +0 -0
@@ -4,7 +4,6 @@ from rbx import console, utils
|
|
4
4
|
from rbx.box import environment, package
|
5
5
|
from rbx.box.environment import VerificationLevel
|
6
6
|
from rbx.box.generators import (
|
7
|
-
extract_generation_testcases_from_groups,
|
8
7
|
generate_outputs_for_testcases,
|
9
8
|
generate_testcases,
|
10
9
|
)
|
@@ -13,6 +12,7 @@ from rbx.box.solutions import (
|
|
13
12
|
print_run_report,
|
14
13
|
run_solutions,
|
15
14
|
)
|
15
|
+
from rbx.box.testcase_extractors import extract_generation_testcases_from_groups
|
16
16
|
from rbx.box.validators import (
|
17
17
|
has_validation_errors,
|
18
18
|
print_validation_report,
|
@@ -50,7 +50,10 @@ def build(
|
|
50
50
|
'Validated [item]{processed}[/item] testcases...',
|
51
51
|
keep=True,
|
52
52
|
) as s:
|
53
|
-
infos = validate_testcases(
|
53
|
+
infos = validate_testcases(
|
54
|
+
s,
|
55
|
+
groups=groups,
|
56
|
+
)
|
54
57
|
print_validation_report(infos)
|
55
58
|
|
56
59
|
if has_validation_errors(infos):
|
@@ -3,7 +3,7 @@ from typing import Annotated, List, Optional
|
|
3
3
|
import typer
|
4
4
|
|
5
5
|
from rbx import annotations, console
|
6
|
-
from rbx.box import
|
6
|
+
from rbx.box import cd, environment, package
|
7
7
|
from rbx.box.contest.build_contest_statements import build_statement
|
8
8
|
from rbx.box.contest.contest_package import (
|
9
9
|
find_contest_package_or_die,
|
@@ -44,6 +44,8 @@ def build(
|
|
44
44
|
contest = find_contest_package_or_die()
|
45
45
|
# At most run the validators, only in samples.
|
46
46
|
if samples:
|
47
|
+
from rbx.box import builder
|
48
|
+
|
47
49
|
for problem in contest.problems:
|
48
50
|
console.console.print(
|
49
51
|
f'Processing problem [item]{problem.short_name}[/item]...'
|
@@ -1,12 +1,8 @@
|
|
1
|
-
import abc
|
2
1
|
import pathlib
|
3
|
-
import shlex
|
4
2
|
import shutil
|
5
|
-
from
|
6
|
-
from typing import Dict, Iterable, List, Optional, Set, Tuple
|
3
|
+
from typing import Dict, List, Optional, Set
|
7
4
|
|
8
5
|
import typer
|
9
|
-
from pydantic import BaseModel
|
10
6
|
|
11
7
|
from rbx import console
|
12
8
|
from rbx.box import checkers, package, testcase_utils, validators
|
@@ -19,10 +15,19 @@ from rbx.box.schema import (
|
|
19
15
|
CodeItem,
|
20
16
|
GeneratorCall,
|
21
17
|
Testcase,
|
22
|
-
TestcaseSubgroup,
|
23
18
|
)
|
24
|
-
from rbx.box.
|
25
|
-
|
19
|
+
from rbx.box.testcase_extractors import (
|
20
|
+
GenerationMetadata,
|
21
|
+
GenerationTestcaseEntry,
|
22
|
+
TestcaseGroupVisitor,
|
23
|
+
extract_generation_testcases,
|
24
|
+
run_testcase_visitor,
|
25
|
+
)
|
26
|
+
from rbx.box.testcase_utils import (
|
27
|
+
TestcaseEntry,
|
28
|
+
fill_output_for_defined_testcase,
|
29
|
+
find_built_testcases,
|
30
|
+
)
|
26
31
|
from rbx.grading.steps import (
|
27
32
|
DigestHolder,
|
28
33
|
DigestOrDest,
|
@@ -35,33 +40,11 @@ def _compile_generator(generator: CodeItem) -> str:
|
|
35
40
|
return compile_item(generator, sanitized=SanitizationLevel.PREFER)
|
36
41
|
|
37
42
|
|
38
|
-
def _get_group_input(
|
39
|
-
group_path: pathlib.Path, subgroup_prefix: str, i: int
|
40
|
-
) -> pathlib.Path:
|
41
|
-
return group_path / f'{subgroup_prefix}{i:03d}.in'
|
42
|
-
|
43
|
-
|
44
|
-
def _get_group_output(
|
45
|
-
group_path: pathlib.Path, subgroup_prefix: str, i: int
|
46
|
-
) -> pathlib.Path:
|
47
|
-
return group_path / f'{subgroup_prefix}{i:03d}.out'
|
48
|
-
|
49
|
-
|
50
|
-
def _fill_output_for_defined_testcase(testcase: Testcase) -> Testcase:
|
51
|
-
res = testcase.model_copy()
|
52
|
-
if res.outputPath is not None:
|
53
|
-
return res
|
54
|
-
output_path = res.inputPath.with_suffix('.ans')
|
55
|
-
if output_path.is_file():
|
56
|
-
res.outputPath = output_path
|
57
|
-
return res
|
58
|
-
|
59
|
-
|
60
43
|
def _copy_testcase_over(
|
61
44
|
testcase: Testcase,
|
62
45
|
dest: Testcase,
|
63
46
|
):
|
64
|
-
testcase =
|
47
|
+
testcase = fill_output_for_defined_testcase(testcase)
|
65
48
|
dest.inputPath.parent.mkdir(parents=True, exist_ok=True)
|
66
49
|
shutil.copy(
|
67
50
|
str(testcase.inputPath),
|
@@ -90,230 +73,6 @@ def get_call_from_string(call_str: str) -> GeneratorCall:
|
|
90
73
|
return GeneratorCall(name=name, args=args)
|
91
74
|
|
92
75
|
|
93
|
-
def _run_generator_script(testcase: TestcaseSubgroup) -> str:
|
94
|
-
assert testcase.generatorScript is not None
|
95
|
-
|
96
|
-
cacher = package.get_file_cacher()
|
97
|
-
|
98
|
-
if not testcase.generatorScript.path.is_file():
|
99
|
-
console.console.print(
|
100
|
-
f'[error]Generator script not found: [item]{testcase.generatorScript.path}[/item][/error]'
|
101
|
-
)
|
102
|
-
raise typer.Exit(1)
|
103
|
-
|
104
|
-
script_digest = DigestHolder()
|
105
|
-
if testcase.generatorScript.path.suffix == '.txt':
|
106
|
-
script_digest.value = cacher.put_file_from_path(testcase.generatorScript.path)
|
107
|
-
else:
|
108
|
-
try:
|
109
|
-
compiled_digest = compile_item(testcase.generatorScript)
|
110
|
-
except:
|
111
|
-
console.console.print(
|
112
|
-
f'[error]Failed compiling generator script for group [item]{testcase.name}[/item].[/error]'
|
113
|
-
)
|
114
|
-
raise
|
115
|
-
|
116
|
-
run_stderr = DigestHolder()
|
117
|
-
run_log = run_item(
|
118
|
-
testcase.generatorScript,
|
119
|
-
DigestOrSource.create(compiled_digest),
|
120
|
-
stdout=DigestOrDest.create(script_digest),
|
121
|
-
stderr=DigestOrDest.create(run_stderr),
|
122
|
-
)
|
123
|
-
|
124
|
-
if run_log is None or run_log.exitcode != 0:
|
125
|
-
console.console.print(
|
126
|
-
f'Could not run generator script for group {testcase.name}'
|
127
|
-
)
|
128
|
-
if run_log is not None:
|
129
|
-
console.console.print(
|
130
|
-
f'[error]Summary:[/error] {run_log.get_summary()}'
|
131
|
-
)
|
132
|
-
if run_stderr.value is not None:
|
133
|
-
console.console.print('[error]Stderr:[/error]')
|
134
|
-
console.console.print(
|
135
|
-
package.get_digest_as_string(run_stderr.value) or ''
|
136
|
-
)
|
137
|
-
raise typer.Exit(1)
|
138
|
-
|
139
|
-
assert script_digest.value
|
140
|
-
script = cacher.get_file_content(script_digest.value).decode()
|
141
|
-
return script
|
142
|
-
|
143
|
-
|
144
|
-
def _extract_script_lines(script: str) -> Iterable[Tuple[str, str, int]]:
|
145
|
-
lines = script.splitlines()
|
146
|
-
for i, line in enumerate(lines):
|
147
|
-
line = line.strip()
|
148
|
-
if not line:
|
149
|
-
continue
|
150
|
-
if line.startswith('#'):
|
151
|
-
continue
|
152
|
-
yield shlex.split(line)[0], shlex.join(shlex.split(line)[1:]), i + 1
|
153
|
-
|
154
|
-
|
155
|
-
class GeneratorScriptEntry(BaseModel):
|
156
|
-
path: pathlib.Path
|
157
|
-
line: int
|
158
|
-
|
159
|
-
|
160
|
-
class GenerationMetadata(BaseModel):
|
161
|
-
copied_to: Testcase
|
162
|
-
|
163
|
-
copied_from: Optional[Testcase] = None
|
164
|
-
generator_call: Optional[GeneratorCall] = None
|
165
|
-
generator_script: Optional[GeneratorScriptEntry] = None
|
166
|
-
|
167
|
-
|
168
|
-
class GenerationTestcaseEntry(BaseModel):
|
169
|
-
group_entry: TestcaseEntry
|
170
|
-
subgroup_entry: TestcaseEntry
|
171
|
-
|
172
|
-
metadata: GenerationMetadata
|
173
|
-
|
174
|
-
|
175
|
-
class TestcaseVisitor(abc.ABC):
|
176
|
-
@abc.abstractmethod
|
177
|
-
def visit(self, entry: GenerationTestcaseEntry):
|
178
|
-
pass
|
179
|
-
|
180
|
-
def should_visit_group(self, group_name: str) -> bool:
|
181
|
-
return True
|
182
|
-
|
183
|
-
def should_visit_subgroup(self, subgroup_path: str) -> bool:
|
184
|
-
return True
|
185
|
-
|
186
|
-
def should_visit_generator_scripts(
|
187
|
-
self, group_name: str, subgroup_path: str
|
188
|
-
) -> bool:
|
189
|
-
return True
|
190
|
-
|
191
|
-
|
192
|
-
class TestcaseGroupVisitor(TestcaseVisitor):
|
193
|
-
def __init__(self, groups: Optional[Set[str]] = None):
|
194
|
-
self.groups = groups
|
195
|
-
|
196
|
-
def should_visit_group(self, group_name: str) -> bool:
|
197
|
-
return self.groups is None or group_name in self.groups
|
198
|
-
|
199
|
-
|
200
|
-
def run_testcase_visitor(visitor: TestcaseVisitor):
|
201
|
-
pkg = package.find_problem_package_or_die()
|
202
|
-
|
203
|
-
def _explore_subgroup(
|
204
|
-
subgroup: TestcaseSubgroup, subgroup_index: Optional[int], prefix: List[str]
|
205
|
-
):
|
206
|
-
assert prefix and len(prefix) >= 1 and len(prefix) <= 2
|
207
|
-
group_path = prefix[0]
|
208
|
-
subgroup_path = '/'.join(prefix)
|
209
|
-
if not visitor.should_visit_subgroup(subgroup_path):
|
210
|
-
return
|
211
|
-
|
212
|
-
def _entry(i: int) -> TestcaseEntry:
|
213
|
-
return TestcaseEntry(group=group_path, index=i)
|
214
|
-
|
215
|
-
def _sub_entry(i: int) -> TestcaseEntry:
|
216
|
-
return TestcaseEntry(group=subgroup_path, index=i)
|
217
|
-
|
218
|
-
def _copied_to(i: int) -> Testcase:
|
219
|
-
group_fs_path = package.get_build_testgroup_path(group_path)
|
220
|
-
group_prefix = ''
|
221
|
-
if subgroup_index is not None:
|
222
|
-
group_prefix = f'{subgroup_index}-'
|
223
|
-
if len(prefix) == 2:
|
224
|
-
group_prefix += f'{prefix[1]}-'
|
225
|
-
return Testcase(
|
226
|
-
inputPath=_get_group_input(group_fs_path, group_prefix, i),
|
227
|
-
outputPath=_get_group_output(group_fs_path, group_prefix, i),
|
228
|
-
)
|
229
|
-
|
230
|
-
# Go through testcases.
|
231
|
-
i = 0
|
232
|
-
# Individual testcases.
|
233
|
-
for tc in subgroup.testcases or []:
|
234
|
-
visitor.visit(
|
235
|
-
GenerationTestcaseEntry(
|
236
|
-
group_entry=_entry(i),
|
237
|
-
subgroup_entry=_sub_entry(i),
|
238
|
-
metadata=GenerationMetadata(
|
239
|
-
copied_from=_fill_output_for_defined_testcase(tc),
|
240
|
-
copied_to=_copied_to(i),
|
241
|
-
),
|
242
|
-
)
|
243
|
-
)
|
244
|
-
i += 1
|
245
|
-
|
246
|
-
# Glob testcases.
|
247
|
-
if subgroup.testcaseGlob:
|
248
|
-
matched_inputs = sorted(PosixPath().glob(subgroup.testcaseGlob))
|
249
|
-
|
250
|
-
for input_path in matched_inputs:
|
251
|
-
if not input_path.is_file() or input_path.suffix != '.in':
|
252
|
-
continue
|
253
|
-
|
254
|
-
tc = Testcase(inputPath=input_path)
|
255
|
-
visitor.visit(
|
256
|
-
GenerationTestcaseEntry(
|
257
|
-
group_entry=_entry(i),
|
258
|
-
subgroup_entry=_sub_entry(i),
|
259
|
-
metadata=GenerationMetadata(
|
260
|
-
copied_from=_fill_output_for_defined_testcase(tc),
|
261
|
-
copied_to=_copied_to(i),
|
262
|
-
),
|
263
|
-
)
|
264
|
-
)
|
265
|
-
i += 1
|
266
|
-
|
267
|
-
# Single generators.
|
268
|
-
for generator_call in subgroup.generators:
|
269
|
-
visitor.visit(
|
270
|
-
GenerationTestcaseEntry(
|
271
|
-
group_entry=_entry(i),
|
272
|
-
subgroup_entry=_sub_entry(i),
|
273
|
-
metadata=GenerationMetadata(
|
274
|
-
generator_call=generator_call,
|
275
|
-
copied_to=_copied_to(i),
|
276
|
-
),
|
277
|
-
)
|
278
|
-
)
|
279
|
-
i += 1
|
280
|
-
|
281
|
-
if not visitor.should_visit_generator_scripts(group_path, subgroup_path):
|
282
|
-
return
|
283
|
-
|
284
|
-
# Run generator script.
|
285
|
-
if subgroup.generatorScript is not None:
|
286
|
-
script = _run_generator_script(subgroup)
|
287
|
-
|
288
|
-
# Run each line from generator script.
|
289
|
-
for generator_name, args, line_number in _extract_script_lines(script):
|
290
|
-
call = GeneratorCall(name=generator_name, args=args)
|
291
|
-
visitor.visit(
|
292
|
-
GenerationTestcaseEntry(
|
293
|
-
group_entry=_entry(i),
|
294
|
-
subgroup_entry=_sub_entry(i),
|
295
|
-
metadata=GenerationMetadata(
|
296
|
-
generator_call=call,
|
297
|
-
generator_script=GeneratorScriptEntry(
|
298
|
-
path=subgroup.generatorScript.path,
|
299
|
-
line=line_number,
|
300
|
-
),
|
301
|
-
copied_to=_copied_to(i),
|
302
|
-
),
|
303
|
-
)
|
304
|
-
)
|
305
|
-
i += 1
|
306
|
-
|
307
|
-
for group in pkg.testcases:
|
308
|
-
if not visitor.should_visit_group(group.name):
|
309
|
-
continue
|
310
|
-
|
311
|
-
_explore_subgroup(group, 0 if group.subgroups else None, [group.name])
|
312
|
-
|
313
|
-
for i, subgroup in enumerate(group.subgroups):
|
314
|
-
_explore_subgroup(subgroup, i + 1, [group.name, subgroup.name])
|
315
|
-
|
316
|
-
|
317
76
|
def _get_necessary_generators_for_groups(
|
318
77
|
groups: Optional[Set[str]] = None,
|
319
78
|
) -> Set[str]:
|
@@ -359,6 +118,8 @@ def compile_generators(
|
|
359
118
|
|
360
119
|
|
361
120
|
def expand_generator_call(call: GeneratorCall) -> GeneratorCall:
|
121
|
+
from rbx.box.stressing import generator_parser
|
122
|
+
|
362
123
|
vars = package.find_problem_package_or_die().expanded_vars
|
363
124
|
generator_for_args = generator_parser.Generator(vars)
|
364
125
|
parsed_args = generator_parser.parse(call.args or '')
|
@@ -439,14 +200,14 @@ def generate_standalone(
|
|
439
200
|
_, validator_digest = validator_tp
|
440
201
|
if progress:
|
441
202
|
progress.update('Validating test...')
|
442
|
-
|
203
|
+
validation_info = validators.validate_one_off(
|
443
204
|
spec.copied_to.inputPath,
|
444
205
|
validator,
|
445
206
|
validator_digest,
|
446
207
|
)
|
447
|
-
if not ok:
|
208
|
+
if not validation_info.ok:
|
448
209
|
_print_error_header('failed validating testcase.')
|
449
|
-
console.console.print(f'[error]Message:[/error] {message}')
|
210
|
+
console.console.print(f'[error]Message:[/error] {validation_info.message}')
|
450
211
|
console.console.print(
|
451
212
|
f'Testcase written at [item]{spec.copied_to.inputPath}[/item]'
|
452
213
|
)
|
@@ -552,67 +313,6 @@ def generate_output_for_testcase(
|
|
552
313
|
raise typer.Exit(1)
|
553
314
|
|
554
315
|
|
555
|
-
def extract_generation_testcases(
|
556
|
-
entries: List[TestcaseEntry],
|
557
|
-
) -> List[GenerationTestcaseEntry]:
|
558
|
-
# TODO: support subgroups.
|
559
|
-
groups = set(entry.group for entry in entries)
|
560
|
-
entry_keys = set(entry.key() for entry in entries)
|
561
|
-
|
562
|
-
res: List[GenerationTestcaseEntry] = []
|
563
|
-
|
564
|
-
class ExtractGenerationTestcasesVisitor(TestcaseVisitor):
|
565
|
-
def should_visit_group(self, group_name: str) -> bool:
|
566
|
-
return group_name in groups
|
567
|
-
|
568
|
-
def visit(self, entry: GenerationTestcaseEntry):
|
569
|
-
# TODO: support subgroups.
|
570
|
-
if entry.group_entry.key() not in entry_keys:
|
571
|
-
return
|
572
|
-
res.append(entry)
|
573
|
-
|
574
|
-
run_testcase_visitor(ExtractGenerationTestcasesVisitor())
|
575
|
-
return res
|
576
|
-
|
577
|
-
|
578
|
-
def extract_generation_testcases_from_groups(
|
579
|
-
groups: Optional[Set[str]] = None,
|
580
|
-
) -> List[GenerationTestcaseEntry]:
|
581
|
-
res: List[GenerationTestcaseEntry] = []
|
582
|
-
|
583
|
-
class ExtractGenerationTestcasesVisitor(TestcaseGroupVisitor):
|
584
|
-
def visit(self, entry: GenerationTestcaseEntry):
|
585
|
-
res.append(entry)
|
586
|
-
|
587
|
-
run_testcase_visitor(ExtractGenerationTestcasesVisitor(groups))
|
588
|
-
return res
|
589
|
-
|
590
|
-
|
591
|
-
def extract_generation_testcases_from_patterns(
|
592
|
-
patterns: List[TestcasePattern],
|
593
|
-
) -> List[GenerationTestcaseEntry]:
|
594
|
-
res: List[GenerationTestcaseEntry] = []
|
595
|
-
|
596
|
-
class ExtractGenerationTestcasesVisitor(TestcaseVisitor):
|
597
|
-
def should_visit_group(self, group_name: str) -> bool:
|
598
|
-
return any(pattern.intersecting_group(group_name) for pattern in patterns)
|
599
|
-
|
600
|
-
def should_visit_subgroup(self, subgroup_path: str) -> bool:
|
601
|
-
return any(
|
602
|
-
pattern.intersecting_group(subgroup_path) for pattern in patterns
|
603
|
-
)
|
604
|
-
|
605
|
-
def visit(self, entry: GenerationTestcaseEntry):
|
606
|
-
if not any(
|
607
|
-
pattern.match(entry.group_entry) for pattern in patterns
|
608
|
-
) and not any(pattern.match(entry.subgroup_entry) for pattern in patterns):
|
609
|
-
return
|
610
|
-
res.append(entry)
|
611
|
-
|
612
|
-
run_testcase_visitor(ExtractGenerationTestcasesVisitor())
|
613
|
-
return res
|
614
|
-
|
615
|
-
|
616
316
|
def generate_outputs_for_testcases(
|
617
317
|
entries: List[TestcaseEntry],
|
618
318
|
progress: Optional[StatusProgress] = None,
|
@@ -4,10 +4,10 @@ import pytest
|
|
4
4
|
|
5
5
|
from rbx.box import package
|
6
6
|
from rbx.box.generators import (
|
7
|
-
extract_generation_testcases_from_groups,
|
8
7
|
generate_outputs_for_testcases,
|
9
8
|
generate_testcases,
|
10
9
|
)
|
10
|
+
from rbx.box.testcase_extractors import extract_generation_testcases_from_groups
|
11
11
|
from rbx.testing_utils import print_directory_tree
|
12
12
|
|
13
13
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import subprocess
|
2
|
+
import sys
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
LAZY_MODULES = {
|
6
|
+
'gitpython',
|
7
|
+
'questionary',
|
8
|
+
'fastapi',
|
9
|
+
'requests',
|
10
|
+
'pydantic_xml',
|
11
|
+
'rbx.box.packaging.polygon.packager',
|
12
|
+
'rbx.box.stresses',
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
def test_rich_not_imported_unnecessary():
|
17
|
+
file_path = Path(__file__).parent / 'lazy_importing_main.py'
|
18
|
+
result = subprocess.run(
|
19
|
+
[sys.executable, '-m', 'coverage', 'run', str(file_path)],
|
20
|
+
capture_output=True,
|
21
|
+
encoding='utf-8',
|
22
|
+
)
|
23
|
+
modules = result.stdout.splitlines()
|
24
|
+
modules = [module for module in modules if module in LAZY_MODULES]
|
25
|
+
assert not modules
|
@@ -18,11 +18,9 @@ from typing import Annotated, List, Optional
|
|
18
18
|
import rich
|
19
19
|
import rich.prompt
|
20
20
|
import typer
|
21
|
-
import questionary
|
22
21
|
|
23
22
|
from rbx import annotations, config, console, utils
|
24
23
|
from rbx.box import (
|
25
|
-
builder,
|
26
24
|
cd,
|
27
25
|
setter_config,
|
28
26
|
state,
|
@@ -33,7 +31,6 @@ from rbx.box import (
|
|
33
31
|
package,
|
34
32
|
compile,
|
35
33
|
presets,
|
36
|
-
stresses,
|
37
34
|
validators,
|
38
35
|
)
|
39
36
|
from rbx.box.contest import main as contest
|
@@ -116,6 +113,8 @@ def edit():
|
|
116
113
|
@app.command('build, b', help='Build all tests for the problem.')
|
117
114
|
@package.within_problem
|
118
115
|
def build(verification: environment.VerificationParam):
|
116
|
+
from rbx.box import builder
|
117
|
+
|
119
118
|
builder.build(verification=verification)
|
120
119
|
|
121
120
|
|
@@ -189,6 +188,8 @@ def run(
|
|
189
188
|
console.console.print('[error]No solutions selected. Exiting.[/error]')
|
190
189
|
raise typer.Exit(1)
|
191
190
|
|
191
|
+
from rbx.box import builder
|
192
|
+
|
192
193
|
if not builder.build(verification=verification, output=check):
|
193
194
|
return
|
194
195
|
|
@@ -322,6 +323,8 @@ def time(
|
|
322
323
|
)
|
323
324
|
check = False
|
324
325
|
|
326
|
+
from rbx.box import builder
|
327
|
+
|
325
328
|
verification = VerificationLevel.ALL_SOLUTIONS.value
|
326
329
|
if not builder.build(verification=verification, output=check):
|
327
330
|
return None
|
@@ -522,6 +525,8 @@ def stress(
|
|
522
525
|
)
|
523
526
|
raise typer.Exit(1)
|
524
527
|
|
528
|
+
from rbx.box import stresses
|
529
|
+
|
525
530
|
with utils.StatusProgress('Running stress...') as s:
|
526
531
|
report = stresses.run_stress(
|
527
532
|
name,
|
@@ -555,6 +560,8 @@ def stress(
|
|
555
560
|
and group.generatorScript.path.suffix == '.txt'
|
556
561
|
}
|
557
562
|
|
563
|
+
import questionary
|
564
|
+
|
558
565
|
testgroup = questionary.select(
|
559
566
|
'Choose the testgroup to add the tests to.\nOnly test groups that have a .txt generatorScript are shown below: ',
|
560
567
|
choices=list(groups_by_name) + ['(create new script)', '(skip)'],
|
@@ -635,6 +642,8 @@ def compile_command(
|
|
635
642
|
),
|
636
643
|
):
|
637
644
|
if path is None:
|
645
|
+
import questionary
|
646
|
+
|
638
647
|
path = questionary.path("What's the path to your asset?").ask()
|
639
648
|
if path is None:
|
640
649
|
console.console.print('[error]No path specified.[/error]')
|
@@ -14,7 +14,6 @@ from rbx.box.packaging.packager import (
|
|
14
14
|
BuiltContestStatement,
|
15
15
|
BuiltProblemPackage,
|
16
16
|
)
|
17
|
-
from rbx.box.packaging.polygon.packager import PolygonContestPackager, PolygonPackager
|
18
17
|
|
19
18
|
app = typer.Typer(no_args_is_help=True, cls=annotations.AliasGroup)
|
20
19
|
|
@@ -77,6 +76,11 @@ def run_contest_packager(
|
|
77
76
|
def polygon(
|
78
77
|
verification: environment.VerificationParam,
|
79
78
|
):
|
79
|
+
from rbx.box.packaging.polygon.packager import (
|
80
|
+
PolygonContestPackager,
|
81
|
+
PolygonPackager,
|
82
|
+
)
|
83
|
+
|
80
84
|
run_contest_packager(
|
81
85
|
PolygonContestPackager, PolygonPackager, verification=verification
|
82
86
|
)
|
@@ -5,11 +5,9 @@ from typing import Type
|
|
5
5
|
import typer
|
6
6
|
|
7
7
|
from rbx import annotations, console
|
8
|
-
from rbx.box import
|
8
|
+
from rbx.box import environment, package
|
9
9
|
from rbx.box.package import get_build_path
|
10
|
-
from rbx.box.packaging.boca.packager import BocaPackager
|
11
10
|
from rbx.box.packaging.packager import BasePackager, BuiltStatement
|
12
|
-
from rbx.box.packaging.polygon.packager import PolygonPackager
|
13
11
|
from rbx.box.statements.build_statements import build_statement
|
14
12
|
|
15
13
|
app = typer.Typer(no_args_is_help=True, cls=annotations.AliasGroup)
|
@@ -19,6 +17,8 @@ def run_packager(
|
|
19
17
|
packager_cls: Type[BasePackager],
|
20
18
|
verification: environment.VerificationParam,
|
21
19
|
) -> pathlib.Path:
|
20
|
+
from rbx.box import builder
|
21
|
+
|
22
22
|
if not builder.verify(verification=verification):
|
23
23
|
console.console.print(
|
24
24
|
'[error]Build or verification failed, check the report.[/error]'
|
@@ -58,6 +58,8 @@ def run_packager(
|
|
58
58
|
def polygon(
|
59
59
|
verification: environment.VerificationParam,
|
60
60
|
):
|
61
|
+
from rbx.box.packaging.polygon.packager import PolygonPackager
|
62
|
+
|
61
63
|
run_packager(PolygonPackager, verification=verification)
|
62
64
|
|
63
65
|
|
@@ -65,4 +67,6 @@ def polygon(
|
|
65
67
|
def boca(
|
66
68
|
verification: environment.VerificationParam,
|
67
69
|
):
|
70
|
+
from rbx.box.packaging.boca.packager import BocaPackager
|
71
|
+
|
68
72
|
run_packager(BocaPackager, verification=verification)
|
@@ -3,8 +3,6 @@ import shutil
|
|
3
3
|
import tempfile
|
4
4
|
from typing import Annotated, Iterable, List, Optional, Sequence, Union
|
5
5
|
|
6
|
-
import git
|
7
|
-
import questionary
|
8
6
|
import rich
|
9
7
|
import rich.prompt
|
10
8
|
import typer
|
@@ -306,6 +304,8 @@ def optionally_install_environment_from_preset(
|
|
306
304
|
if env_path.is_file():
|
307
305
|
if digest_file(preset_env_path) == digest_file(env_path):
|
308
306
|
return
|
307
|
+
import questionary
|
308
|
+
|
309
309
|
overwrite = questionary.confirm(
|
310
310
|
'Preset environment file has changed. Overwrite?',
|
311
311
|
default=False,
|
@@ -371,6 +371,8 @@ def _install(root: pathlib.Path = pathlib.Path(), force: bool = False):
|
|
371
371
|
|
372
372
|
|
373
373
|
def install_from_remote(fetch_info: PresetFetchInfo, force: bool = False) -> str:
|
374
|
+
import git
|
375
|
+
|
374
376
|
assert fetch_info.fetch_uri is not None
|
375
377
|
with tempfile.TemporaryDirectory() as d:
|
376
378
|
console.console.print(
|
@@ -484,6 +486,8 @@ def update(
|
|
484
486
|
|
485
487
|
for preset_name in presets:
|
486
488
|
if preset_name == LOCAL:
|
489
|
+
import questionary
|
490
|
+
|
487
491
|
if not questionary.confirm(
|
488
492
|
'Updating local preset will remove all custom changes you made to the preset.',
|
489
493
|
default=False,
|