rbx.cp 0.5.0__py3-none-any.whl
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/__init__.py +0 -0
- rbx/annotations.py +127 -0
- rbx/autoenum.py +333 -0
- rbx/box/__init__.py +0 -0
- rbx/box/builder.py +77 -0
- rbx/box/cd.py +37 -0
- rbx/box/checkers.py +134 -0
- rbx/box/code.py +185 -0
- rbx/box/compile.py +56 -0
- rbx/box/conftest.py +42 -0
- rbx/box/contest/__init__.py +0 -0
- rbx/box/contest/build_contest_statements.py +347 -0
- rbx/box/contest/contest_package.py +76 -0
- rbx/box/contest/contest_utils.py +20 -0
- rbx/box/contest/main.py +179 -0
- rbx/box/contest/schema.py +155 -0
- rbx/box/contest/statements.py +82 -0
- rbx/box/creation.py +72 -0
- rbx/box/download.py +64 -0
- rbx/box/environment.py +345 -0
- rbx/box/extensions.py +26 -0
- rbx/box/generators.py +478 -0
- rbx/box/generators_test.py +63 -0
- rbx/box/main.py +449 -0
- rbx/box/package.py +316 -0
- rbx/box/packaging/boca/extension.py +27 -0
- rbx/box/packaging/boca/packager.py +245 -0
- rbx/box/packaging/contest_main.py +82 -0
- rbx/box/packaging/main.py +68 -0
- rbx/box/packaging/packager.py +117 -0
- rbx/box/packaging/polygon/packager.py +320 -0
- rbx/box/packaging/polygon/test.py +81 -0
- rbx/box/packaging/polygon/xml_schema.py +106 -0
- rbx/box/presets/__init__.py +503 -0
- rbx/box/presets/fetch.py +70 -0
- rbx/box/presets/lock_schema.py +20 -0
- rbx/box/presets/schema.py +59 -0
- rbx/box/schema.py +394 -0
- rbx/box/solutions.py +792 -0
- rbx/box/solutions_test.py +41 -0
- rbx/box/statements/__init__.py +0 -0
- rbx/box/statements/build_statements.py +359 -0
- rbx/box/statements/builders.py +375 -0
- rbx/box/statements/joiners.py +113 -0
- rbx/box/statements/latex.py +47 -0
- rbx/box/statements/latex_jinja.py +214 -0
- rbx/box/statements/schema.py +138 -0
- rbx/box/stresses.py +292 -0
- rbx/box/stressing/__init__.py +0 -0
- rbx/box/stressing/finder_parser.py +359 -0
- rbx/box/stressing/generator_parser.py +258 -0
- rbx/box/testcases.py +54 -0
- rbx/box/ui/__init__.py +0 -0
- rbx/box/ui/captured_log.py +372 -0
- rbx/box/ui/css/app.tcss +48 -0
- rbx/box/ui/main.py +38 -0
- rbx/box/ui/run.py +209 -0
- rbx/box/validators.py +245 -0
- rbx/box/validators_test.py +15 -0
- rbx/checker.py +128 -0
- rbx/clone.py +197 -0
- rbx/config.py +271 -0
- rbx/conftest.py +38 -0
- rbx/console.py +27 -0
- rbx/create.py +37 -0
- rbx/edit.py +24 -0
- rbx/grading/__init__.py +0 -0
- rbx/grading/caching.py +356 -0
- rbx/grading/conftest.py +33 -0
- rbx/grading/judge/__init__.py +0 -0
- rbx/grading/judge/cacher.py +503 -0
- rbx/grading/judge/digester.py +35 -0
- rbx/grading/judge/sandbox.py +748 -0
- rbx/grading/judge/sandboxes/__init__.py +0 -0
- rbx/grading/judge/sandboxes/isolate.py +683 -0
- rbx/grading/judge/sandboxes/stupid_sandbox.py +310 -0
- rbx/grading/judge/sandboxes/timeit.py +217 -0
- rbx/grading/judge/storage.py +284 -0
- rbx/grading/judge/test.py +38 -0
- rbx/grading/judge/testiso.py +54 -0
- rbx/grading/steps.py +522 -0
- rbx/grading/steps_with_caching.py +59 -0
- rbx/grading/steps_with_caching_run_test.py +429 -0
- rbx/grading_utils.py +148 -0
- rbx/hydration.py +101 -0
- rbx/main.py +122 -0
- rbx/metadata.py +105 -0
- rbx/providers/__init__.py +43 -0
- rbx/providers/codeforces.py +73 -0
- rbx/providers/provider.py +26 -0
- rbx/resources/checkers/boilerplate.cpp +20 -0
- rbx/resources/default_config.json +48 -0
- rbx/resources/envs/default.rbx.yml +37 -0
- rbx/resources/envs/isolate.rbx.yml +37 -0
- rbx/resources/packagers/boca/checker.sh +43 -0
- rbx/resources/packagers/boca/compare +53 -0
- rbx/resources/packagers/boca/compile/c +172 -0
- rbx/resources/packagers/boca/compile/cc +173 -0
- rbx/resources/packagers/boca/compile/cpp +172 -0
- rbx/resources/packagers/boca/compile/java +194 -0
- rbx/resources/packagers/boca/compile/kt +155 -0
- rbx/resources/packagers/boca/compile/pas +172 -0
- rbx/resources/packagers/boca/compile/py2 +173 -0
- rbx/resources/packagers/boca/compile/py3 +173 -0
- rbx/resources/packagers/boca/run/c +128 -0
- rbx/resources/packagers/boca/run/cc +128 -0
- rbx/resources/packagers/boca/run/cpp +128 -0
- rbx/resources/packagers/boca/run/java +194 -0
- rbx/resources/packagers/boca/run/kt +159 -0
- rbx/resources/packagers/boca/run/py2 +166 -0
- rbx/resources/packagers/boca/run/py3 +166 -0
- rbx/resources/presets/default/contest/contest.rbx.yml +14 -0
- rbx/resources/presets/default/contest/statement/contest.rbx.tex +97 -0
- rbx/resources/presets/default/contest/statement/olymp.sty +250 -0
- rbx/resources/presets/default/contest/statement/template.rbx.tex +42 -0
- rbx/resources/presets/default/preset.rbx.yml +12 -0
- rbx/resources/presets/default/problem/.gitignore +6 -0
- rbx/resources/presets/default/problem/gen.cpp +9 -0
- rbx/resources/presets/default/problem/problem.rbx.yml +44 -0
- rbx/resources/presets/default/problem/random.py +3 -0
- rbx/resources/presets/default/problem/random.txt +2 -0
- rbx/resources/presets/default/problem/sols/main.cpp +9 -0
- rbx/resources/presets/default/problem/sols/slow.cpp +15 -0
- rbx/resources/presets/default/problem/sols/wa.cpp +9 -0
- rbx/resources/presets/default/problem/statement/olymp.sty +250 -0
- rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- rbx/resources/presets/default/problem/statement/statement.rbx.tex +18 -0
- rbx/resources/presets/default/problem/statement/template.rbx.tex +89 -0
- rbx/resources/presets/default/problem/tests/samples/000.in +1 -0
- rbx/resources/presets/default/problem/tests/samples/001.in +1 -0
- rbx/resources/presets/default/problem/validator.cpp +16 -0
- rbx/resources/presets/default/problem/wcmp.cpp +34 -0
- rbx/resources/templates/template.cpp +19 -0
- rbx/run.py +45 -0
- rbx/schema.py +64 -0
- rbx/submit.py +61 -0
- rbx/submitors/__init__.py +18 -0
- rbx/submitors/codeforces.py +120 -0
- rbx/submitors/submitor.py +25 -0
- rbx/test.py +347 -0
- rbx/testcase.py +70 -0
- rbx/testcase_rendering.py +79 -0
- rbx/testdata/box1/gen1.cpp +7 -0
- rbx/testdata/box1/gen2.cpp +9 -0
- rbx/testdata/box1/genScript.py +2 -0
- rbx/testdata/box1/hard-tle.sol.cpp +26 -0
- rbx/testdata/box1/ole.cpp +17 -0
- rbx/testdata/box1/problem.rbx.yml +39 -0
- rbx/testdata/box1/re.sol.cpp +23 -0
- rbx/testdata/box1/sol.cpp +22 -0
- rbx/testdata/box1/tests/1.in +1 -0
- rbx/testdata/box1/tle-and-incorrect.sol.cpp +33 -0
- rbx/testdata/box1/tle.sol.cpp +35 -0
- rbx/testdata/box1/validator.cpp +11 -0
- rbx/testdata/box1/wa.sol.cpp +22 -0
- rbx/testdata/caching/executable.py +1 -0
- rbx/testdata/compatible +0 -0
- rbx/testing_utils.py +65 -0
- rbx/utils.py +162 -0
- rbx_cp-0.5.0.dist-info/LICENSE +201 -0
- rbx_cp-0.5.0.dist-info/METADATA +89 -0
- rbx_cp-0.5.0.dist-info/RECORD +164 -0
- rbx_cp-0.5.0.dist-info/WHEEL +4 -0
- rbx_cp-0.5.0.dist-info/entry_points.txt +4 -0
rbx/box/main.py
ADDED
@@ -0,0 +1,449 @@
|
|
1
|
+
# flake8: noqa
|
2
|
+
from gevent import monkey
|
3
|
+
|
4
|
+
monkey.patch_all()
|
5
|
+
|
6
|
+
import shlex
|
7
|
+
import sys
|
8
|
+
import typing
|
9
|
+
|
10
|
+
from rbx.box.schema import CodeItem, ExpectedOutcome
|
11
|
+
|
12
|
+
|
13
|
+
import pathlib
|
14
|
+
import shutil
|
15
|
+
from typing import Annotated, List, Optional
|
16
|
+
|
17
|
+
import rich
|
18
|
+
import rich.prompt
|
19
|
+
import typer
|
20
|
+
import questionary
|
21
|
+
|
22
|
+
from rbx import annotations, config, console, utils
|
23
|
+
from rbx.box import (
|
24
|
+
builder,
|
25
|
+
cd,
|
26
|
+
creation,
|
27
|
+
download,
|
28
|
+
environment,
|
29
|
+
generators,
|
30
|
+
package,
|
31
|
+
compile,
|
32
|
+
presets,
|
33
|
+
stresses,
|
34
|
+
)
|
35
|
+
from rbx.box.contest import main as contest
|
36
|
+
from rbx.box.environment import VerificationLevel, get_environment_path
|
37
|
+
from rbx.box.packaging import main as packaging
|
38
|
+
from rbx.box.solutions import (
|
39
|
+
get_matching_solutions,
|
40
|
+
print_run_report,
|
41
|
+
run_and_print_interactive_solutions,
|
42
|
+
run_solutions,
|
43
|
+
)
|
44
|
+
from rbx.box.statements import build_statements
|
45
|
+
from rbx.box.ui import main as ui_pkg
|
46
|
+
|
47
|
+
app = typer.Typer(no_args_is_help=True, cls=annotations.AliasGroup)
|
48
|
+
app.add_typer(
|
49
|
+
build_statements.app,
|
50
|
+
name='statements, st',
|
51
|
+
cls=annotations.AliasGroup,
|
52
|
+
help='Manage statements.',
|
53
|
+
)
|
54
|
+
app.add_typer(
|
55
|
+
download.app,
|
56
|
+
name='download',
|
57
|
+
cls=annotations.AliasGroup,
|
58
|
+
help='Download an asset from supported repositories.',
|
59
|
+
)
|
60
|
+
app.add_typer(
|
61
|
+
presets.app, name='presets', cls=annotations.AliasGroup, help='Manage presets.'
|
62
|
+
)
|
63
|
+
app.add_typer(
|
64
|
+
packaging.app,
|
65
|
+
name='package, pkg',
|
66
|
+
cls=annotations.AliasGroup,
|
67
|
+
help='Build problem packages.',
|
68
|
+
)
|
69
|
+
app.add_typer(
|
70
|
+
contest.app, name='contest', cls=annotations.AliasGroup, help='Contest management.'
|
71
|
+
)
|
72
|
+
app.add_typer(
|
73
|
+
compile.app, name='compile', cls=annotations.AliasGroup, help='Compile assets.'
|
74
|
+
)
|
75
|
+
|
76
|
+
|
77
|
+
@app.command('ui', hidden=True)
|
78
|
+
@package.within_problem
|
79
|
+
def ui():
|
80
|
+
ui_pkg.start()
|
81
|
+
|
82
|
+
|
83
|
+
@app.command('edit, e', help='Open problem.rbx.yml in your default editor.')
|
84
|
+
@package.within_problem
|
85
|
+
def edit():
|
86
|
+
console.console.print('Opening problem definition in editor...')
|
87
|
+
# Call this function just to raise exception in case we're no in
|
88
|
+
# a problem package.
|
89
|
+
package.find_problem()
|
90
|
+
config.open_editor(package.find_problem_yaml() or pathlib.Path())
|
91
|
+
|
92
|
+
|
93
|
+
@app.command('build, b', help='Build all tests for the problem.')
|
94
|
+
@package.within_problem
|
95
|
+
def build(verification: environment.VerificationParam):
|
96
|
+
builder.build(verification=verification)
|
97
|
+
|
98
|
+
|
99
|
+
@app.command('verify, v', help='Build and verify all the tests for the problem.')
|
100
|
+
@package.within_problem
|
101
|
+
def verify(verification: environment.VerificationParam):
|
102
|
+
if not builder.verify(verification=verification):
|
103
|
+
console.console.print('[error]Verification failed, check the report.[/error]')
|
104
|
+
|
105
|
+
|
106
|
+
@app.command('run, r', help='Build and run solution(s).')
|
107
|
+
@package.within_problem
|
108
|
+
def run(
|
109
|
+
verification: environment.VerificationParam,
|
110
|
+
solution: Annotated[
|
111
|
+
Optional[str],
|
112
|
+
typer.Argument(
|
113
|
+
help='Path to solution to run. If not specified, will run all solutions.'
|
114
|
+
),
|
115
|
+
] = None,
|
116
|
+
outcome: Optional[str] = typer.Option(
|
117
|
+
None,
|
118
|
+
'--outcome',
|
119
|
+
'-o',
|
120
|
+
help='Include only solutions whose expected outcomes intersect with this.',
|
121
|
+
),
|
122
|
+
check: bool = typer.Option(
|
123
|
+
True,
|
124
|
+
'--nocheck',
|
125
|
+
flag_value=False,
|
126
|
+
help='Whether to not build outputs for tests and run checker.',
|
127
|
+
),
|
128
|
+
detailed: bool = typer.Option(
|
129
|
+
False,
|
130
|
+
'--detailed',
|
131
|
+
'-d',
|
132
|
+
help='Whether to print a detailed view of the tests using tables.',
|
133
|
+
),
|
134
|
+
):
|
135
|
+
main_solution = package.get_main_solution()
|
136
|
+
if check and main_solution is None:
|
137
|
+
console.console.print(
|
138
|
+
'[warning]No main solution found, running without checkers.[/warning]'
|
139
|
+
)
|
140
|
+
check = False
|
141
|
+
|
142
|
+
builder.build(verification=verification, output=check)
|
143
|
+
|
144
|
+
with utils.StatusProgress('Running solutions...') as s:
|
145
|
+
tracked_solutions = None
|
146
|
+
if outcome is not None:
|
147
|
+
tracked_solutions = {
|
148
|
+
str(solution.path)
|
149
|
+
for solution in get_matching_solutions(ExpectedOutcome(outcome))
|
150
|
+
}
|
151
|
+
if solution:
|
152
|
+
tracked_solutions = {solution}
|
153
|
+
solution_result = run_solutions(
|
154
|
+
progress=s,
|
155
|
+
tracked_solutions=tracked_solutions,
|
156
|
+
check=check,
|
157
|
+
group_first=detailed,
|
158
|
+
verification=VerificationLevel(verification),
|
159
|
+
)
|
160
|
+
|
161
|
+
console.console.print()
|
162
|
+
console.console.rule('[status]Run report[/status]', style='status')
|
163
|
+
print_run_report(
|
164
|
+
solution_result,
|
165
|
+
console.console,
|
166
|
+
verification,
|
167
|
+
detailed=detailed,
|
168
|
+
)
|
169
|
+
|
170
|
+
|
171
|
+
@app.command(
|
172
|
+
'irun, ir', help='Build and run solution(s) by passing testcases in the CLI.'
|
173
|
+
)
|
174
|
+
@package.within_problem
|
175
|
+
def irun(
|
176
|
+
verification: environment.VerificationParam,
|
177
|
+
solution: Annotated[
|
178
|
+
Optional[str],
|
179
|
+
typer.Argument(
|
180
|
+
help='Path to solution to run. If not specified, will run all solutions.'
|
181
|
+
),
|
182
|
+
] = None,
|
183
|
+
outcome: Optional[str] = typer.Option(
|
184
|
+
None,
|
185
|
+
'--outcome',
|
186
|
+
'-o',
|
187
|
+
help='Include only solutions whose expected outcomes intersect with this.',
|
188
|
+
),
|
189
|
+
check: bool = typer.Option(
|
190
|
+
True,
|
191
|
+
'--nocheck',
|
192
|
+
flag_value=False,
|
193
|
+
help='Whether to not build outputs for tests and run checker.',
|
194
|
+
),
|
195
|
+
generator: Optional[str] = typer.Option(
|
196
|
+
None,
|
197
|
+
'--generator',
|
198
|
+
'-g',
|
199
|
+
help='Generator call to use to generate a single test for execution.',
|
200
|
+
),
|
201
|
+
print: bool = typer.Option(
|
202
|
+
False, '--print', '-p', help='Whether to print outputs to terminal.'
|
203
|
+
),
|
204
|
+
):
|
205
|
+
if not print:
|
206
|
+
console.console.print(
|
207
|
+
'[warning]Outputs will be written to files. If you wish to print them to the terminal, use the "-p" parameter.'
|
208
|
+
)
|
209
|
+
main_solution = package.get_main_solution()
|
210
|
+
if check and main_solution is None:
|
211
|
+
console.console.print(
|
212
|
+
'[warning]No main solution found, running without checkers.[/warning]'
|
213
|
+
)
|
214
|
+
check = False
|
215
|
+
|
216
|
+
tracked_solutions = None
|
217
|
+
if outcome is not None:
|
218
|
+
tracked_solutions = {
|
219
|
+
str(solution.path)
|
220
|
+
for solution in get_matching_solutions(ExpectedOutcome(outcome))
|
221
|
+
}
|
222
|
+
if solution:
|
223
|
+
tracked_solutions = {solution}
|
224
|
+
run_and_print_interactive_solutions(
|
225
|
+
tracked_solutions=tracked_solutions,
|
226
|
+
check=check,
|
227
|
+
verification=VerificationLevel(verification),
|
228
|
+
generator=generators.get_call_from_string(generator)
|
229
|
+
if generator is not None
|
230
|
+
else None,
|
231
|
+
print=print,
|
232
|
+
)
|
233
|
+
|
234
|
+
|
235
|
+
@app.command('create, c', help='Create a new problem package.')
|
236
|
+
@package.within_problem
|
237
|
+
def create(
|
238
|
+
name: str,
|
239
|
+
preset: Annotated[
|
240
|
+
Optional[str], typer.Option(help='Preset to use when creating the problem.')
|
241
|
+
] = None,
|
242
|
+
):
|
243
|
+
if preset is not None:
|
244
|
+
creation.create(name, preset=preset)
|
245
|
+
return
|
246
|
+
creation.create(name)
|
247
|
+
|
248
|
+
|
249
|
+
@app.command('stress', help='Run a stress test.')
|
250
|
+
@package.within_problem
|
251
|
+
def stress(
|
252
|
+
name: str,
|
253
|
+
generator_args: Annotated[
|
254
|
+
Optional[str],
|
255
|
+
typer.Option(
|
256
|
+
'--generator',
|
257
|
+
'-g',
|
258
|
+
help='Run generator [name] with these args.',
|
259
|
+
),
|
260
|
+
] = None,
|
261
|
+
finder: Annotated[
|
262
|
+
Optional[str],
|
263
|
+
typer.Option(
|
264
|
+
'--finder',
|
265
|
+
'-f',
|
266
|
+
help='Run a stress with this finder expression.',
|
267
|
+
),
|
268
|
+
] = None,
|
269
|
+
timeout: Annotated[
|
270
|
+
int, typer.Option(help='For how many seconds to run the stress test.')
|
271
|
+
] = 10,
|
272
|
+
findings: Annotated[
|
273
|
+
int, typer.Option(help='How many breaking tests to look for.')
|
274
|
+
] = 1,
|
275
|
+
verbose: bool = typer.Option(
|
276
|
+
False,
|
277
|
+
'-v',
|
278
|
+
'--verbose',
|
279
|
+
help='Whether to print verbose output for checkers and finders.',
|
280
|
+
),
|
281
|
+
):
|
282
|
+
if finder and not generator_args or generator_args and not finder:
|
283
|
+
console.console.print(
|
284
|
+
'[error]Options --generator/-g and --finder/-f should be specified together.'
|
285
|
+
)
|
286
|
+
raise typer.Exit(1)
|
287
|
+
|
288
|
+
with utils.StatusProgress('Running stress...') as s:
|
289
|
+
report = stresses.run_stress(
|
290
|
+
name,
|
291
|
+
timeout,
|
292
|
+
args=generator_args,
|
293
|
+
finder=finder,
|
294
|
+
findingsLimit=findings,
|
295
|
+
progress=s,
|
296
|
+
verbose=verbose,
|
297
|
+
)
|
298
|
+
|
299
|
+
stresses.print_stress_report(report)
|
300
|
+
|
301
|
+
if not report.findings:
|
302
|
+
return
|
303
|
+
|
304
|
+
# Add found tests.
|
305
|
+
res = rich.prompt.Confirm.ask(
|
306
|
+
'Do you want to add the tests that were found to a test group?',
|
307
|
+
console=console.console,
|
308
|
+
)
|
309
|
+
if not res:
|
310
|
+
return
|
311
|
+
testgroup = None
|
312
|
+
while testgroup is None or testgroup:
|
313
|
+
groups_by_name = {
|
314
|
+
name: group
|
315
|
+
for name, group in package.get_test_groups_by_name().items()
|
316
|
+
if group.generatorScript is not None
|
317
|
+
and group.generatorScript.path.suffix == '.txt'
|
318
|
+
}
|
319
|
+
|
320
|
+
testgroup = questionary.select(
|
321
|
+
'Choose the testgroup to add the tests to.\nOnly test groups that have a .txt generatorScript are shown below: ',
|
322
|
+
choices=list(groups_by_name) + ['(skip)'],
|
323
|
+
).ask()
|
324
|
+
|
325
|
+
if testgroup not in groups_by_name:
|
326
|
+
break
|
327
|
+
try:
|
328
|
+
subgroup = groups_by_name[testgroup]
|
329
|
+
assert subgroup.generatorScript is not None
|
330
|
+
generator_script = pathlib.Path(subgroup.generatorScript.path)
|
331
|
+
|
332
|
+
finding_lines = []
|
333
|
+
for finding in report.findings:
|
334
|
+
line = finding.generator.name
|
335
|
+
if finding.generator.args is not None:
|
336
|
+
line = f'{line} {finding.generator.args}'
|
337
|
+
finding_lines.append(line)
|
338
|
+
|
339
|
+
with generator_script.open('a') as f:
|
340
|
+
stress_text = f'# Obtained by running `rbx {shlex.join(sys.argv[1:])}`'
|
341
|
+
finding_text = '\n'.join(finding_lines)
|
342
|
+
f.write(f'\n{stress_text}\n{finding_text}\n')
|
343
|
+
|
344
|
+
console.console.print(
|
345
|
+
f"Added [item]{len(report.findings)}[/item] tests to test group [item]{testgroup}[/item]'s generatorScript at [item]{subgroup.generatorScript.path}[/item]."
|
346
|
+
)
|
347
|
+
except typer.Exit:
|
348
|
+
continue
|
349
|
+
break
|
350
|
+
|
351
|
+
|
352
|
+
@app.command('environment, env', help='Set or show the current box environment.')
|
353
|
+
@package.within_problem
|
354
|
+
def environment_command(
|
355
|
+
env: Annotated[Optional[str], typer.Argument()] = None,
|
356
|
+
install_from: Annotated[
|
357
|
+
Optional[str],
|
358
|
+
typer.Option(
|
359
|
+
'--install',
|
360
|
+
'-i',
|
361
|
+
help='Whether to install this environment from the given file.',
|
362
|
+
),
|
363
|
+
] = None,
|
364
|
+
):
|
365
|
+
if env is None:
|
366
|
+
cfg = config.get_config()
|
367
|
+
console.console.print(f'Current environment: [item]{cfg.boxEnvironment}[/item]')
|
368
|
+
return
|
369
|
+
if install_from is not None:
|
370
|
+
environment.install_environment(env, pathlib.Path(install_from))
|
371
|
+
if not get_environment_path(env).is_file():
|
372
|
+
console.console.print(
|
373
|
+
f'[error]Environment [item]{env}[/item] does not exist.[/error]'
|
374
|
+
)
|
375
|
+
raise typer.Exit(1)
|
376
|
+
|
377
|
+
cfg = config.get_config()
|
378
|
+
if env == cfg.boxEnvironment:
|
379
|
+
console.console.print(
|
380
|
+
f'Environment is already set to [item]{env}[/item].',
|
381
|
+
)
|
382
|
+
return
|
383
|
+
console.console.print(
|
384
|
+
f'Changing box environment from [item]{cfg.boxEnvironment}[/item] to [item]{env}[/item]...'
|
385
|
+
)
|
386
|
+
cfg.boxEnvironment = env
|
387
|
+
config.save_config(cfg)
|
388
|
+
|
389
|
+
# Also clear cache when changing environments.
|
390
|
+
clear()
|
391
|
+
|
392
|
+
|
393
|
+
@app.command(
|
394
|
+
'activate',
|
395
|
+
help='Activate the environment of the current preset used by the package.',
|
396
|
+
)
|
397
|
+
@cd.within_closest_package
|
398
|
+
def activate():
|
399
|
+
preset_lock = presets.get_preset_lock()
|
400
|
+
if preset_lock is None:
|
401
|
+
console.console.print(
|
402
|
+
'[warning]No configured preset to be activated for this package.[/warning]'
|
403
|
+
)
|
404
|
+
raise typer.Exit(1)
|
405
|
+
|
406
|
+
preset = presets.get_installed_preset_or_null(preset_lock.preset_name)
|
407
|
+
if preset is None:
|
408
|
+
if preset_lock.uri is None:
|
409
|
+
console.console.print(
|
410
|
+
'[error]Preset is not installed. Install it manually, or specify a URI in [item].preset-lock.yml[/item].[/error]'
|
411
|
+
)
|
412
|
+
raise
|
413
|
+
presets.install(preset_lock.uri)
|
414
|
+
|
415
|
+
preset = presets.get_installed_preset(preset_lock.preset_name)
|
416
|
+
if preset.env is not None:
|
417
|
+
environment_command(preset.name)
|
418
|
+
|
419
|
+
console.console.print(f'[success]Preset [item]{preset.name}[/item] is activated.')
|
420
|
+
|
421
|
+
|
422
|
+
@app.command('languages', help='List the languages available in this environment')
|
423
|
+
@package.within_problem
|
424
|
+
def languages():
|
425
|
+
env = environment.get_environment()
|
426
|
+
|
427
|
+
console.console.print(
|
428
|
+
f'[success]There are [item]{len(env.languages)}[/item] language(s) available.'
|
429
|
+
)
|
430
|
+
|
431
|
+
for language in env.languages:
|
432
|
+
console.console.print(
|
433
|
+
f'[item]{language.name}[/item], aka [item]{language.readable_name or language.name}[/item]:'
|
434
|
+
)
|
435
|
+
console.console.print(language)
|
436
|
+
console.console.print()
|
437
|
+
|
438
|
+
|
439
|
+
@app.command('clear, clean', help='Clears cache and build directories.')
|
440
|
+
@package.within_problem
|
441
|
+
def clear():
|
442
|
+
console.console.print('Cleaning cache and build directories...')
|
443
|
+
shutil.rmtree('.box', ignore_errors=True)
|
444
|
+
shutil.rmtree('build', ignore_errors=True)
|
445
|
+
|
446
|
+
|
447
|
+
@app.callback()
|
448
|
+
def callback():
|
449
|
+
pass
|