rbx.cp 0.5.72__py3-none-any.whl → 0.5.73__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/box/cli.py CHANGED
@@ -60,7 +60,7 @@ app.add_typer(
60
60
  )
61
61
  app.add_typer(
62
62
  download.app,
63
- name='download',
63
+ name='download, down',
64
64
  cls=annotations.AliasGroup,
65
65
  help='Download an asset from supported repositories (sub-command).',
66
66
  rich_help_panel='Management',
@@ -104,12 +104,10 @@ def main(
104
104
  help='Whether to compile and run testlib components with sanitizers enabled. '
105
105
  'If you want to run the solutions with sanitizers enabled, use the "-s" flag in the corresponding run command.',
106
106
  ),
107
- debug_logs: bool = typer.Option(
108
- False,
109
- '--debug-logs',
110
- '--debug',
111
- '-d',
112
- help='Whether to save extra debug logs along with the evaluation results.',
107
+ capture: bool = typer.Option(
108
+ True,
109
+ '--capture',
110
+ help='Whether to save extra logs and outputs from interactive solutions.',
113
111
  ),
114
112
  ):
115
113
  if cd.is_problem_package() and not package.is_cache_valid():
@@ -125,7 +123,7 @@ def main(
125
123
  '[warning]Sanitizers are running just for testlib components.\n'
126
124
  'If you want to run the solutions with sanitizers enabled, use the [item]-s[/item] flag in the corresponding run command.[/warning]'
127
125
  )
128
- state.STATE.debug_logs = debug_logs
126
+ state.STATE.debug_logs = capture
129
127
 
130
128
 
131
129
  @app.command('ui', hidden=True)
@@ -136,6 +134,15 @@ def ui():
136
134
  ui_pkg.start()
137
135
 
138
136
 
137
+ @app.command(
138
+ 'on',
139
+ help='Run a command in the context of a problem (or a set of problems) of a contest.',
140
+ context_settings={'allow_extra_args': True, 'ignore_unknown_options': True},
141
+ )
142
+ def on(ctx: typer.Context, problems: str) -> None:
143
+ contest.on(ctx, problems)
144
+
145
+
139
146
  @app.command('diff', hidden=True)
140
147
  def diff(path1: pathlib.Path, path2: pathlib.Path):
141
148
  from rbx.box.ui import main as ui_pkg
@@ -1,5 +1,30 @@
1
+ from typing import List
2
+
1
3
  from rbx.box import environment, package
2
4
  from rbx.box.contest import contest_package
5
+ from rbx.box.contest.schema import ContestProblem
6
+
7
+
8
+ def match_problem(problems: str, contest_problem: ContestProblem) -> bool:
9
+ short_name = contest_problem.short_name.lower()
10
+ problems = problems.lower()
11
+ if problems == '*':
12
+ return True
13
+ if '-' in problems:
14
+ start, end = problems.split('-')
15
+ return start <= short_name <= end
16
+ problem_set = set(p.strip().lower() for p in problems.split(','))
17
+ return short_name in problem_set
18
+
19
+
20
+ def get_problems_of_interest(problems: str) -> List[ContestProblem]:
21
+ contest = contest_package.find_contest_package_or_die()
22
+ problems_of_interest = []
23
+
24
+ for p in contest.problems:
25
+ if match_problem(problems, p):
26
+ problems_of_interest.append(p)
27
+ return problems_of_interest
3
28
 
4
29
 
5
30
  def clear_all_caches():
rbx/box/contest/main.py CHANGED
@@ -232,3 +232,27 @@ def each(ctx: typer.Context) -> None:
232
232
  console.console.print(
233
233
  '[error]One of the commands above failed. Check the output![/error]'
234
234
  )
235
+
236
+
237
+ @app.command(
238
+ 'on',
239
+ help='Run a command in the problem (or in a set of problems) of a context.',
240
+ context_settings={'allow_extra_args': True, 'ignore_unknown_options': True},
241
+ )
242
+ @within_contest
243
+ def on(ctx: typer.Context, problems: str) -> None:
244
+ command = ' '.join(['rbx'] + ctx.args)
245
+ problems_of_interest = contest_utils.get_problems_of_interest(problems)
246
+
247
+ if not problems_of_interest:
248
+ console.console.print(
249
+ f'[error]No problems found in contest matching [item]{problems}[/item].[/error]'
250
+ )
251
+ raise typer.Exit(1)
252
+
253
+ for p in problems_of_interest:
254
+ console.console.print(
255
+ f'[status]Running [item]{command}[/item] for [item]{p.short_name}[/item]...[/status]'
256
+ )
257
+ subprocess.call(command, cwd=p.get_path(), shell=True)
258
+ console.console.print()
rbx/box/download.py CHANGED
@@ -5,7 +5,7 @@ from typing import Optional
5
5
  import typer
6
6
 
7
7
  from rbx import annotations, console
8
- from rbx.box import header, package
8
+ from rbx.box import header, package, remote
9
9
  from rbx.box.schema import CodeItem
10
10
  from rbx.config import get_builtin_checker, get_jngen, get_testlib
11
11
  from rbx.grading import steps
@@ -72,3 +72,21 @@ def checker(name: str):
72
72
  console.console.print(
73
73
  f'[success]Downloaded [item]{name}[/item] into current package.[/success]'
74
74
  )
75
+
76
+
77
+ @app.command('remote, r', help='Download a remote code.')
78
+ @package.within_problem
79
+ def remote_cmd(
80
+ name: str,
81
+ output: Optional[str] = typer.Option(
82
+ None,
83
+ '-o',
84
+ '--output',
85
+ help='Whether to not build outputs for tests and run checker.',
86
+ ),
87
+ ):
88
+ path = remote.expand_file(name)
89
+
90
+ if output is not None:
91
+ pathlib.Path(output).parent.mkdir(parents=True, exist_ok=True)
92
+ shutil.copy(str(path), output)
@@ -46,7 +46,7 @@ class RunExplorerScreen(Screen):
46
46
  if pkg.type == TaskType.COMMUNICATION:
47
47
  tips.display = True
48
48
  tips.write(
49
- 'This is an interactive problem.\nYou can use the [bold blue]rbx -d run[/bold blue] command to capture the interaction between the processes and see them here.'
49
+ 'This is an interactive problem.\nYou can use the [bold blue]rbx --capture run[/bold blue] command to capture the interaction between the processes and see them here.'
50
50
  )
51
51
  yield tips
52
52
 
@@ -132,16 +132,26 @@ SFPID=\$!
132
132
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
133
133
  INTPID=\$!
134
134
 
135
- wait \$INTPID
136
- ECINT=\$?
137
-
135
+ ECINT=0
138
136
  ECSF=0
139
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
140
- # kill the solution
141
- kill -9 \$SFPID
142
- else
137
+
138
+ wait -p EXITID -n \$SFPID \$INTPID
139
+ ECEXIT=\$?
140
+ if [[ \$ECEXIT -ne 0 ]]; then
141
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
142
+ fi
143
+
144
+ EXITFIRST=none
145
+ if [[ \$EXITID -eq \$INTPID ]]; then
143
146
  wait \$SFPID
144
147
  ECSF=\$?
148
+ ECINT=\$ECEXIT
149
+ EXITFIRST=interactor
150
+ else
151
+ wait \$INTPID
152
+ ECINT=\$?
153
+ ECSF=\$ECEXIT
154
+ EXITFIRST=solution
145
155
  fi
146
156
 
147
157
  rm -rf fifo.in fifo.out
@@ -149,27 +159,38 @@ rm -rf fifo.in fifo.out
149
159
  echo "Ran solution as \$@" &>>stderr0
150
160
  echo "interactor exitcode \$ECINT" &>>stderr0
151
161
  echo "solution exitcode \$ECSF" &>>stderr0
162
+ echo "exit first \$EXITFIRST" &>>stderr0
163
+
164
+ finish() {
165
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
166
+ exit \$1
167
+ }
168
+
169
+ # 1. Check for interactor errors.
170
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
171
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
172
+ echo "testlib exitcode \$ECINT" >stdout0
173
+ finish 0
174
+ elif [[ \$ECINT -ne 0 ]]; then
175
+ finish 9
176
+ fi
177
+ fi
152
178
 
153
- RTE=0
154
- if [[ \$ECSF -eq -13 ]]; then
155
- RTE=0
156
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
157
- echo "Found EOF RTE" &>>stderr0
158
- RTE=1
179
+ # 2. Check for solution errors.
180
+ if [[ \$ECSF -ne 0 ]]; then
181
+ finish \$ECSF
159
182
  fi
160
183
 
161
- ret=0
162
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
184
+ # 3. Check for interactor without looking at solution output.
185
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
163
186
  echo "testlib exitcode \$ECINT" >stdout0
164
- ret=0
165
- elif [[ \$ECSF -ne 0 ]]; then
166
- ret=\$ECSF
187
+ finish 0
167
188
  elif [[ \$ECINT -ne 0 ]]; then
168
- ret=9
189
+ finish 9
169
190
  fi
170
191
 
171
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
172
- exit \$ret
192
+ # 4. Finish with zero and later check output.
193
+ finish 0
173
194
  EOF
174
195
 
175
196
  chmod 755 runit.sh
@@ -132,16 +132,26 @@ SFPID=\$!
132
132
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
133
133
  INTPID=\$!
134
134
 
135
- wait \$INTPID
136
- ECINT=\$?
137
-
135
+ ECINT=0
138
136
  ECSF=0
139
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
140
- # kill the solution
141
- kill -9 \$SFPID
142
- else
137
+
138
+ wait -p EXITID -n \$SFPID \$INTPID
139
+ ECEXIT=\$?
140
+ if [[ \$ECEXIT -ne 0 ]]; then
141
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
142
+ fi
143
+
144
+ EXITFIRST=none
145
+ if [[ \$EXITID -eq \$INTPID ]]; then
143
146
  wait \$SFPID
144
147
  ECSF=\$?
148
+ ECINT=\$ECEXIT
149
+ EXITFIRST=interactor
150
+ else
151
+ wait \$INTPID
152
+ ECINT=\$?
153
+ ECSF=\$ECEXIT
154
+ EXITFIRST=solution
145
155
  fi
146
156
 
147
157
  rm -rf fifo.in fifo.out
@@ -149,27 +159,38 @@ rm -rf fifo.in fifo.out
149
159
  echo "Ran solution as \$@" &>>stderr0
150
160
  echo "interactor exitcode \$ECINT" &>>stderr0
151
161
  echo "solution exitcode \$ECSF" &>>stderr0
162
+ echo "exit first \$EXITFIRST" &>>stderr0
163
+
164
+ finish() {
165
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
166
+ exit \$1
167
+ }
168
+
169
+ # 1. Check for interactor errors.
170
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
171
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
172
+ echo "testlib exitcode \$ECINT" >stdout0
173
+ finish 0
174
+ elif [[ \$ECINT -ne 0 ]]; then
175
+ finish 9
176
+ fi
177
+ fi
152
178
 
153
- RTE=0
154
- if [[ \$ECSF -eq -13 ]]; then
155
- RTE=0
156
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
157
- echo "Found EOF RTE" &>>stderr0
158
- RTE=1
179
+ # 2. Check for solution errors.
180
+ if [[ \$ECSF -ne 0 ]]; then
181
+ finish \$ECSF
159
182
  fi
160
183
 
161
- ret=0
162
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
184
+ # 3. Check for interactor without looking at solution output.
185
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
163
186
  echo "testlib exitcode \$ECINT" >stdout0
164
- ret=0
165
- elif [[ \$ECSF -ne 0 ]]; then
166
- ret=\$ECSF
187
+ finish 0
167
188
  elif [[ \$ECINT -ne 0 ]]; then
168
- ret=9
189
+ finish 9
169
190
  fi
170
191
 
171
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
172
- exit \$ret
192
+ # 4. Finish with zero and later check output.
193
+ finish 0
173
194
  EOF
174
195
 
175
196
  chmod 755 runit.sh
@@ -132,16 +132,26 @@ SFPID=\$!
132
132
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
133
133
  INTPID=\$!
134
134
 
135
- wait \$INTPID
136
- ECINT=\$?
137
-
135
+ ECINT=0
138
136
  ECSF=0
139
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
140
- # kill the solution
141
- kill -9 \$SFPID
142
- else
137
+
138
+ wait -p EXITID -n \$SFPID \$INTPID
139
+ ECEXIT=\$?
140
+ if [[ \$ECEXIT -ne 0 ]]; then
141
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
142
+ fi
143
+
144
+ EXITFIRST=none
145
+ if [[ \$EXITID -eq \$INTPID ]]; then
143
146
  wait \$SFPID
144
147
  ECSF=\$?
148
+ ECINT=\$ECEXIT
149
+ EXITFIRST=interactor
150
+ else
151
+ wait \$INTPID
152
+ ECINT=\$?
153
+ ECSF=\$ECEXIT
154
+ EXITFIRST=solution
145
155
  fi
146
156
 
147
157
  rm -rf fifo.in fifo.out
@@ -149,26 +159,38 @@ rm -rf fifo.in fifo.out
149
159
  echo "Ran solution as \$@" &>>stderr0
150
160
  echo "interactor exitcode \$ECINT" &>>stderr0
151
161
  echo "solution exitcode \$ECSF" &>>stderr0
162
+ echo "exit first \$EXITFIRST" &>>stderr0
163
+
164
+ finish() {
165
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
166
+ exit \$1
167
+ }
168
+
169
+ # 1. Check for interactor errors.
170
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
171
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
172
+ echo "testlib exitcode \$ECINT" >stdout0
173
+ finish 0
174
+ elif [[ \$ECINT -ne 0 ]]; then
175
+ finish 9
176
+ fi
177
+ fi
152
178
 
153
- RTE=0
154
- if [[ \$ECSF -eq -13 ]]; then
155
- RTE=0
156
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
157
- echo "Found EOF RTE" &>>stderr0
158
- RTE=1
179
+ # 2. Check for solution errors.
180
+ if [[ \$ECSF -ne 0 ]]; then
181
+ finish \$ECSF
159
182
  fi
160
- ret=0
161
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
183
+
184
+ # 3. Check for interactor without looking at solution output.
185
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
162
186
  echo "testlib exitcode \$ECINT" >stdout0
163
- ret=0
164
- elif [[ \$ECSF -ne 0 ]]; then
165
- ret=\$ECSF
187
+ finish 0
166
188
  elif [[ \$ECINT -ne 0 ]]; then
167
- ret=9
189
+ finish 9
168
190
  fi
169
191
 
170
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
171
- exit \$ret
192
+ # 4. Finish with zero and later check output.
193
+ finish 0
172
194
  EOF
173
195
 
174
196
  chmod 755 runit.sh
@@ -145,16 +145,26 @@ SFPID=\$!
145
145
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
146
146
  INTPID=\$!
147
147
 
148
- wait \$INTPID
149
- ECINT=\$?
150
-
148
+ ECINT=0
151
149
  ECSF=0
152
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
153
- # kill the solution
154
- kill -9 \$SFPID
155
- else
150
+
151
+ wait -p EXITID -n \$SFPID \$INTPID
152
+ ECEXIT=\$?
153
+ if [[ \$ECEXIT -ne 0 ]]; then
154
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
155
+ fi
156
+
157
+ EXITFIRST=none
158
+ if [[ \$EXITID -eq \$INTPID ]]; then
156
159
  wait \$SFPID
157
160
  ECSF=\$?
161
+ ECINT=\$ECEXIT
162
+ EXITFIRST=interactor
163
+ else
164
+ wait \$INTPID
165
+ ECINT=\$?
166
+ ECSF=\$ECEXIT
167
+ EXITFIRST=solution
158
168
  fi
159
169
 
160
170
  rm -rf fifo.in fifo.out
@@ -162,27 +172,38 @@ rm -rf fifo.in fifo.out
162
172
  echo "Ran solution as \$@" &>>stderr0
163
173
  echo "interactor exitcode \$ECINT" &>>stderr0
164
174
  echo "solution exitcode \$ECSF" &>>stderr0
175
+ echo "exit first \$EXITFIRST" &>>stderr0
165
176
 
166
- RTE=0
167
- if [[ \$ECSF -eq -13 ]]; then
168
- RTE=0
169
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
170
- echo "Found EOF RTE" &>>stderr0
171
- RTE=1
177
+ finish() {
178
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
179
+ exit \$1
180
+ }
181
+
182
+ # 1. Check for interactor errors.
183
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
184
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
185
+ echo "testlib exitcode \$ECINT" >stdout0
186
+ finish 0
187
+ elif [[ \$ECINT -ne 0 ]]; then
188
+ finish 9
189
+ fi
172
190
  fi
173
191
 
174
- ret=0
175
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
192
+ # 2. Check for solution errors.
193
+ if [[ \$ECSF -ne 0 ]]; then
194
+ finish \$ECSF
195
+ fi
196
+
197
+ # 3. Check for interactor without looking at solution output.
198
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
176
199
  echo "testlib exitcode \$ECINT" >stdout0
177
- ret=0
178
- elif [[ \$ECSF -ne 0 ]]; then
179
- ret=\$ECSF
200
+ finish 0
180
201
  elif [[ \$ECINT -ne 0 ]]; then
181
- ret=9
202
+ finish 9
182
203
  fi
183
204
 
184
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
185
- exit \$ret
205
+ # 4. Finish with zero and later check output.
206
+ finish 0
186
207
  EOF
187
208
 
188
209
  chmod 755 runit.sh
@@ -136,16 +136,26 @@ SFPID=\$!
136
136
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
137
137
  INTPID=\$!
138
138
 
139
- wait \$INTPID
140
- ECINT=\$?
141
-
139
+ ECINT=0
142
140
  ECSF=0
143
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
144
- # kill the solution
145
- kill -9 \$SFPID
146
- else
141
+
142
+ wait -p EXITID -n \$SFPID \$INTPID
143
+ ECEXIT=\$?
144
+ if [[ \$ECEXIT -ne 0 ]]; then
145
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
146
+ fi
147
+
148
+ EXITFIRST=none
149
+ if [[ \$EXITID -eq \$INTPID ]]; then
147
150
  wait \$SFPID
148
151
  ECSF=\$?
152
+ ECINT=\$ECEXIT
153
+ EXITFIRST=interactor
154
+ else
155
+ wait \$INTPID
156
+ ECINT=\$?
157
+ ECSF=\$ECEXIT
158
+ EXITFIRST=solution
149
159
  fi
150
160
 
151
161
  rm -rf fifo.in fifo.out
@@ -153,27 +163,38 @@ rm -rf fifo.in fifo.out
153
163
  echo "Ran solution as \$@" &>>stderr0
154
164
  echo "interactor exitcode \$ECINT" &>>stderr0
155
165
  echo "solution exitcode \$ECSF" &>>stderr0
166
+ echo "exit first \$EXITFIRST" &>>stderr0
156
167
 
157
- RTE=0
158
- if [[ \$ECSF -eq -13 ]]; then
159
- RTE=0
160
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
161
- echo "Found EOF RTE" &>>stderr0
162
- RTE=1
168
+ finish() {
169
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
170
+ exit \$1
171
+ }
172
+
173
+ # 1. Check for interactor errors.
174
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
175
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
176
+ echo "testlib exitcode \$ECINT" >stdout0
177
+ finish 0
178
+ elif [[ \$ECINT -ne 0 ]]; then
179
+ finish 9
180
+ fi
163
181
  fi
164
182
 
165
- ret=0
166
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
183
+ # 2. Check for solution errors.
184
+ if [[ \$ECSF -ne 0 ]]; then
185
+ finish \$ECSF
186
+ fi
187
+
188
+ # 3. Check for interactor without looking at solution output.
189
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
167
190
  echo "testlib exitcode \$ECINT" >stdout0
168
- ret=0
169
- elif [[ \$ECSF -ne 0 ]]; then
170
- ret=\$ECSF
191
+ finish 0
171
192
  elif [[ \$ECINT -ne 0 ]]; then
172
- ret=9
193
+ finish 9
173
194
  fi
174
195
 
175
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
176
- exit \$ret
196
+ # 4. Finish with zero and later check output.
197
+ finish 0
177
198
  EOF
178
199
 
179
200
  chmod 755 runit.sh
@@ -123,16 +123,26 @@ SFPID=\$!
123
123
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
124
124
  INTPID=\$!
125
125
 
126
- wait \$INTPID
127
- ECINT=\$?
128
-
126
+ ECINT=0
129
127
  ECSF=0
130
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
131
- # kill the solution
132
- kill -9 \$SFPID
133
- else
128
+
129
+ wait -p EXITID -n \$SFPID \$INTPID
130
+ ECEXIT=\$?
131
+ if [[ \$ECEXIT -ne 0 ]]; then
132
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
133
+ fi
134
+
135
+ EXITFIRST=none
136
+ if [[ \$EXITID -eq \$INTPID ]]; then
134
137
  wait \$SFPID
135
138
  ECSF=\$?
139
+ ECINT=\$ECEXIT
140
+ EXITFIRST=interactor
141
+ else
142
+ wait \$INTPID
143
+ ECINT=\$?
144
+ ECSF=\$ECEXIT
145
+ EXITFIRST=solution
136
146
  fi
137
147
 
138
148
  rm -rf fifo.in fifo.out
@@ -140,27 +150,38 @@ rm -rf fifo.in fifo.out
140
150
  echo "Ran solution as \$@" &>>stderr0
141
151
  echo "interactor exitcode \$ECINT" &>>stderr0
142
152
  echo "solution exitcode \$ECSF" &>>stderr0
153
+ echo "exit first \$EXITFIRST" &>>stderr0
154
+
155
+ finish() {
156
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
157
+ exit \$1
158
+ }
159
+
160
+ # 1. Check for interactor errors.
161
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
162
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
163
+ echo "testlib exitcode \$ECINT" >stdout0
164
+ finish 0
165
+ elif [[ \$ECINT -ne 0 ]]; then
166
+ finish 9
167
+ fi
168
+ fi
143
169
 
144
- RTE=0
145
- if [[ \$ECSF -eq -13 ]]; then
146
- RTE=0
147
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
148
- echo "Found EOF RTE" &>>stderr0
149
- RTE=1
170
+ # 2. Check for solution errors.
171
+ if [[ \$ECSF -ne 0 ]]; then
172
+ finish \$ECSF
150
173
  fi
151
174
 
152
- ret=0
153
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
175
+ # 3. Check for interactor without looking at solution output.
176
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
154
177
  echo "testlib exitcode \$ECINT" >stdout0
155
- ret=0
156
- elif [[ \$ECSF -ne 0 ]]; then
157
- ret=\$ECSF
178
+ finish 0
158
179
  elif [[ \$ECINT -ne 0 ]]; then
159
- ret=9
180
+ finish 9
160
181
  fi
161
182
 
162
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
163
- exit \$ret
183
+ # 4. Finish with zero and later check output.
184
+ finish 0
164
185
  EOF
165
186
 
166
187
  chmod 755 runit.sh
@@ -115,22 +115,34 @@ cat <<EOF >runit.sh
115
115
  #!/bin/bash
116
116
  mkfifo fifo.in fifo.out
117
117
 
118
+ echo "Running solution as \$@" >&2
119
+
118
120
  "\$@" >fifo.out <fifo.in 2>/dev/null &
119
121
  SFPID=\$!
120
122
 
121
123
  ./interactor.exe "stdin0" "stdout0" <fifo.out >fifo.in 2>stderr0 &
122
124
  INTPID=\$!
123
125
 
124
- wait \$INTPID
125
- ECINT=\$?
126
-
126
+ ECINT=0
127
127
  ECSF=0
128
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
129
- # kill the solution
130
- kill -9 \$SFPID
131
- else
128
+
129
+ wait -p EXITID -n \$SFPID \$INTPID
130
+ ECEXIT=\$?
131
+ if [[ \$ECEXIT -ne 0 ]]; then
132
+ kill -SIGTERM \$SFPID \$INTPID 2>/dev/null
133
+ fi
134
+
135
+ EXITFIRST=none
136
+ if [[ \$EXITID -eq \$INTPID ]]; then
132
137
  wait \$SFPID
133
138
  ECSF=\$?
139
+ ECINT=\$ECEXIT
140
+ EXITFIRST=interactor
141
+ else
142
+ wait \$INTPID
143
+ ECINT=\$?
144
+ ECSF=\$ECEXIT
145
+ EXITFIRST=solution
134
146
  fi
135
147
 
136
148
  rm -rf fifo.in fifo.out
@@ -138,27 +150,38 @@ rm -rf fifo.in fifo.out
138
150
  echo "Ran solution as \$@" &>>stderr0
139
151
  echo "interactor exitcode \$ECINT" &>>stderr0
140
152
  echo "solution exitcode \$ECSF" &>>stderr0
153
+ echo "exit first \$EXITFIRST" &>>stderr0
154
+
155
+ finish() {
156
+ echo "exitting from runit.sh with exit code \$1" &>>stderr0
157
+ exit \$1
158
+ }
159
+
160
+ # 1. Check for interactor errors.
161
+ if [[ \$ECSF -eq -SIGPIPE ]] || [[ \$ECSF -eq -SIGTERM ]] || [[ \$ECSF -ne 0 ]] && ! cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
162
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
163
+ echo "testlib exitcode \$ECINT" >stdout0
164
+ finish 0
165
+ elif [[ \$ECINT -ne 0 ]]; then
166
+ finish 9
167
+ fi
168
+ fi
141
169
 
142
- RTE=0
143
- if [[ \$ECSF -eq -13 ]]; then
144
- RTE=0
145
- elif [[ \$ECSF -ne 0 ]] && cat stderr0 | grep -q "wrong output format Unexpected end of file"; then
146
- echo "Found EOF RTE" &>>stderr0
147
- RTE=1
170
+ # 2. Check for solution errors.
171
+ if [[ \$ECSF -ne 0 ]]; then
172
+ finish \$ECSF
148
173
  fi
149
174
 
150
- ret=0
151
- if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]] && [[ \$RTE -eq 0 ]]; then
175
+ # 3. Check for interactor without looking at solution output.
176
+ if [[ \$ECINT -ge 1 ]] && [[ \$ECINT -le 4 ]]; then
152
177
  echo "testlib exitcode \$ECINT" >stdout0
