rbx.cp 0.5.66__py3-none-any.whl → 0.5.67__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/checkers.py +4 -2
- rbx/box/cli.py +6 -7
- rbx/box/compile.py +3 -1
- rbx/box/formatting.py +5 -1
- rbx/box/generators.py +5 -5
- rbx/box/package.py +11 -3
- rbx/box/packaging/boca/upload.py +1 -0
- rbx/box/presets/__init__.py +2 -1
- rbx/box/remote.py +151 -0
- rbx/box/retries.py +3 -9
- rbx/box/schema.py +25 -10
- rbx/box/solutions.py +41 -64
- rbx/box/stresses.py +17 -6
- rbx/box/ui/css/app.tcss +27 -7
- rbx/box/ui/main.py +3 -0
- rbx/box/ui/screens/rich_log_modal.py +29 -0
- rbx/box/ui/screens/run_explorer.py +20 -3
- rbx/box/ui/screens/run_test_explorer.py +20 -0
- rbx/box/ui/screens/selector.py +6 -4
- rbx/box/ui/screens/test_explorer.py +2 -13
- rbx/box/ui/utils/run_ui.py +13 -0
- rbx/box/unit.py +34 -0
- rbx/grading/steps.py +7 -0
- rbx/resources/checkers/noop.cpp +13 -0
- rbx/resources/packagers/boca/compile/java +10 -5
- rbx/resources/packagers/boca/compile/py2 +52 -44
- rbx/resources/packagers/boca/compile/py3 +52 -44
- rbx/resources/packagers/boca/interactive/java +2 -3
- rbx/resources/packagers/boca/run/java +2 -3
- rbx/test.py +1 -1
- {rbx_cp-0.5.66.dist-info → rbx_cp-0.5.67.dist-info}/METADATA +1 -1
- {rbx_cp-0.5.66.dist-info → rbx_cp-0.5.67.dist-info}/RECORD +35 -32
- {rbx_cp-0.5.66.dist-info → rbx_cp-0.5.67.dist-info}/LICENSE +0 -0
- {rbx_cp-0.5.66.dist-info → rbx_cp-0.5.67.dist-info}/WHEEL +0 -0
- {rbx_cp-0.5.66.dist-info → rbx_cp-0.5.67.dist-info}/entry_points.txt +0 -0
rbx/box/ui/css/app.tcss
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
Screen {
|
2
2
|
background: $background;
|
3
3
|
color: $text;
|
4
|
+
align: center middle;
|
4
5
|
}
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
ModalScreen {
|
8
|
+
background: $background 65%;
|
8
9
|
}
|
9
10
|
|
10
11
|
ListView {
|
@@ -25,13 +26,9 @@ DiffBox {
|
|
25
26
|
border: solid $accent;
|
26
27
|
height: 1fr;
|
27
28
|
width: 1fr;
|
28
|
-
|
29
|
+
RichLog {
|
29
30
|
height: 1fr;
|
30
31
|
width: 1fr;
|
31
|
-
|
32
|
-
.code_inline {
|
33
|
-
background: $background;
|
34
|
-
}
|
35
32
|
}
|
36
33
|
}
|
37
34
|
|
@@ -110,4 +107,27 @@ TestExplorerScreen, RunTestExplorerScreen {
|
|
110
107
|
border: solid $accent;
|
111
108
|
padding: 0 1;
|
112
109
|
}
|
110
|
+
}
|
111
|
+
|
112
|
+
#rich-dialog {
|
113
|
+
max-width: 80;
|
114
|
+
height: auto;
|
115
|
+
max-height: 5;
|
116
|
+
|
117
|
+
RichLog {
|
118
|
+
border: solid $accent;
|
119
|
+
padding: 0 1;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
#selector-dialog {
|
124
|
+
max-width: 80;
|
125
|
+
height: auto;
|
126
|
+
}
|
127
|
+
|
128
|
+
#run-tips {
|
129
|
+
border: solid $accent;
|
130
|
+
padding: 0 1;
|
131
|
+
height: auto;
|
132
|
+
text-align: center;
|
113
133
|
}
|
rbx/box/ui/main.py
CHANGED
@@ -6,6 +6,7 @@ from textual.containers import Center
|
|
6
6
|
from textual.screen import Screen
|
7
7
|
from textual.widgets import Footer, Header, OptionList
|
8
8
|
|
9
|
+
from rbx.box import remote
|
9
10
|
from rbx.box.ui.screens.differ import DifferScreen
|
10
11
|
from rbx.box.ui.screens.run_explorer import RunExplorerScreen
|
11
12
|
from rbx.box.ui.screens.test_explorer import TestExplorerScreen
|
@@ -57,5 +58,7 @@ def start():
|
|
57
58
|
|
58
59
|
|
59
60
|
def start_differ(path1: pathlib.Path, path2: pathlib.Path):
|
61
|
+
path1, path2 = remote.expand_files([path1, path2])
|
62
|
+
|
60
63
|
app = rbxDifferApp(path1, path2)
|
61
64
|
app.run()
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from textual.app import ComposeResult
|
4
|
+
from textual.containers import Container
|
5
|
+
from textual.screen import ModalScreen
|
6
|
+
|
7
|
+
from rbx.box.ui.widgets.rich_log_box import RichLogBox
|
8
|
+
|
9
|
+
|
10
|
+
class RichLogModal(ModalScreen[None]):
|
11
|
+
BINDINGS = [
|
12
|
+
('q', 'app.pop_screen', 'Close'),
|
13
|
+
('g', 'app.pop_screen', 'Close'),
|
14
|
+
]
|
15
|
+
|
16
|
+
def __init__(self, log: str, title: Optional[str] = None):
|
17
|
+
super().__init__()
|
18
|
+
self._log = log
|
19
|
+
self._title = title
|
20
|
+
|
21
|
+
def compose(self) -> ComposeResult:
|
22
|
+
with Container(id='rich-dialog'):
|
23
|
+
box = RichLogBox(markup=True)
|
24
|
+
if self._title:
|
25
|
+
box.border_title = self._title
|
26
|
+
yield box
|
27
|
+
|
28
|
+
async def on_mount(self):
|
29
|
+
self.query_one(RichLogBox).write(self._log)
|
@@ -1,15 +1,19 @@
|
|
1
1
|
from typing import Optional
|
2
2
|
|
3
3
|
from textual.app import ComposeResult
|
4
|
+
from textual.containers import Vertical
|
4
5
|
from textual.reactive import reactive
|
5
6
|
from textual.screen import Screen
|
6
7
|
from textual.widgets import Footer, Header, Label, ListItem, ListView
|
7
8
|
|
9
|
+
from rbx.box import package
|
10
|
+
from rbx.box.schema import TaskType
|
8
11
|
from rbx.box.solutions import SolutionReportSkeleton
|
9
12
|
from rbx.box.ui.screens.error import ErrorScreen
|
10
13
|
from rbx.box.ui.screens.run_test_explorer import RunTestExplorerScreen
|
11
14
|
from rbx.box.ui.screens.selector import SelectorScreen
|
12
15
|
from rbx.box.ui.utils.run_ui import get_skeleton, get_solution_markup, has_run
|
16
|
+
from rbx.box.ui.widgets.rich_log_box import RichLogBox
|
13
17
|
|
14
18
|
|
15
19
|
class RunExplorerScreen(Screen):
|
@@ -29,9 +33,22 @@ class RunExplorerScreen(Screen):
|
|
29
33
|
Label(get_solution_markup(self.skeleton, sol), markup=True)
|
30
34
|
for i, sol in enumerate(self.skeleton.solutions)
|
31
35
|
]
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
with Vertical():
|
37
|
+
run_list = ListView(*[ListItem(item) for item in items], id='run-list')
|
38
|
+
run_list.border_title = 'Runs'
|
39
|
+
yield run_list
|
40
|
+
|
41
|
+
tips = RichLogBox(id='run-tips')
|
42
|
+
tips.markup = True
|
43
|
+
tips.display = False
|
44
|
+
tips.border_title = 'Tips'
|
45
|
+
pkg = package.find_problem_package_or_die()
|
46
|
+
if pkg.type == TaskType.COMMUNICATION:
|
47
|
+
tips.display = True
|
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.'
|
50
|
+
)
|
51
|
+
yield tips
|
35
52
|
|
36
53
|
def on_mount(self):
|
37
54
|
if not has_run():
|
@@ -13,7 +13,9 @@ from rbx.box.testcase_extractors import (
|
|
13
13
|
GenerationTestcaseEntry,
|
14
14
|
extract_generation_testcases,
|
15
15
|
)
|
16
|
+
from rbx.box.ui.screens.rich_log_modal import RichLogModal
|
16
17
|
from rbx.box.ui.utils.run_ui import (
|
18
|
+
get_metadata_markup,
|
17
19
|
get_run_testcase_markup,
|
18
20
|
get_run_testcase_metadata_markup,
|
19
21
|
)
|
@@ -30,6 +32,7 @@ class RunTestExplorerScreen(Screen):
|
|
30
32
|
('3', 'show_log', 'Show log'),
|
31
33
|
('m', 'toggle_metadata', 'Toggle metadata'),
|
32
34
|
('s', 'toggle_side_by_side', 'Toggle sxs'),
|
35
|
+
('g', 'toggle_test_metadata', 'Toggle test metadata'),
|
33
36
|
]
|
34
37
|
|
35
38
|
side_by_side: reactive[bool] = reactive(False)
|
@@ -62,6 +65,11 @@ class RunTestExplorerScreen(Screen):
|
|
62
65
|
yield TwoSidedTestBoxWidget(id='test-output')
|
63
66
|
|
64
67
|
async def on_mount(self):
|
68
|
+
self.title = str(self.solution.path)
|
69
|
+
|
70
|
+
if self.diff_solution is not None:
|
71
|
+
self.title = f'{self.title} vs. {self.diff_solution.path}'
|
72
|
+
|
65
73
|
self.query_one('#test-list').border_title = 'Tests'
|
66
74
|
self.query_one('#test-input').border_title = 'Input'
|
67
75
|
|
@@ -164,3 +172,15 @@ class RunTestExplorerScreen(Screen):
|
|
164
172
|
return
|
165
173
|
widget = self.query_one('#test-output', TwoSidedTestBoxWidget)
|
166
174
|
widget.diff_with_data = diff_with_data
|
175
|
+
|
176
|
+
def action_toggle_test_metadata(self):
|
177
|
+
list_view = self.query_one('#test-list', ListView)
|
178
|
+
if list_view.index is None:
|
179
|
+
return
|
180
|
+
entry = self._entries[list_view.index]
|
181
|
+
self.app.push_screen(
|
182
|
+
RichLogModal(
|
183
|
+
get_metadata_markup(entry),
|
184
|
+
title='Testcase metadata',
|
185
|
+
)
|
186
|
+
)
|
rbx/box/ui/screens/selector.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import List, Optional
|
2
2
|
|
3
3
|
from textual.app import ComposeResult
|
4
|
+
from textual.containers import Container
|
4
5
|
from textual.screen import ModalScreen
|
5
6
|
from textual.widgets import ListItem, ListView
|
6
7
|
|
@@ -14,10 +15,11 @@ class SelectorScreen(ModalScreen[int]):
|
|
14
15
|
self.title = title
|
15
16
|
|
16
17
|
def compose(self) -> ComposeResult:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
with Container(id='selector-dialog'):
|
19
|
+
list_view = ListView(*self.options)
|
20
|
+
if self.title:
|
21
|
+
list_view.border_title = self.title
|
22
|
+
yield list_view
|
21
23
|
|
22
24
|
def on_list_view_selected(self, event: ListView.Selected):
|
23
25
|
self.dismiss(event.list_view.index)
|
@@ -11,6 +11,7 @@ from rbx.box.testcase_extractors import (
|
|
11
11
|
GenerationTestcaseEntry,
|
12
12
|
extract_generation_testcases_from_groups,
|
13
13
|
)
|
14
|
+
from rbx.box.ui.utils.run_ui import get_metadata_markup
|
14
15
|
from rbx.box.ui.widgets.file_log import FileLog
|
15
16
|
from rbx.box.ui.widgets.rich_log_box import RichLogBox
|
16
17
|
from rbx.box.ui.widgets.test_output_box import TestBoxWidget, TestcaseRenderingData
|
@@ -78,19 +79,7 @@ class TestExplorerScreen(Screen):
|
|
78
79
|
)
|
79
80
|
|
80
81
|
metadata.clear()
|
81
|
-
metadata.write(
|
82
|
-
f'[bold]{entry.group_entry.group}[/bold] / [bold]{entry.group_entry.index}[/bold]'
|
83
|
-
)
|
84
|
-
if entry.metadata.copied_from is not None:
|
85
|
-
metadata.write(
|
86
|
-
f'[bold]Copied from:[/bold] {entry.metadata.copied_from.inputPath}'
|
87
|
-
)
|
88
|
-
if entry.metadata.generator_call is not None:
|
89
|
-
metadata.write(f'[bold]Gen. call:[/bold] {entry.metadata.generator_call}')
|
90
|
-
if entry.metadata.generator_script is not None:
|
91
|
-
metadata.write(
|
92
|
-
f'[bold]Gen. script:[/bold] {entry.metadata.generator_script}'
|
93
|
-
)
|
82
|
+
metadata.write(get_metadata_markup(entry))
|
94
83
|
|
95
84
|
async def _update_tests(self):
|
96
85
|
self.watch(
|
rbx/box/ui/utils/run_ui.py
CHANGED
@@ -4,6 +4,7 @@ from typing import List, Optional
|
|
4
4
|
from rbx import utils
|
5
5
|
from rbx.box import package, solutions
|
6
6
|
from rbx.box.solutions import SolutionReportSkeleton, SolutionSkeleton
|
7
|
+
from rbx.box.testcase_extractors import GenerationTestcaseEntry
|
7
8
|
from rbx.box.testcase_utils import TestcaseEntry
|
8
9
|
from rbx.grading.steps import Evaluation
|
9
10
|
|
@@ -93,3 +94,15 @@ def get_run_testcase_metadata_markup(
|
|
93
94
|
if checker_msg is not None:
|
94
95
|
lines.append(f'[b]Checker:[/b] {checker_msg}')
|
95
96
|
return '\n'.join(lines)
|
97
|
+
|
98
|
+
|
99
|
+
def get_metadata_markup(entry: GenerationTestcaseEntry) -> str:
|
100
|
+
lines = []
|
101
|
+
lines.append(f'[b]{entry.group_entry.group}[/b] / [b]{entry.group_entry.index}[/b]')
|
102
|
+
if entry.metadata.copied_from is not None:
|
103
|
+
lines.append(f'[b]Copied from:[/b] {entry.metadata.copied_from.inputPath}')
|
104
|
+
if entry.metadata.generator_call is not None:
|
105
|
+
lines.append(f'[b]Gen. call:[/b] {entry.metadata.generator_call}')
|
106
|
+
if entry.metadata.generator_script is not None:
|
107
|
+
lines.append(f'[b]Gen. script:[/b] {entry.metadata.generator_script}')
|
108
|
+
return '\n'.join(lines)
|
rbx/box/unit.py
CHANGED
@@ -14,6 +14,7 @@ from rbx.box.schema import (
|
|
14
14
|
ValidatorOutcome,
|
15
15
|
ValidatorTest,
|
16
16
|
)
|
17
|
+
from rbx.grading.steps import Outcome
|
17
18
|
from rbx.utils import StatusProgress
|
18
19
|
|
19
20
|
|
@@ -181,6 +182,39 @@ async def run_checker_unit_tests(progress: StatusProgress):
|
|
181
182
|
skip_run_log=True,
|
182
183
|
)
|
183
184
|
|
185
|
+
if test.answer is not None:
|
186
|
+
ans_result = await checkers.check(
|
187
|
+
compiled_digest,
|
188
|
+
run_log=None,
|
189
|
+
testcase=Testcase(
|
190
|
+
inputPath=test.input or empty_file,
|
191
|
+
outputPath=test.answer,
|
192
|
+
),
|
193
|
+
program_output=test.answer,
|
194
|
+
skip_run_log=True,
|
195
|
+
)
|
196
|
+
|
197
|
+
if ans_result.outcome != Outcome.ACCEPTED:
|
198
|
+
console.console.print(
|
199
|
+
f'[error]FAIL[/error] Unit test [item]#{i + 1}[/item] ({test.running_tests_formatted_string()})'
|
200
|
+
)
|
201
|
+
console.console.print(
|
202
|
+
'[error]Error validating the [item].ans[/item] file.'
|
203
|
+
)
|
204
|
+
console.console.print(
|
205
|
+
'[error]While checking your [item].ans[/item] against itself, the checker returned the following error:[/error]'
|
206
|
+
)
|
207
|
+
console.console.print(
|
208
|
+
f' [status]Verdict[/status] {ans_result.outcome.name}'
|
209
|
+
)
|
210
|
+
console.console.print(
|
211
|
+
f' [status]Message[/status] {ans_result.message}'
|
212
|
+
)
|
213
|
+
console.console.print(
|
214
|
+
'[error]Please fix your [item].ans[/item] file and try again, or double-check that your checker is correct.[/error]'
|
215
|
+
)
|
216
|
+
continue
|
217
|
+
|
184
218
|
markup = (
|
185
219
|
'[success]OK[/success]'
|
186
220
|
if test.outcome.match(result.outcome)
|
rbx/grading/steps.py
CHANGED
@@ -34,6 +34,7 @@ class Outcome(Enum):
|
|
34
34
|
WRONG_ANSWER = 'wrong-answer'
|
35
35
|
MEMORY_LIMIT_EXCEEDED = 'memory-limit-exceeded'
|
36
36
|
TIME_LIMIT_EXCEEDED = 'time-limit-exceeded'
|
37
|
+
IDLENESS_LIMIT_EXCEEDED = 'idleness-limit-exceeded'
|
37
38
|
RUNTIME_ERROR = 'runtime-error'
|
38
39
|
OUTPUT_LIMIT_EXCEEDED = 'output-limit-exceeded'
|
39
40
|
JUDGE_FAILED = 'judge-failed'
|
@@ -46,6 +47,12 @@ class Outcome(Enum):
|
|
46
47
|
|
47
48
|
return max(outcomes, key=_outcome_to_int)
|
48
49
|
|
50
|
+
def is_slow(self) -> bool:
|
51
|
+
return self in [
|
52
|
+
Outcome.TIME_LIMIT_EXCEEDED,
|
53
|
+
Outcome.IDLENESS_LIMIT_EXCEEDED,
|
54
|
+
]
|
55
|
+
|
49
56
|
|
50
57
|
class DigestHolder(BaseModel):
|
51
58
|
value: Optional[str] = None
|
@@ -107,8 +107,13 @@ cdir=$(pwd)
|
|
107
107
|
echo "Current directory is $cdir" >&2
|
108
108
|
|
109
109
|
# Make sure the class name is Main.
|
110
|
-
|
111
|
-
|
110
|
+
regex="public[[:space:]]+class[[:space:]]+[A-Za-z0-9_\\$]+([^A-Za-z0-9_\\$])"
|
111
|
+
klass=$(basename "$name" .java)
|
112
|
+
if [ -n "$(sed -n -E "/$regex/p" src/$name)" ]; then
|
113
|
+
klass="Main"
|
114
|
+
mv "src/$name" "src/Main.java"
|
115
|
+
sed -i -E "s/$regex/public class Main\1/" src/Main.java
|
116
|
+
fi
|
112
117
|
|
113
118
|
cat <<EOF >compileit.sh
|
114
119
|
#!/bin/bash
|
@@ -126,8 +131,8 @@ if [ ! -x \$jar ]; then
|
|
126
131
|
fi
|
127
132
|
export CLASSPATH=.:\$CLASSPATH
|
128
133
|
cd src
|
129
|
-
if [ -r "
|
130
|
-
\$javac
|
134
|
+
if [ -r "\$klass.java" ]; then
|
135
|
+
\$javac \$klass.java
|
131
136
|
echo \$? > ../compileit.retcode
|
132
137
|
fi
|
133
138
|
find . -name "*.java" | while read lin; do
|
@@ -135,7 +140,7 @@ find . -name "*.java" | while read lin; do
|
|
135
140
|
echo \$? > ../compileit.retcode
|
136
141
|
done
|
137
142
|
rm -f ../$jarfile
|
138
|
-
\$jar cvfe ../$jarfile
|
143
|
+
\$jar cvfe ../$jarfile \$klass *
|
139
144
|
exit 0
|
140
145
|
EOF
|
141
146
|
chmod 755 compileit.sh
|
@@ -42,47 +42,47 @@
|
|
42
42
|
umask 0022
|
43
43
|
|
44
44
|
if [ "$1" == "" ]; then
|
45
|
-
|
46
|
-
|
45
|
+
echo "parameter problem"
|
46
|
+
exit 43
|
47
47
|
fi
|
48
48
|
if [ ! -r "$1" ]; then
|
49
|
-
|
50
|
-
|
49
|
+
echo "$1 not found or it's not readable"
|
50
|
+
exit 44
|
51
51
|
fi
|
52
52
|
name="$1"
|
53
53
|
if [ ! -r "$1" ]; then
|
54
|
-
|
55
|
-
|
54
|
+
echo "$1 not found or it's not readable"
|
55
|
+
exit 44
|
56
56
|
fi
|
57
57
|
mkdir -p src
|
58
58
|
if [ "${name##*.}" == "zip" -a "${name##*.}" == "ZIP" ]; then
|
59
|
-
|
60
|
-
|
59
|
+
unzip "$name" -d src
|
60
|
+
name="*.c"
|
61
61
|
else
|
62
|
-
|
62
|
+
cp "$name" src
|
63
63
|
fi
|
64
64
|
id -u bocajail >/dev/null 2>/dev/null
|
65
65
|
if [ $? == 0 ]; then
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
bocau=$(id -u bocajail)
|
67
|
+
bocag=$(id -g bocajail)
|
68
|
+
chown bocajail.nogroup .
|
69
69
|
else
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
bocau=$(id -u nobody)
|
71
|
+
bocag=$(id -g nobody)
|
72
|
+
chown nobody.nogroup .
|
73
73
|
fi
|
74
74
|
if [ "$bocau" == "" -o "$bocag" == "" ]; then
|
75
|
-
|
76
|
-
|
75
|
+
echo "error finding user to run script"
|
76
|
+
exit 43
|
77
77
|
fi
|
78
78
|
|
79
79
|
# this script makes use of safeexec to execute the code with less privilegies
|
80
80
|
# make sure that directories below are correct.
|
81
|
-
sf
|
81
|
+
sf=$(which safeexec)
|
82
82
|
[ -x "$sf" ] || sf=/usr/bin/safeexec
|
83
83
|
if [ ! -x $sf ]; then
|
84
|
-
|
85
|
-
|
84
|
+
echo "$sf not found or it's not executable"
|
85
|
+
exit 46
|
86
86
|
fi
|
87
87
|
maxm=512000
|
88
88
|
if [ "$4" != "" ]; then
|
@@ -93,9 +93,9 @@ fi
|
|
93
93
|
|
94
94
|
# setting up the timelimit according to the problem
|
95
95
|
if [ "$3" == "" ]; then
|
96
|
-
time=5
|
96
|
+
time=5
|
97
97
|
else
|
98
|
-
time=$3
|
98
|
+
time=$3
|
99
99
|
fi
|
100
100
|
let "ttime = $time + 30"
|
101
101
|
|
@@ -106,7 +106,7 @@ else
|
|
106
106
|
fi
|
107
107
|
|
108
108
|
rm -f "$exe" compileit.retcode runit.retcode 2>/dev/null
|
109
|
-
cat <<EOF >
|
109
|
+
cat <<EOF >compileit.sh
|
110
110
|
#!/bin/bash
|
111
111
|
cc=\`which python2\`
|
112
112
|
[ -x "\$cc" ] || cc=/usr/bin/python2
|
@@ -115,6 +115,14 @@ if [ ! -x "\$cc" ]; then
|
|
115
115
|
exit 47
|
116
116
|
fi
|
117
117
|
cd src
|
118
|
+
"\$cc" -m py_compile "$name"
|
119
|
+
pyc_ret=\$?
|
120
|
+
if [ "\$pyc_ret" != "0" ]; then
|
121
|
+
echo "python syntax check failed: \$pyc_ret"
|
122
|
+
echo \$pyc_ret > ../compileit.retcode
|
123
|
+
exit 0
|
124
|
+
fi
|
125
|
+
|
118
126
|
echo "#!/usr/bin/python2" | cat - "$name" > "../$exe"
|
119
127
|
chmod 755 "../$exe"
|
120
128
|
echo \$? > ../compileit.retcode
|
@@ -122,13 +130,13 @@ exit 0
|
|
122
130
|
EOF
|
123
131
|
chmod 755 compileit.sh
|
124
132
|
|
125
|
-
cdir
|
133
|
+
cdir=$(pwd)
|
126
134
|
echo "Current directory is $cdir" >&2
|
127
135
|
echo $cdir | grep -q "/bocajail"
|
128
136
|
if [ $? == 0 ]; then
|
129
|
-
|
130
|
-
|
131
|
-
|
137
|
+
cdir=$(echo $cdir | sed "s/.*\/bocajail//")
|
138
|
+
echo "Internal directory is $cdir"
|
139
|
+
cat <<EOF >runit.sh
|
132
140
|
#!/bin/bash
|
133
141
|
cd "$cdir"
|
134
142
|
[ -f /proc/cpuinfo ] || /bin/mount -t proc proc /proc
|
@@ -142,32 +150,32 @@ if [ ! -d /bocajail ]; then
|
|
142
150
|
/bin/umount /sys 2>/dev/null
|
143
151
|
fi
|
144
152
|
EOF
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
153
|
+
chmod 755 runit.sh
|
154
|
+
chroot /bocajail "$cdir/runit.sh"
|
155
|
+
if [ -r runit.retcode ]; then
|
156
|
+
ret=$(cat runit.retcode)
|
157
|
+
else
|
158
|
+
ret=99
|
159
|
+
fi
|
152
160
|
else
|
153
|
-
|
154
|
-
|
155
|
-
|
161
|
+
echo "COMPILATION IS NOT BEING CHROOTED -- THIS IS NOT AN IDEAL SETTING"
|
162
|
+
$sf -r1 -F1000 -n0 -U$bocau -G$bocag -C. -ostdout0 -estderr0 -d$maxm -m$maxm -f20000 -t$ttime -T$ttime ./compileit.sh
|
163
|
+
ret=$?
|
156
164
|
fi
|
157
165
|
if [ -f "stdout0" ]; then
|
158
|
-
|
166
|
+
cat "stdout0"
|
159
167
|
fi
|
160
168
|
if [ -f "stderr0" ]; then
|
161
|
-
|
169
|
+
cat "stderr0"
|
162
170
|
fi
|
163
171
|
rm -rf src/
|
164
172
|
if [ "$ret" != "0" ]; then
|
165
|
-
|
166
|
-
|
173
|
+
echo "Compilation Error: $ret"
|
174
|
+
exit $ret
|
167
175
|
fi
|
168
|
-
ret
|
176
|
+
ret=$(cat compileit.retcode)
|
169
177
|
if [ "$ret" != "0" ]; then
|
170
|
-
|
171
|
-
|
178
|
+
echo "Compilation Error: $ret"
|
179
|
+
ret=1
|
172
180
|
fi
|
173
181
|
exit $ret
|