rbx.cp 0.17.8__py3-none-any.whl → 0.18.1__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/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.17.8'
1
+ __version__ = '0.18.1'
rbx/box/code.py CHANGED
@@ -23,6 +23,7 @@ from rbx.box.environment import (
23
23
  get_execution_config,
24
24
  get_file_mapping,
25
25
  get_language,
26
+ get_language_by_extension,
26
27
  get_mapped_command,
27
28
  get_mapped_commands,
28
29
  get_sandbox_params_from_config,
@@ -81,7 +82,7 @@ def get_extension(code: CodeItem) -> str:
81
82
  def find_language_name(code: CodeItem) -> str:
82
83
  if code.language is not None:
83
84
  return get_language(code.language).name
84
- return get_language(get_extension(code)).name
85
+ return get_language_by_extension(get_extension(code)).name
85
86
 
86
87
 
87
88
  def is_executable_sanitized(executable: DigestOrSource) -> bool:
@@ -113,6 +114,12 @@ CXX_WARNING_FLAGS = (
113
114
  )
114
115
 
115
116
 
117
+ def add_color_flags_to_command(command: str) -> str:
118
+ if is_cxx_command(command):
119
+ return command + ' -fdiagnostics-color=always'
120
+ return command
121
+
122
+
116
123
  def add_warning_flags_to_command(command: str) -> str:
117
124
  if is_cxx_command(command):
118
125
  return command + ' ' + CXX_WARNING_FLAGS
@@ -121,6 +128,7 @@ def add_warning_flags_to_command(command: str) -> str:
121
128
 
122
129
  def add_warning_flags(commands: List[str], force_warnings: bool) -> List[str]:
123
130
  cfg = setter_config.get_setter_config()
131
+ commands = [add_color_flags_to_command(command) for command in commands]
124
132
  if cfg.warnings.enabled or force_warnings:
125
133
  return [add_warning_flags_to_command(command) for command in commands]
126
134
  return commands
@@ -512,6 +520,7 @@ def compile_item(
512
520
  dependency_cache = package.get_dependency_cache()
513
521
  sandbox = package.get_singleton_sandbox()
514
522
  sandbox_params = get_sandbox_params_from_config(compilation_options.sandbox)
523
+ sandbox_params.set_env['CLICOLOR_FORCE'] = '1'
515
524
 
516
525
  if not compilation_options.commands:
517
526
  # Language is not compiled.
@@ -126,8 +126,6 @@ def get_problems_for_statement(
126
126
  raise typer.Exit(1)
127
127
 
128
128
  def matches(statement: Statement) -> bool:
129
- if not requires_matching_statement:
130
- return True
131
129
  if contest_statement.match is None:
132
130
  return statement.language == contest_statement.language
133
131
  return statement.name == contest_statement.match
@@ -137,6 +135,8 @@ def get_problems_for_statement(
137
135
  matching_statements = [
138
136
  statement for statement in pkg.expanded_statements if matches(statement)
139
137
  ]
138
+ if not matching_statements and requires_matching_statement:
139
+ matching_statements = pkg.expanded_statements
140
140
  if not matching_statements:
141
141
  console.console.print(
142
142
  f'[error]No statement found for language {contest_statement.language} in problem {problem.short_name}[/error]'
@@ -188,7 +188,9 @@ def _build_problem_statements(
188
188
  custom_vars: Optional[Dict[str, Any]] = None,
189
189
  ) -> List[ExtractedProblem]:
190
190
  console.console.print('Building problem-level statements...')
191
- extracted_problems = get_problems_for_statement(contest, statement)
191
+ extracted_problems = get_problems_for_statement(
192
+ contest, statement, requires_matching_statement=True
193
+ )
192
194
  res = []
193
195
  contest_cwd_absolute = utils.abspath(pathlib.Path())
194
196
  contest_assets = get_relative_assets(statement.path, statement.assets)
rbx/box/environment.py CHANGED
@@ -302,6 +302,17 @@ def get_language(name: str) -> EnvironmentLanguage:
302
302
  raise typer.Exit()
303
303
 
304
304
 
305
+ @functools.cache
306
+ def get_language_by_extension(extension: str) -> EnvironmentLanguage:
307
+ for lang in get_environment().languages:
308
+ if lang.extension == extension:
309
+ return lang
310
+ console.console.print(
311
+ f'Language with extension [item]{extension}[/item] not found.', style='error'
312
+ )
313
+ raise typer.Exit()
314
+
315
+
305
316
  def install_environment(name: str, file: pathlib.Path):
306
317
  if not file.is_file():
307
318
  console.console.print(
@@ -1,4 +1,3 @@
1
- import os
2
1
  import pathlib
3
2
  import tempfile
4
3
  from typing import Any, Dict, Optional
@@ -7,7 +6,7 @@ import rich
7
6
  import rich.progress
8
7
  import typer
9
8
 
10
- from rbx import console
9
+ from rbx import console, utils
11
10
  from rbx.box import header, limits_info, naming, package
12
11
  from rbx.box.generators import get_all_built_testcases
13
12
  from rbx.box.lang import code_to_langs, is_valid_lang_code
@@ -28,11 +27,14 @@ from rbx.box.testcase_utils import (
28
27
 
29
28
  _API_URL = 'https://polygon.codeforces.com/api'
30
29
 
31
- POLY = api.Polygon(
32
- _API_URL,
33
- os.environ.get('POLYGON_API_KEY', '').strip(),
34
- os.environ.get('POLYGON_API_SECRET', '').strip(),
35
- )
30
+
31
+ def _get_polygon_api() -> api.Polygon:
32
+ env = utils.environ()
33
+ return api.Polygon(
34
+ _API_URL,
35
+ env.get('POLYGON_API_KEY', '').strip(),
36
+ env.get('POLYGON_API_SECRET', '').strip(),
37
+ )
36
38
 
37
39
 
38
40
  def _get_source_type(code: CodeItem):
@@ -56,7 +58,8 @@ def _get_solution_tag(solution: Solution, is_first: bool = False) -> api.Solutio
56
58
 
57
59
 
58
60
  def _find_or_create_problem(problem_name: str) -> api.Problem:
59
- results = POLY.problems_list(name=problem_name)
61
+ api = _get_polygon_api()
62
+ results = api.problems_list(name=problem_name)
60
63
  for result in results:
61
64
  if result.name == problem_name:
62
65
  console.console.print(
@@ -64,7 +67,7 @@ def _find_or_create_problem(problem_name: str) -> api.Problem:
64
67
  )
65
68
  return result
66
69
  console.console.print(f'Creating new problem [item]{problem_name}[/item].')
67
- return POLY.problem_create(problem_name)
70
+ return api.problem_create(problem_name)
68
71
 
69
72
 
70
73
  def _update_problem_info(problem: api.Problem):
@@ -3,6 +3,7 @@ import pathlib
3
3
  import shutil
4
4
 
5
5
  from rbx import console, utils
6
+ from rbx.box.formatting import href
6
7
  from rbx.box.schema import CodeItem
7
8
  from rbx.grading.judge.cacher import FileCacher
8
9
  from rbx.grading.steps import GradingFileOutput
@@ -70,7 +71,7 @@ def print_warning_stack_report():
70
71
  return
71
72
  console.console.rule('[status]Warning stack[/status]')
72
73
  console.console.print(
73
- f'[warning]There were some warnings within the code that run at [item]{stack.root.absolute()}[/item][/warning]'
74
+ f'[warning]There were some warnings within the code that run at {href(stack.root.absolute())}[/warning]'
74
75
  )
75
76
  if stack.warnings:
76
77
  console.console.print(f'{len(stack.warnings)} compilation warnings')
@@ -78,13 +79,13 @@ def print_warning_stack_report():
78
79
  'You can use [item]rbx compile[/item] to reproduce the issues with the files below.'
79
80
  )
80
81
  for path in sorted(stack.warnings):
81
- console.console.print(f'- [item]{path}[/item]')
82
+ console.console.print(f'- {href(path)}')
82
83
  console.console.print()
83
84
 
84
85
  if stack.sanitizer_warnings:
85
86
  console.console.print(f'{len(stack.sanitizer_warnings)} sanitizer warnings')
86
87
  for path in sorted(stack.sanitizer_warnings):
87
88
  console.console.print(
88
- f'- [item]{path}[/item], example log at [item]{stack.sanitizer_warnings[path]}[/item]'
89
+ f'- {href(path)}, example log at {href(stack.sanitizer_warnings[path])}'
89
90
  )
90
91
  console.console.print()
rbx/box/schema.py CHANGED
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- import os
4
3
  import pathlib
5
4
  import re
6
5
  import typing
@@ -9,6 +8,7 @@ from typing import Annotated, Any, Dict, List, Optional
9
8
  from pydantic import AfterValidator, BaseModel, ConfigDict, Field, model_validator
10
9
  from pydantic_core import PydanticCustomError
11
10
 
11
+ from rbx import utils
12
12
  from rbx.autoenum import AutoEnum, alias
13
13
  from rbx.box.fields import NameField, Primitive, RecVars, Vars, expand_vars
14
14
  from rbx.box.statements.expander import expand_statements
@@ -492,8 +492,8 @@ A formula to estimate the time limit for the problem.
492
492
  res = modifier.time
493
493
  if modifier.timeMultiplier is not None:
494
494
  res = int(res * float(modifier.timeMultiplier))
495
- if 'RBX_TIME_MULTIPLIER' in os.environ:
496
- res = int(res * float(os.environ['RBX_TIME_MULTIPLIER']))
495
+ if 'RBX_TIME_MULTIPLIER' in utils.environ():
496
+ res = int(res * float(utils.environ()['RBX_TIME_MULTIPLIER']))
497
497
  return res
498
498
 
499
499
  def memorylimit_for_language(self, language: Optional[str] = None) -> int:
rbx/box/solutions.py CHANGED
@@ -742,14 +742,14 @@ async def run_and_print_interactive_solutions(
742
742
  stdout_path = stdout_path.with_suffix('.pout')
743
743
 
744
744
  if stdout_path.is_file():
745
- console.console.print(f'[status]Output:[/status] {stdout_path}')
745
+ console.console.print(f'[status]Output:[/status] {href(stdout_path)}')
746
746
  if stdout_path.with_suffix('.pio').is_file():
747
747
  console.console.print(
748
- f'[status]Interaction:[/status] {stdout_path.with_suffix(".pio")}'
748
+ f'[status]Interaction:[/status] {href(stdout_path.with_suffix(".pio"))}'
749
749
  )
750
750
  if eval.log.stderr_absolute_path is not None:
751
751
  console.console.print(
752
- f'[status]Stderr:[/status] {eval.log.stderr_absolute_path}'
752
+ f'[status]Stderr:[/status] {href(eval.log.stderr_absolute_path)}'
753
753
  )
754
754
  console.console.print()
755
755
 
@@ -1,7 +1,6 @@
1
1
  import datetime
2
2
  import functools
3
3
  import hashlib
4
- import os
5
4
  import pathlib
6
5
  import re
7
6
  import time
@@ -15,7 +14,7 @@ from bs4 import BeautifulSoup, Tag
15
14
  from pydantic import BaseModel
16
15
  from throttlex import Throttler
17
16
 
18
- from rbx import console
17
+ from rbx import console, utils
19
18
  from rbx.box import naming
20
19
  from rbx.box.tooling.boca.debug_utils import pretty_print_request_data
21
20
  from rbx.grading.steps import Outcome
@@ -31,7 +30,7 @@ UPLOAD_LOG_REGEX = re.compile(r'Problem (\d+) \([^\)]+\) updated')
31
30
  def _parse_env_var(var: str, override: Optional[str]) -> str:
32
31
  if override is not None:
33
32
  return override
34
- value = os.environ.get(var)
33
+ value = utils.environ().get(var)
35
34
  if value is None:
36
35
  console.console.print(
37
36
  f'[error][item]{var}[/item] is not set. Set it as an environment variable.[/error]'
rbx/grading/steps.py CHANGED
@@ -617,6 +617,7 @@ _WARNING_RE = re.compile(r'([^:]+):\d+:\d+:[ ]+warning:.*')
617
617
  def _check_for_compilation_warnings_in_line(line: str) -> bool:
618
618
  if line.startswith('./'):
619
619
  return False
620
+ line = utils.strip_ansi_codes(line)
620
621
  match = _WARNING_RE.match(line)
621
622
  if match is None:
622
623
  return False
@@ -98,36 +98,31 @@ fi
98
98
 
99
99
  maxms=100
100
100
 
101
- if [ "$2" == "" ]; then
102
- jarfile=run.jar
103
- else
104
- jarfile=$2
105
- fi
101
+ jarfile=run.jar
106
102
 
107
103
  cdir=$(pwd)
108
104
  echo "Current directory is $cdir" >&2
109
- mainname=$(echo $name | cut -d'.' -f1)
110
- if [ "$mainname" == "" ]; then
111
- mainname=Main
112
- fi
105
+
106
+ mv "src/$name" "src/Main.kt"
113
107
 
114
108
  cat <<EOF >compileit.sh
115
109
  #!/bin/bash
116
- kotlinc=/snap/kotlin/24/bin/kotlinc
110
+ kotlinc=$(which kotlinc)
111
+ [ -x "\$kotlinc" ] || kotlinc=/snap/kotlin/24/bin/kotlinc
117
112
  [ -x "\$kotlinc" ] || kotlinc=/snap/bin/kotlinc
113
+ [ -x "\$kotlinc" ] || kotlinc=/opt/kotlinc/bin/kotlinc
118
114
  if [ ! -x \$kotlinc ]; then
119
115
  echo "\$kotlinc not found or it's not executable"
120
116
  exit 47
121
117
  fi
122
118
  cd src
123
- \$kotlinc -J-Xmx${maxm}M -J-Xss${maxms}M -J-Xms${maxm}M -d ../$jarfile -include-runtime $name
119
+ \$kotlinc -d ../$jarfile -include-runtime Main.kt
124
120
  echo \$? > ../compileit.retcode
125
121
 
126
122
  exit 0
127
123
  EOF
128
124
  chmod 755 compileit.sh
129
125
 
130
- echo "COMPILATION IS NOT BEING CHROOTED -- THIS IS NOT AN IDEAL SETTING"
131
126
  #$kotlinc "$name"
132
127
  $sf -r1 -t20 -T32 -istdin0 -F512 -u512 -U$bocau -G$bocag -n0 -C. -d40000000000 -m40000000000 ./compileit.sh
133
128
  #./compileit.sh
@@ -148,4 +143,5 @@ if [ "$ret" != "0" ]; then
148
143
  echo "Compilation Error: $ret"
149
144
  ret=1
150
145
  fi
146
+ echo "Kotlin compilation successful with return code $ret"
151
147
  exit $ret
@@ -70,9 +70,17 @@ if [ "$1" == "" -o "$2" == "" -o "$3" == "" ]; then
70
70
  echo "parameter problem"
71
71
  exit 43
72
72
  fi
73
- if [ ! -x "$1" ]; then
74
- echo "$1 not found (or is not in the current dir) or it's not executable"
75
- exit 44
73
+ if [ -r run.exe ]; then
74
+ rm -f run.jar
75
+ cp run.exe run.jar
76
+ fi
77
+ if [ -r "$1" ]; then
78
+ rm -f run.jar
79
+ cp "$1" run.jar
80
+ fi
81
+ if [ ! -r run.jar ]; then
82
+ echo "ERROR: file run.jar not found - possible error during compilation"
83
+ exit 1
76
84
  fi
77
85
  name=$(basename "$1")
78
86
  if [ "${name##*.}" == "class" -a "${name##*.}" == "CLASS" ]; then
@@ -114,6 +122,7 @@ if [ "$5" != "" ]; then
114
122
  maxm=${5}000
115
123
  fi
116
124
  fi
125
+ let "maxms = $maxm / 10"
117
126
  maxf=1024
118
127
  if [ "$6" != "" ]; then
119
128
  if [ "$6" -gt "0" ]; then
@@ -143,14 +152,13 @@ if [ $? -eq 0 ]; then
143
152
  cd "$cdir"
144
153
  [ -f /proc/cpuinfo ] || /bin/mount -t proc proc /proc
145
154
  [ -d /sys/kernel ] || /bin/mount -t sysfs sysfs /sys
146
- kotlin=$(which kotlin)
147
- [ -x "\$kotlin" ] || kotlin=/usr/bin/kotlin
148
- if [ ! -x "\$kotlin" ]; then
149
- echo "\$kotlin not found or it's not executable"
155
+ java=$(which java)
156
+ [ -x "\$java" ] || java=/usr/bin/java
157
+ if [ ! -x "\$java" ]; then
158
+ echo "\$java not found or it's not executable"
150
159
  exit 47
151
160
  fi
152
- export CLASSPATH=.:./run.jar:$CLASSPATH
153
- ./runit.sh "$cdir" "$sf" "$ttime" -r$nruns -t$time -T$ttime -F512 -u512 -U$bocau -G$bocag -n0 -C. -d40000000000 -m40000000000 -- "\$kotlin" -cp run.jar -J-Xmx${maxm}K -J-Xss${maxms}K -J-Xms${maxm}K "$name"
161
+ ./runit.sh "$cdir" "$sf" "$ttime" -r$nruns -t$time -T$ttime -F256 -u256 -U$bocau -G$bocag -n0 -C. -f20000 -d20000000 -m20000000 -- "\$java" -cp run.jar -Xmx${maxm}K -Xss${maxms}K -Xms${maxm}K MainKt
154
162
  retval=\$?
155
163
  echo \$retval > runch.exitcode
156
164
  if [ ! -d /bocajail ]; then
@@ -111,7 +111,7 @@ if [ "$4" != "" ]; then
111
111
  nruns=$4
112
112
  fi
113
113
  fi
114
- maxm=1024000
114
+ maxm=512000
115
115
  if [ "$5" != "" ]; then
116
116
  if [ "$5" -gt "0" ]; then
117
117
  maxm=${5}000
@@ -130,18 +130,52 @@ cp "$2" stdin0 2>/dev/null
130
130
 
131
131
  cdir=$(pwd)
132
132
  echo "Current directory is $cdir" >&2
133
- echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2
134
- echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2
135
- echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2
136
- kotlin=/snap/kotlin/24/bin/kotlin
137
- [ -x "$kotlin" ] || kotlin=/usr/bin/kotlin
138
- if [ ! -x "$kotlin" ]; then
139
- echo "$kotlin not found or it's not executable"
140
- exit 47
141
- fi
142
- "$sf" -r$nruns -t$time -T$ttime -istdin0 -F512 -u512 -U$bocau -G$bocag -ostdout0 -estderr0 -n0 -C. -d40000000000 -m40000000000 -- "$kotlin" -cp run.jar -J-Xmx${maxm}K -J-Xss${maxms}K -J-Xms${maxm}K "$name"
143
- #"$kotlin" -cp run.jar -J-Xmx${maxm}K -J-Xss${maxms}K -J-Xms${maxm}K "$name"
144
- ret=$?
133
+ echo $cdir | grep -q "/bocajail"
134
+ if [ $? == 0 ]; then
135
+ cdir=$(echo $cdir | sed "s/.*\/bocajail//")
136
+ cat <<EOF >runit.sh
137
+ #!/bin/bash
138
+ cd "$cdir"
139
+ [ -f /proc/cpuinfo ] || /bin/mount -t proc proc /proc
140
+ #/bin/mount --bind /dev /dev
141
+ [ -d /sys/kernel ] || /bin/mount -t sysfs sysfs /sys
142
+ java=$(which java)
143
+ [ -x "\$java" ] || java=/usr/bin/java
144
+ if [ ! -x "\$java" ]; then
145
+ echo "\$java not found or it's not executable"
146
+ exit 47
147
+ fi
148
+ "$sf" -r$nruns -t$time -T$ttime -istdin0 -F256 -u256 -ostdout0 -estderr0 -U$bocau -G$bocag -n0 -C. -f20000 -d20000000 -m20000000 -- "\$java" -cp run.jar -Xmx${maxm}K -Xss${maxms}K -Xms${maxm}K MainKt
149
+ retval=\$?
150
+ echo \$retval > runit.retcode
151
+ if [ ! -d /bocajail ]; then
152
+ /bin/umount /proc 2>/dev/null
153
+ #/bin/umount /dev
154
+ /bin/umount /sys 2>/dev/null
155
+ fi
156
+ EOF
157
+ chmod 755 runit.sh
158
+ chroot /bocajail "$cdir/runit.sh"
159
+ if [ -r runit.retcode ]; then
160
+ ret=$(cat runit.retcode)
161
+ fi
162
+ if [ "$ret" == "" ]; then
163
+ echo "Execution error - check autojudging"
164
+ exit 49
165
+ fi
166
+ else
167
+ echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2
168
+ echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2
169
+ echo "CODE NOT BEING CHROOTED. DO NOT RUN THIS ON THE MAIN SERVER" >&2
170
+ java=$(which java)
171
+ [ -x "$java" ] || java=/usr/bin/java
172
+ if [ ! -x "$java" ]; then
173
+ echo "$java not found or it's not executable"
174
+ exit 47
175
+ fi
176
+ "$sf" -r$nruns -t$time -T$ttime -istdin0 -F256 -u256 -U$bocau -G$bocag -ostdout0 -estderr0 -n0 -C. -d20000000 -m20000000 -- "$java" -jar run.jar -Xmx${maxm}K -Xss${maxms}K -Xms${maxm}K
177
+ ret=$?
178
+ fi
145
179
  if [ $ret -gt 10 ]; then
146
180
  if [ -r stderr0 ]; then
147
181
  grep -q "not find or load main class" stderr0
@@ -22,9 +22,6 @@ languages:
22
22
  command: "./{executable}"
23
23
  fileMapping:
24
24
  compilable: "compilable.cpp"
25
- extensions:
26
- boca:
27
- bocaLanguage: "cc"
28
25
  - name: "c"
29
26
  readableName: "C"
30
27
  extension: "c"
@@ -58,9 +55,22 @@ languages:
58
55
  fileMapping:
59
56
  compilable: "Main.java"
60
57
  executable: "Main.jar"
58
+ - name: "kotlin"
59
+ readableName: "Kotlin"
60
+ extension: "kt"
61
+ compilation:
62
+ commands:
63
+ - "kotlinc -d {executable} -include-runtime {compilable}"
64
+ execution:
65
+ command:
66
+ "java -Xss100m -Xmx{{memory}}m -Xms{{initialMemory}}m -cp {executable}
67
+ MainKt"
68
+ fileMapping:
69
+ compilable: "Main.kt"
70
+ executable: "Main.jar"
61
71
  extensions:
62
72
  boca:
63
- languages: ["c", "cc", "java", "py3"]
73
+ languages: ["c", "cpp", "java", "py3", "kt"]
64
74
  flags:
65
75
  c: "-O2 -lm -static"
66
76
  cc: "-std=c++20 -O2 -lm -static"
@@ -1,7 +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.17.8"
4
+ min_version: "0.18.1"
5
5
  uri: "rsalesc/rbx/rbx/resources/presets/default"
6
6
  problem: "problem"
7
7
  contest: "contest"
rbx/utils.py CHANGED
@@ -9,8 +9,9 @@ import re
9
9
  import shutil
10
10
  import subprocess
11
11
  import sys
12
- from typing import Any, Optional, Type, TypeVar, Union
12
+ from typing import Any, Dict, Optional, Type, TypeVar, Union
13
13
 
14
+ import dotenv
14
15
  import rich
15
16
  import rich.markup
16
17
  import rich.prompt
@@ -123,6 +124,16 @@ def escape_markup(s: str) -> str:
123
124
  return rich.markup.escape(s, _escape=re.compile(r'(\\*)(\[)').sub)
124
125
 
125
126
 
127
+ ANSI_RE = re.compile(r'\x1b\[[0-9;]*m')
128
+
129
+
130
+ def strip_ansi_codes(text: str) -> str:
131
+ """
132
+ Removes ANSI escape codes (including color codes) from a string.
133
+ """
134
+ return ANSI_RE.sub('', text)
135
+
136
+
126
137
  def abspath(path: pathlib.Path) -> pathlib.Path:
127
138
  return pathlib.Path(os.path.abspath(path))
128
139
 
@@ -403,3 +414,27 @@ class StatusProgress(rich.status.Status):
403
414
  def step(self, delta: int = 1):
404
415
  self.processed += delta
405
416
  self.update_with_progress(self.processed)
417
+
418
+
419
+ @functools.cache
420
+ def _read_envrc_at(path: pathlib.Path) -> Dict[str, str]:
421
+ entries = []
422
+ while os.path.dirname(str(path)) != str(path):
423
+ envrc = path / '.envrc'
424
+ envrc_local = path / '.envrc.local'
425
+ if envrc_local.is_file():
426
+ entries.append(dotenv.dotenv_values(envrc_local))
427
+ if envrc.is_file():
428
+ entries.append(dotenv.dotenv_values(envrc))
429
+ path = path.parent
430
+
431
+ res = {}
432
+ for entry in reversed(entries):
433
+ res.update(entry)
434
+ return res
435
+
436
+
437
+ def environ() -> Dict[str, str]:
438
+ res = os.environ.copy()
439
+ res.update(_read_envrc_at(pathlib.Path.cwd()))
440
+ return res
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.17.8
3
+ Version: 0.18.1
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9.1,<4.0.0
@@ -34,6 +34,7 @@ Requires-Dist: pydantic (>=2.11.7,<3.0.0)
34
34
  Requires-Dist: pydantic-xml[lxml] (>=2.11.0,<3.0.0)
35
35
  Requires-Dist: pypandoc (>=1.15,<2.0)
36
36
  Requires-Dist: pyte (>=0.8.2,<0.9.0)
37
+ Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
37
38
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
38
39
  Requires-Dist: questionary (>=2.1.0,<3.0.0)
39
40
  Requires-Dist: requests (>=2.32.3,<3.0.0)
@@ -1,5 +1,5 @@
1
1
  rbx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- rbx/__version__.py,sha256=YJo_Aah7IjrrnqgQ0geT3JVZmcyVLd5hsYZZzqkenbQ,23
2
+ rbx/__version__.py,sha256=2o8cZebVQq3IlZWOsEUKQhQ2rd7qwhVQIKyXuLPJU84,23
3
3
  rbx/annotations.py,sha256=_TkLhgZWiUyon3bonHwUo03ls1jY8LwgcR4bVgtgnc0,3519
4
4
  rbx/autoenum.py,sha256=cusv8ClXRlDVvhZ8eDrtYcL_2peXlHugAey_ht8roXk,12025
5
5
  rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -7,10 +7,10 @@ rbx/box/builder.py,sha256=umrTdVAwvsOosBDVvDZ6kq1yWg3Z2Lxp2o1zK-V7BBk,3594
7
7
  rbx/box/cd.py,sha256=_XAzb3kV1NUaaRs8hc9SGDo10O1yh2_gr1EiAKzfUjI,2711
8
8
  rbx/box/checkers.py,sha256=mRovZyTZdySFEaYFVc3Lc-xgEsu6F9FjVPOxDwub7aY,13226
9
9
  rbx/box/cli.py,sha256=iNabTCnSf7qhOJAGxUrgWTrPov6xWwq6soMOSoUb9WI,30129
10
- rbx/box/code.py,sha256=TWF-o8fTh5nAtndKuO9Ti7KL-Ye6mkOoUnRzS4POrfw,25524
10
+ rbx/box/code.py,sha256=iSHIg9wJ2jC7zVOu2l21TcVUip13t_qsgbqwzMNKTRw,25857
11
11
  rbx/box/compile.py,sha256=Kzn5mEQu4vb91W9vjyt0DS6cfPJzFLTUoowFj7uHLUo,2539
12
12
  rbx/box/contest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- rbx/box/contest/build_contest_statements.py,sha256=y-jODWc5ANm5uhj2kTHxyYnEOr4CzpxynJFvFjClTso,14734
13
+ rbx/box/contest/build_contest_statements.py,sha256=UW-Ta-1pTUbMqgy9Drrn4eJj3wdg-KBoqUr1hgaPOrY,14840
14
14
  rbx/box/contest/contest_package.py,sha256=d7PoUHIWVtqaRGatYOfRvZbQ-bz4MPGmv-H94Eg1yyQ,3289
15
15
  rbx/box/contest/contest_utils.py,sha256=fsWHG1e65wq9zvRY3tdf32VF0nU1yzGTOBX5yjXiNk4,1102
16
16
  rbx/box/contest/main.py,sha256=-aBmlwbEbGMHxWlF7ulIAeKLy2v7VVsvpb4c-kkqKK8,8564
@@ -20,7 +20,7 @@ rbx/box/creation.py,sha256=oTAC11XV2Pw2YAlF_d11Eo7A1fD6ItlpFMpLEzMLyFI,1331
20
20
  rbx/box/deferred.py,sha256=II3X9e87JCOZtmspnHh-n4PFqh-FsH_oc0XJHZ9ZYVQ,691
21
21
  rbx/box/download.py,sha256=tLW5gLVeLk0gHMEMwScSoHIXQPkXuPsqXzItsrsnUZY,3070
22
22
  rbx/box/dump_schemas.py,sha256=HXJ195h4e017DpfoFfW3MRDukON2ZhcKtJjkRPX-dX4,649
23
- rbx/box/environment.py,sha256=BRwbeqE5To4yBGP7CJbKPMUxUXIlOWscXw1Vp8glrQ0,14018
23
+ rbx/box/environment.py,sha256=RBxFrcsjiMh80B6Pv21n047Yl96Vegwgo3HtPA-3QAE,14358
24
24
  rbx/box/extensions.py,sha256=Von8kIeXvNFTkGlMRMTvL2HIHPwlkuiMswr-ydbGV1w,519
25
25
  rbx/box/fields.py,sha256=Gsox7Q1M7I8I2FtKvwiAfYUC6USpwghk8fel2Q9Eyhg,2291
26
26
  rbx/box/formatting.py,sha256=i3vXHpo_L_VpVPxOe4wHlai1WhlDJlfxUexS9DC0Szg,1249
@@ -51,7 +51,7 @@ rbx/box/packaging/polygon/importer.py,sha256=SqyYUpeDZuqY8MH_ZaD26p3asAWJelcSzsg
51
51
  rbx/box/packaging/polygon/packager.py,sha256=cnKRnUvoRJM2Ytp_GHxN4fG-a1lPEo1pvg6NjBoLNgQ,12428
52
52
  rbx/box/packaging/polygon/polygon_api.py,sha256=mPKEqiwANJ1nr-JhOgzGMaDhnbljsAgzzPHW6kkf7R4,41016
53
53
  rbx/box/packaging/polygon/test.py,sha256=bgEju5PwudgyfwxXJagm8fM6CJVlWM6l_-2q1V-oKaQ,3069
54
- rbx/box/packaging/polygon/upload.py,sha256=902GlUaq9KBkQ_UMOX96kAeeuLMM_MmASILPP5ZPYVo,13846
54
+ rbx/box/packaging/polygon/upload.py,sha256=j2IaUA0-LxYzgOJzqORYsUECaU079dSbLxqh1Zzqw-I,13942
55
55
  rbx/box/packaging/polygon/xml_schema.py,sha256=Jzmd9Oy9-Y_XppzMHC-GxfuzmS0WGqWJRz1pjhylLTk,3551
56
56
  rbx/box/presets/__init__.py,sha256=YusqU2ewwq3R1MqIXRM2N-i3uFX6s8m8PDbFJDr4zyg,37451
57
57
  rbx/box/presets/fetch.py,sha256=aom7f5atJ5Vy5Ox7k0aF8FDVMIeTjF0IRCkP_nrt6Ms,3118
@@ -60,10 +60,10 @@ rbx/box/presets/schema.py,sha256=5Nw72QrSsA39cUCCLlVfSYMImK_-TfJEGu5TSIDv3W8,291
60
60
  rbx/box/remote.py,sha256=hCdiZSmh6Y1vnSEwLZ_gtAMYV-WLVlU3iVnvcObRpRc,5274
61
61
  rbx/box/retries.py,sha256=BZsi4sYBjm3VK5zb_pBQSYQuKo3ZntmtEFoVPZHg4QI,4982
62
62
  rbx/box/sanitizers/issue_stack.py,sha256=nHtF8bksTIbvOlmDEy72SoXnXfQyIDBHU_3NOn-X1Ss,3534
63
- rbx/box/sanitizers/warning_stack.py,sha256=3-5quni5NWMs2k2NI6MWVFR_ec8BeGFVZ29xyifZ_dY,2882
64
- rbx/box/schema.py,sha256=Q4rDXssTVsmf8kc_0tvZ1SnyXauYi-XubV2WiLBHIBY,20292
63
+ rbx/box/sanitizers/warning_stack.py,sha256=L7tCWmqj2SRtgT7nWPJrKLTqbk4hb5bN9wRKfkCFMWU,2890
64
+ rbx/box/schema.py,sha256=pbmRiVf8pB6ipA8HCpQer9B9SxpbTvJuCNZswLfWe8g,20314
65
65
  rbx/box/setter_config.py,sha256=vyZbsbgkjelZOblMLX5A1j4CLqPNQkrv83IZr_3-46Y,5301
66
- rbx/box/solutions.py,sha256=Id5X9711p5VX0kZfVXpj_klADPz8k5GvQsV3oXvhgrU,52848
66
+ rbx/box/solutions.py,sha256=DzvGs9olhydtTjb4EMq7HsaH2-99eQtJCXFOqnh-uT4,52866
67
67
  rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
68
68
  rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
69
  rbx/box/statements/build_statements.py,sha256=ZbciKblRUnRnTuuZfqU4W4EK6XhKkxuT1ByGMPjzNQU,13298
@@ -94,7 +94,7 @@ rbx/box/tooling/boca/debug_utils.py,sha256=Rs1ptMWsy32jl_DJZASeOfyqh8HCJdhIXufdb
94
94
  rbx/box/tooling/boca/main.py,sha256=knl1rpaHIwA63KkzMJMZQrejzMpbTPBhYqGx1IpuNm4,289
95
95
  rbx/box/tooling/boca/manual_scrape.py,sha256=iuNtOHrWczdaWNNRMKGYkgr-wSwgtjZedpz5-sX5IRQ,724
96
96
  rbx/box/tooling/boca/scrape.py,sha256=7p4DW0smqX0_6o-C1KFIAve3YI7zfIZkP0Y9kAgHDLE,956
97
- rbx/box/tooling/boca/scraper.py,sha256=XwKeRI5Dn9dBHRVA2CXu9qIjsxkAsi5bPDpVwdr7fRk,33740
97
+ rbx/box/tooling/boca/scraper.py,sha256=Tak3VMMveMu-1OiOiXg1mlL2URjk4lCIPudhCu0Im1o,33742
98
98
  rbx/box/tooling/converter.py,sha256=cTRUuZ7GToMuAUo6VE7tOtaeNkXHJZE29me0yopvvsY,2544
99
99
  rbx/box/tooling/main.py,sha256=uj6XHjJMF3nyb4enbbTK8XbUAuiRLT_RP1kVwSMqV5E,2003
100
100
  rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -140,7 +140,7 @@ rbx/grading/judge/sandboxes/tee.py,sha256=fLulB8fV7k5cO-ikRgURpsETrvr6LoUSjGxFM3
140
140
  rbx/grading/judge/storage.py,sha256=8o3pz0Ansanc5t23XGtshJHCD_q4dIR_XorpeVEvg1g,15621
141
141
  rbx/grading/limits.py,sha256=zCyRTEtUQFd1RKL_fFKl3qSiRSIDCalBaSLlt1yhi0Y,896
142
142
  rbx/grading/profiling.py,sha256=OEdtoAzjYjLfi-QI5Ke7tLZzJeqvGpMB2utQBNuH3E4,3369
143
- rbx/grading/steps.py,sha256=qJ0tVWSggGhWj6zUuCV8HTJD9NE11JzRFZN41_jBz_0,26674
143
+ rbx/grading/steps.py,sha256=rH0Jhgt26NntdZSHRkZepMsDTFYZBjUnlMC2nxbYZKo,26714
144
144
  rbx/grading/steps_with_caching.py,sha256=RWHtmlEfszKnKM9ADrfbCUZbxZSTD-BiHV3XSiGW8WY,4797
145
145
  rbx/resources/checkers/boilerplate.cpp,sha256=vj1Qjy59JKEzb4ZpaX_MkL1FaZn_tTLZXjrIkP0nGfc,363
146
146
  rbx/resources/checkers/noop.cpp,sha256=aZI6EfZEWq2opbb-kysvl0UeUoYGLU682LccP7cfBG8,214
@@ -154,14 +154,14 @@ rbx/resources/packagers/boca/compile/c,sha256=DZ9PWjgDTuauwY4my8Y8WXz0gZCBd4I7n0
154
154
  rbx/resources/packagers/boca/compile/cc,sha256=jxPjE9UDspBcEJV4kG7wkYbiadXCBePiMq4M9zvp5vE,4517
155
155
  rbx/resources/packagers/boca/compile/cpp,sha256=Fla9Ld6niiZT-0tRiekb2PS18dB2k0e8QmRFepMASag,4452
156
156
  rbx/resources/packagers/boca/compile/java,sha256=UrgpcwCtrJsMAEF0B7gDRl2VCZgtBocassleN3Jxw7o,5192
157
- rbx/resources/packagers/boca/compile/kt,sha256=C_EZGs19irFFmMGg_UHA64hAitXglx18hYG4EkeXSJM,3953
157
+ rbx/resources/packagers/boca/compile/kt,sha256=bE9dhp2vEJjgGobOHOfbQyBQIR7fzSuWnwP2QuwTRhY,3894
158
158
  rbx/resources/packagers/boca/compile/py2,sha256=eFJIzpRuE7XtI1CzE44njnRUU7tQNgK_wNbIslh9I0Q,4695
159
159
  rbx/resources/packagers/boca/compile/py3,sha256=HWA_yQ6B8VQ_WYVRZWPclbxv7BRiEJTTc9H9oWl1bGU,4695
160
160
  rbx/resources/packagers/boca/interactive/c,sha256=HVEyQ4uHyqkuzopWvOKtju1J45sulgC-zNioJg-_mgE,4856
161
161
  rbx/resources/packagers/boca/interactive/cc,sha256=HVEyQ4uHyqkuzopWvOKtju1J45sulgC-zNioJg-_mgE,4856
162
162
  rbx/resources/packagers/boca/interactive/cpp,sha256=HVEyQ4uHyqkuzopWvOKtju1J45sulgC-zNioJg-_mgE,4856
163
163
  rbx/resources/packagers/boca/interactive/java,sha256=NgtrKg5sTFQO589QTfEVSYYQOMsKTn7RQ2A4lCxBnFc,5595
164
- rbx/resources/packagers/boca/interactive/kt,sha256=p2Nz1Tnn0n55umH-cX1NBnkfMoB0sHPBndRmkkht2_o,5516
164
+ rbx/resources/packagers/boca/interactive/kt,sha256=EQ7oygjq5-zhLdLOAm2Vo9Wj0vxokDUz5SNIOWchiyw,5601
165
165
  rbx/resources/packagers/boca/interactive/py2,sha256=A-4GgaIFvt3-8c8MeYzeT19I4MztAY6uyy3VDnaOyII,4829
166
166
  rbx/resources/packagers/boca/interactive/py3,sha256=1Kgj-zy4e8hk1583wNZUxnCBvmfyCkPDV9WMhyshyLw,4829
167
167
  rbx/resources/packagers/boca/interactor_compile.sh,sha256=ZsUjQAtLSSwfZsYEs200lSdSrRbGrEFgAmRBmLOzI48,1161
@@ -171,7 +171,7 @@ rbx/resources/packagers/boca/run/c,sha256=bhB-I-mJ4xNa6lr0OwC1O-eiMVTE_bdAd13nmy
171
171
  rbx/resources/packagers/boca/run/cc,sha256=bhB-I-mJ4xNa6lr0OwC1O-eiMVTE_bdAd13nmySiT8A,3687
172
172
  rbx/resources/packagers/boca/run/cpp,sha256=bhB-I-mJ4xNa6lr0OwC1O-eiMVTE_bdAd13nmySiT8A,3687
173
173
  rbx/resources/packagers/boca/run/java,sha256=rAcvpriBr3NAuzzjMzIrtTBTgD9dLVr49dW2P7LmYNc,5578
174
- rbx/resources/packagers/boca/run/kt,sha256=0nTcFhEtGSJXLkPmGCqOx58XpTdoGn0qL5niePGDEdo,4673
174
+ rbx/resources/packagers/boca/run/kt,sha256=zzCffAP9Rtuv_qqiPYUkmRYOg6MsNXQCdVZMPD4VZc4,5584
175
175
  rbx/resources/packagers/boca/run/py2,sha256=2IobOou2k6oYIa_mw0DjeZaqJgw9ZQc69e6XYnRS-fo,4917
176
176
  rbx/resources/packagers/boca/run/py3,sha256=_w9IBoDhAThrABcvWfZQ0wOaqnzeiqwG5AL-eAQrVSU,4917
177
177
  rbx/resources/packagers/boca/safeexec.c,sha256=HcZyfnCoIRY8Q7HjT6ohUdNBcP4h6jd5A4uoXXNPzYw,17377
@@ -200,8 +200,8 @@ rbx/resources/presets/default/contest/statement/contest.rbx.tex,sha256=Jx6op_WdV
200
200
  rbx/resources/presets/default/contest/statement/info.rbx.tex,sha256=Wz8Tbmi2lPWMgDbJsJolUi1xaQMwSnHmpZ3JwAy_Tb0,998
201
201
  rbx/resources/presets/default/contest/statement/instructions.tex,sha256=JG_eR13ukZgEahrrmrbg40H8cUzpoUE8QLocihN-fZ8,2414
202
202
  rbx/resources/presets/default/contest/statement/logo.png,sha256=RLNYmZoc-BR6AZKkmr4UEg3h01YeFzvy604jMAQC7aA,414485
203
- rbx/resources/presets/default/env.rbx.yml,sha256=quSPG5Xs9KroYLATNLPNtORLGRWtrLLt2Fx81T1enAM,1692
204
- rbx/resources/presets/default/preset.rbx.yml,sha256=j9TYuDEd4NVbVg1Q7KcFl0Af8Rt_vIcw-3mhNmKi_bQ,520
203
+ rbx/resources/presets/default/env.rbx.yml,sha256=af11icSgwlw80ouYpY_2Eb5N1D4J-v1QKLeIes5Bi94,2008
204
+ rbx/resources/presets/default/preset.rbx.yml,sha256=ULKYyTybsFPOivzfWfGHwLeUPkC3f6tGLkJI_1zxuBM,520
205
205
  rbx/resources/presets/default/problem/.gitignore,sha256=1rt95y9Q7ZHIQn28JyZQUdD5zkpRosjAl9ZqoQmX2cE,149
206
206
  rbx/resources/presets/default/problem/gens/gen.cpp,sha256=rn6sGRjZ1sFE1Rq02r6488iquY9xTrutcvLv4d1sohA,178
207
207
  rbx/resources/presets/default/problem/manual_tests/samples/000.in,sha256=w66OEtCJGqjUNj8cJrqgImgGVm8W_OlIUtF255ds-ow,4
@@ -222,9 +222,9 @@ rbx/resources/presets/default/shared/problem_template.rbx.tex,sha256=KDibf4LtUio
222
222
  rbx/resources/templates/rbx.h,sha256=0AZds9R0PmuPgnlTENb33Y81LW0LlnmOJFaoN8oG3Yo,3638
223
223
  rbx/resources/templates/template.cpp,sha256=xXWpWo7fa7HfmPNqkmHcmv3i46Wm0ZL-gPmkRfGvLn4,317
224
224
  rbx/testing_utils.py,sha256=vNNdaytowJfuopszVHeFzVtHWlPfipPW4zpqCOvdZKU,2908
225
- rbx/utils.py,sha256=ua7qzt5rrpTKgEZXC6cKVDVklOReIYWL6sNsSWkrWE4,11355
226
- rbx_cp-0.17.8.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
227
- rbx_cp-0.17.8.dist-info/METADATA,sha256=TtEtoCRE5ToPgHA0W3hbbVtDWN1utV9NXYYdBN0mM5w,4799
228
- rbx_cp-0.17.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
229
- rbx_cp-0.17.8.dist-info/entry_points.txt,sha256=Gw2_BZ5Jon61biaH_ETbAQGXy8fR5On9gw2U4A1erpo,40
230
- rbx_cp-0.17.8.dist-info/RECORD,,
225
+ rbx/utils.py,sha256=zOXjEkEN9tlzLliWpssNTSmcvdgveUWDdo427qI3dhM,12225
226
+ rbx_cp-0.18.1.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
227
+ rbx_cp-0.18.1.dist-info/METADATA,sha256=N6exVvO8bgDLebW5exIGhjnDdiEuv6-N_Q_vAGC3iRQ,4845
228
+ rbx_cp-0.18.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
229
+ rbx_cp-0.18.1.dist-info/entry_points.txt,sha256=Gw2_BZ5Jon61biaH_ETbAQGXy8fR5On9gw2U4A1erpo,40
230
+ rbx_cp-0.18.1.dist-info/RECORD,,