153
- ret=0
154
- elif [[ \$ECSF -ne 0 ]]; then
155
- ret=\$ECSF
178
+ finish 0
156
179
  elif [[ \$ECINT -ne 0 ]]; then
157
- ret=9
180
+ finish 9
158
181
  fi
159
182
 
160
- echo "exitting from runit.sh with exit code \$ret" &>>stderr0
161
- exit \$ret
183
+ # 4. Finish with zero and later check output.
184
+ finish 0
162
185
  EOF
163
186
 
164
187
  chmod 755 runit.sh
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.5.72
3
+ Version: 0.5.73
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -5,20 +5,20 @@ rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  rbx/box/builder.py,sha256=MDm2qqmhedAbhn3rWP6cDwbBsGhV6sz_2sg1zLkPDw0,3613
6
6
  rbx/box/cd.py,sha256=KGaqXHnv2hCumZS2VdMezFfwFEQcSq0rt05_KZtuQAo,1570
7
7
  rbx/box/checkers.py,sha256=0r_9cdRfZJlDuBuBB7xrzMJixcVL2JdBe4dmWAQym04,12828
8
- rbx/box/cli.py,sha256=ssm8X4klvtvQS9P-bABQTQkdYEc07ydWIgJ3l78Cuo4,27524
8
+ rbx/box/cli.py,sha256=jWL-Tws_74d0WFuHymk_VSTWTy8MGgmroBD0o5sqGxo,27767
9
9
  rbx/box/code.py,sha256=2oC1JbZiwfeg53ZICPig-KJYchqFRIZz-inlM-cLc7Q,19911
