Skip to content

Use oicompare as the default checker #261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/sinol_make/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import argcomplete

from sinol_make import util, sio2jail
from sinol_make.helpers import cache
from sinol_make.helpers import cache, oicompare

# Required for side effects
from sinol_make.task_type.normal import NormalTaskType # noqa
from sinol_make.task_type.interactive import InteractiveTaskType # noqa


__version__ = "1.8.2"
__version__ = "1.8.3"


def configure_parsers():
Expand Down Expand Up @@ -76,6 +76,7 @@ def main_exn():
parser.print_help()
exit(1)
check_sio2jail()
oicompare.check_and_download()

for curr_args in arguments:
args = parser.parse_args(curr_args)
Expand Down
56 changes: 56 additions & 0 deletions src/sinol_make/helpers/oicompare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import requests
import subprocess

from sinol_make import util


__OICOMAPRE_VERSION = 'v1.0.2'


def get_path():
return os.path.expanduser('~/.local/bin/oicompare')


def check_installed():
path = get_path()
if not os.path.exists(path):
return False
try:
output = subprocess.run([path, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except PermissionError:
return False
if output.returncode != 0:
return False
if output.stdout.decode().strip() != f'oicompare version {__OICOMAPRE_VERSION[1:]}':
return False
return True


def download_oicomapare():
url = f'https://github.com/sio2project/oicompare/releases/download/{__OICOMAPRE_VERSION}/oicompare'
if util.is_macos_arm():
url += '-arm64'
path = get_path()
os.makedirs(os.path.dirname(path), exist_ok=True)
manual_download_msg = ("You can try downloading it manually from "
f"https://github.com/sio2project/oicompare/releases/tag/{__OICOMAPRE_VERSION}/ and placing "
f"it in ~/.local/bin/oicomapre")
try:
request = requests.get(url)
except requests.exceptions.ConnectionError:
util.exit_with_error("Couldn't download oicompare (couldn't connect). " + manual_download_msg)
if request.status_code != 200:
util.exit_with_error(f"Couldn't download oicompare (returned status code: {request.status_code}). "
+ manual_download_msg)
with open(path, 'wb') as f:
f.write(request.content)
os.chmod(path, 0o755)


def check_and_download():
if check_installed():
return
download_oicomapare()
if not check_installed():
util.exit_with_error("Couldn't download oicompare. Please try again later or download it manually.")
21 changes: 20 additions & 1 deletion src/sinol_make/task_type/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from sinol_make import util
from sinol_make.executors.sio2jail import Sio2jailExecutor
from sinol_make.executors.time import TimeExecutor
from sinol_make.helpers import package_util, paths, cache
from sinol_make.helpers import package_util, paths, cache, oicompare
from sinol_make.helpers.classinit import RegisteredSubclassesBase
from sinol_make.interfaces.Errors import CheckerException
from sinol_make.structs.status_structs import ExecutionResult
Expand Down Expand Up @@ -162,6 +162,23 @@ def _run_diff(self, output_file_path, answer_file_path) -> Tuple[bool, Fraction,
else:
return False, Fraction(0, 1), ""

def _run_oicompare(self, output_file_path, answer_file_path) -> Tuple[bool, Fraction, str]:
path = oicompare.get_path()
proc = subprocess.Popen([path, output_file_path, answer_file_path, 'english_abbreviated'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.wait()
output, stderr = proc.communicate()
if proc.returncode == 0:
return True, Fraction(100, 1), ""
elif proc.returncode == 1:
return False, Fraction(0, 1), output.decode('utf-8').strip()
else:
raise CheckerException(f"!!! oicompare failed with code {proc.returncode}. This is a huge bug, please report"
f" it here https://github.com/sio2project/sinol-make/issues/new/choose and provide "
f"these files: {output_file_path}, {answer_file_path}.\n"
f"Output: {output.decode('utf-8').strip()}\n"
f"Stderr: {stderr.decode('utf-8').strip()}")

def check_output(self, input_file_path, output_file_path, answer_file_path) -> Tuple[bool, Fraction, str]:
"""
Runs the checker (or runs diff) and returns a tuple of three values:
Expand All @@ -171,6 +188,8 @@ def check_output(self, input_file_path, output_file_path, answer_file_path) -> T
"""
if self.has_checker:
return self._run_checker(input_file_path, output_file_path, answer_file_path)
elif oicompare.check_installed():
return self._run_oicompare(output_file_path, answer_file_path)
else:
return self._run_diff(output_file_path, answer_file_path)

Expand Down
4 changes: 3 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import multiprocessing as mp

from sinol_make import util
from sinol_make.helpers import compile, paths, cache
from sinol_make.helpers import compile, paths, cache, oicompare
from sinol_make.interfaces.Errors import CompilationError


Expand Down Expand Up @@ -91,6 +91,8 @@ def pytest_configure(config):
except FileNotFoundError:
pass

oicompare.check_and_download()


def pytest_generate_tests(metafunc):
if "time_tool" in metafunc.fixturenames:
Expand Down
Loading