10
10
  rbx/box/compile.py,sha256=Kzn5mEQu4vb91W9vjyt0DS6cfPJzFLTUoowFj7uHLUo,2539
11
11
  rbx/box/conftest.py,sha256=sEmciXSeDC-wmrZ1JSxbsUenKNP_VWW32mrCun2pY3I,1070
12
12
  rbx/box/contest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  rbx/box/contest/build_contest_statements.py,sha256=DtbzLShc8zzbjE-1sBFtPY3JGhSwm48q6eSOPYWSVxQ,11399
14
14
  rbx/box/contest/contest_package.py,sha256=OaUbpBtkhkgOPzJ1ccI_Vq4FMSaJvZm3gMOKfVY8oy4,3032
15
- rbx/box/contest/contest_utils.py,sha256=TDE7I6YQJlu4dQd68wzOp019bNgqiT0RlM-LMQMjL9w,301
16
- rbx/box/contest/main.py,sha256=u76kAQSVWEuyGLqVgyjXwYxJwHXAeEHMwbM7MfenKvE,7574
15
+ rbx/box/contest/contest_utils.py,sha256=fsWHG1e65wq9zvRY3tdf32VF0nU1yzGTOBX5yjXiNk4,1102
16
+ rbx/box/contest/main.py,sha256=5IRdTRxk4u7wSFgmcC18mefuuLfgsJGRlYWl3pLg-v8,8416
17
17
  rbx/box/contest/schema.py,sha256=OOoQUPYAHzu78aQfRbrqGepiUdGxSVRR1VQKFbKHjkE,6111
18
18
  rbx/box/contest/statements.py,sha256=Or8gFb6P_oViGdeiVgepXsvd_W84mA7LRaVmiAXWWSg,2977
19
19
  rbx/box/creation.py,sha256=Evz7K6JoarD-4JJQsZsgoxU9FgCF9Z7-LfuroG4Cqls,2444
20
20
  rbx/box/deferred.py,sha256=II3X9e87JCOZtmspnHh-n4PFqh-FsH_oc0XJHZ9ZYVQ,691
21
- rbx/box/download.py,sha256=DxAiAk4lDYWEz1C9UTvZzHTq6hgm4fxGezApm2IkCTM,2601
21
+ rbx/box/download.py,sha256=tLW5gLVeLk0gHMEMwScSoHIXQPkXuPsqXzItsrsnUZY,3070
22
22
  rbx/box/dump_schemas.py,sha256=3j5t47_vJmXj0BCczxDX6ByOcsfolGEDNCBXlPpk86w,593
23
23
  rbx/box/environment.py,sha256=Kp69MekUwwoVpupnafUcN5KAbP-ZTCwe0OQXt1h0FN8,11859
24
24
  rbx/box/extensions.py,sha256=Von8kIeXvNFTkGlMRMTvL2HIHPwlkuiMswr-ydbGV1w,519
@@ -83,7 +83,7 @@ rbx/box/ui/screens/differ.py,sha256=Sp6xQwsFiqMl0tvbdhiPdh8AWUNPT8jshce3H7DhPrw,
83
83
  rbx/box/ui/screens/error.py,sha256=k6Rs5maR_APKepMtPcDMSXo6BDKrP-pAnFFJgqmXDKE,496
84
84
  rbx/box/ui/screens/rich_log_modal.py,sha256=ciKC7_3SLKToDvQA9mrcNNdKBX85f2B1ASgrtyDvn38,799
85
85
  rbx/box/ui/screens/run.py,sha256=eKIfFRi-VbqKDxlhZDuOEdVl91XCndnmNIZyj_LMV0c,6028
86
- rbx/box/ui/screens/run_explorer.py,sha256=YhcMd1d1ZNZWf2pOrdkOS_FN1M1t0N6T8U2tAHAxMfM,3389
86
+ rbx/box/ui/screens/run_explorer.py,sha256=SC0GqUTqVFoaXKRPConMltUgDBC2QSBeN3xuN0KS8m4,3396
87
87
  rbx/box/ui/screens/run_test_explorer.py,sha256=D6sXTEbqzXI7uPu3EXZoFyIBxlGFbkdeyWj9OwYFHS8,6681
88
88
  rbx/box/ui/screens/selector.py,sha256=s9JR74anCt8NAlkk7GeNvqyqz2YEhCWTebOUNQ7HrXg,856
89
89
  rbx/box/ui/screens/test_explorer.py,sha256=Iv6yDqELr4-Ouo9PSD5Wr3bTdbmx8VfrK9zj5ULhPlg,4078
@@ -149,13 +149,13 @@ rbx/resources/packagers/boca/compile/kt,sha256=3B900QSD4jSXnX91gJbvI4ZmNELHSiBb5
149
149
  rbx/resources/packagers/boca/compile/pas,sha256=C5IwZzmZpIos49FrLGafRbdGPODNJn7N5JbnLX_FT_4,4576
150
150
  rbx/resources/packagers/boca/compile/py2,sha256=UJknN4xiKP8oMN8tRZ92tDlESXgBfRO69QfyUyjijvA,4739
151
151
  rbx/resources/packagers/boca/compile/py3,sha256=L5Yzl_G5kTdmx7N7-oW3Dm_sq4uQJleRmFq84WNfZXo,4739
152
- rbx/resources/packagers/boca/interactive/c,sha256=_AkIHI790gsa3_k_oYgvQdRCgLOzOymxnT0foEz_qu0,5829
153
- rbx/resources/packagers/boca/interactive/cc,sha256=_AkIHI790gsa3_k_oYgvQdRCgLOzOymxnT0foEz_qu0,5829
154
- rbx/resources/packagers/boca/interactive/cpp,sha256=Hybb9Z-ReWUGuR6Ia6ODPGPGcIJFtjdP_9iVG-7z3RE,5828
155
- rbx/resources/packagers/boca/interactive/java,sha256=Q7507ehwXwCdLHyVQ2Rtsy5umBLQMX5pe6ptYIUfH18,6796
156
- rbx/resources/packagers/boca/interactive/kt,sha256=HZ6rSAA0nvuFAov6F1psEja4FEV0V6MqiS8TLhZQMAw,6730
157
- rbx/resources/packagers/boca/interactive/py2,sha256=Ieku094OBwNra_U0Dcd9VO6GbOzrljfJjzVB5JGJPYo,5993
158
- rbx/resources/packagers/boca/interactive/py3,sha256=73WSpcBlqiuskdKQvPSBlQ0tAp18UavKOcMisrdXC8w,5957
152
+ rbx/resources/packagers/boca/interactive/c,sha256=gLuJ9heX00i-8bmj5J1j4RcHaksMEDv-z3ykDoYqqZs,6360
153
+ rbx/resources/packagers/boca/interactive/cc,sha256=gLuJ9heX00i-8bmj5J1j4RcHaksMEDv-z3ykDoYqqZs,6360
154
+ rbx/resources/packagers/boca/interactive/cpp,sha256=gLuJ9heX00i-8bmj5J1j4RcHaksMEDv-z3ykDoYqqZs,6360
155
+ rbx/resources/packagers/boca/interactive/java,sha256=seoD4td8n85l7v-8rqDuwEKhl3ekHnHkZ_Z3ypNVoJA,7327
156
+ rbx/resources/packagers/boca/interactive/kt,sha256=L5-hTrQ9VblO0d1hBOjbHVzEp1GEELWo0N8AceULnCU,7261
157
+ rbx/resources/packagers/boca/interactive/py2,sha256=ceNObaszmSzAxfK7CuXdjO-8XoR3PNa0kxieoJBlJFg,6524
158
+ rbx/resources/packagers/boca/interactive/py3,sha256=htrTvWHoAulWV2e-Y9AlcpWNsq0_rv0ktrbTzxO96aE,6524
159
159
  rbx/resources/packagers/boca/interactor_compile.sh,sha256=5dvF_eYuAJS3wlxyjUIJvu9HUNiMvET17rgoPq-WIlc,1082
160
160
  rbx/resources/packagers/boca/run/bkp,sha256=xyDkZDaxgUrW-K2I0YJs8a8dJMuF-k8_ganDGxqhvUQ,4218
161
161
  rbx/resources/packagers/boca/run/c,sha256=bhB-I-mJ4xNa6lr0OwC1O-eiMVTE_bdAd13nmySiT8A,3687
@@ -217,8 +217,8 @@ rbx/testcase.py,sha256=yKOq3CAJZ1YTmInvnoIs0u1iJnRj_X85XiWbLI-p9d8,1951
217
217
  rbx/testcase_rendering.py,sha256=nfmv6dSEqd4aR3TsaODwkKGK6AXty_DDKtWf_ejiQpI,2084
218
218
  rbx/testing_utils.py,sha256=x_PqD8Zd2PkN91NxVHUnSTs044-1WK5KKtttKQBXpFs,2083
219
219
  rbx/utils.py,sha256=SfR844_i0ebRDMkmS_w1YdZiWPc6h2RGADygewlWRbA,4845
220
- rbx_cp-0.5.72.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
221
- rbx_cp-0.5.72.dist-info/METADATA,sha256=XcIhcEEPVCd1Ows9DFdu3qgQodAnSPokFDk4RU9hyA8,3604
222
- rbx_cp-0.5.72.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
223
- rbx_cp-0.5.72.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
224
- rbx_cp-0.5.72.dist-info/RECORD,,
220
+ rbx_cp-0.5.73.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
221
+ rbx_cp-0.5.73.dist-info/METADATA,sha256=NK12BtXCVWjzZWL9Dnvo0R3zsd8pZSgRqL2xwng11-A,3604
222
+ rbx_cp-0.5.73.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
223
+ rbx_cp-0.5.73.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
224
+ rbx_cp-0.5.73.dist-info/RECORD,,