Skip to content

Commit

Permalink
Merge branch 'main' into undocumented-options
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/sinol_make/helpers/package_util.py
#	tests/util.py
  • Loading branch information
MasloMaslane committed Sep 19, 2023
2 parents 388af9b + 8adc34e commit 34a30b2
Show file tree
Hide file tree
Showing 31 changed files with 409 additions and 145 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/Arch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Prepare system
run: |
sysctl kernel.perf_event_paranoid=-1
pacman -Syu --noconfirm diffutils time gcc dpkg
pacman -Syu --noconfirm diffutils time gcc dpkg ghostscript texlive-latexextra
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/Ubuntu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
- /home/actions/oiejq:/github/home/.local/bin
env:
DEB_PYTHON_INSTALL_LAYOUT: deb
DEBIAN_FRONTEND: noninteractive
TZ: Europe/Warsaw
options:
--privileged
steps:
Expand All @@ -22,7 +24,7 @@ jobs:
- name: Prepare system
run: |
apt update
apt install -y sqlite3 sqlite3-doc build-essential dpkg
apt install -y sqlite3 sqlite3-doc build-essential dpkg texlive-latex-extra ghostscript
sysctl kernel.perf_event_paranoid=-1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macOS.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
run: |
rm -f /usr/local/bin/2to3* /usr/local/bin/python3* /usr/local/bin/idle3* \
/usr/local/bin/pydoc3* # Homebrew will fail if these exist
brew install gnu-time coreutils diffutils dpkg
brew install gnu-time coreutils diffutils dpkg ghostscript texlive
- name: Install Python dependencies
run: |
python3 -m pip install .[tests]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ You can also specify your ingen source file which will be used. Run `sinol-make
- `sinol-make inwer` -- Verifies whether input files are correct using your "inwer.cpp" program. You can specify what inwer
program to use, what tests to check and how many CPUs to use. Run `sinol-make inwer --help` to see available flags.
- `sinol-make export` -- Creates archive ready to upload to sio2 or szkopul. Run `sinol-make export --help` to see all available flags.
- `sinol-make doc` -- Compiles all LaTeX files in doc/ directory to PDF. Run `sinol-make doc --help` to see all available flags.

### Reporting bugs and contributing code

Expand Down
4 changes: 3 additions & 1 deletion src/sinol_make/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

from sinol_make import util, oiejq

__version__ = "1.5.6"

__version__ = "1.5.7"


def configure_parsers():
parser = argparse.ArgumentParser(
Expand Down
71 changes: 71 additions & 0 deletions src/sinol_make/commands/doc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import os
import glob
import argparse
import subprocess

from sinol_make import util
from sinol_make.interfaces.BaseCommand import BaseCommand


class Command(BaseCommand):
"""
Class for `doc` command.
"""

def get_name(self):
return "doc"

def compile_file(self, file_path):
print(util.info(f'Compiling {os.path.basename(file_path)}...'))
os.chdir(os.path.dirname(file_path))
subprocess.run(['latex', file_path])
dvi_file = os.path.splitext(file_path)[0] + '.dvi'
dvi_file_path = os.path.join(os.path.dirname(file_path), dvi_file)
if not os.path.exists(dvi_file_path):
print(util.error('Compilation failed.'))
return False

process = subprocess.run(['dvipdf', dvi_file_path])
if process.returncode != 0:
print(util.error('Compilation failed.'))
return False
print(util.info(f'Compilation successful for file {os.path.basename(file_path)}.'))
return True

def configure_subparser(self, subparser: argparse.ArgumentParser):
parser = subparser.add_parser(
self.get_name(),
help='Compile latex files to pdf',
description='Compiles latex files to pdf. By default compiles all files in the `doc` directory.\n'
'You can also specify files to compile.')
parser.add_argument('files', type=str, nargs='*', help='files to compile')

def run(self, args: argparse.Namespace):
util.exit_if_not_package()

if args.files == []:
self.files = glob.glob(os.path.join(os.getcwd(), 'doc', '*.tex'))
else:
self.files = []
for file in args.files:
if not os.path.exists(file):
print(util.warning(f'File {file} does not exist.'))
else:
self.files.append(os.path.abspath(file))
if self.files == []:
print(util.warning('No files to compile.'))
return

original_cwd = os.getcwd()
failed = []
for file in self.files:
if not self.compile_file(file):
failed.append(file)
os.chdir(original_cwd)

if failed:
for failed_file in failed:
print(util.error(f'Failed to compile {failed_file}'))
util.exit_with_error('Compilation failed.')
else:
print(util.info('Compilation was successful for all files.'))
20 changes: 16 additions & 4 deletions src/sinol_make/commands/export/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def get_generated_tests(self):
util.exit_with_error('Failed to run ingen.')

tests = glob.glob(os.path.join(working_dir, f'{self.task_id}*.in'))
return [package_util.extract_test_id(test) for test in tests]
return [package_util.extract_test_id(test, self.task_id) for test in tests]

def copy_package_required_files(self, target_dir: str):
"""
Expand Down Expand Up @@ -74,7 +74,7 @@ def copy_package_required_files(self, target_dir: str):
tests_to_copy = []
for ext in ['in', 'out']:
for test in glob.glob(os.path.join(os.getcwd(), ext, f'{self.task_id}*.{ext}')):
if package_util.extract_test_id(test) not in generated_tests:
if package_util.extract_test_id(test, self.task_id) not in generated_tests:
tests_to_copy.append(test)

if len(tests_to_copy) > 0:
Expand All @@ -83,15 +83,25 @@ def copy_package_required_files(self, target_dir: str):
print(util.warning(f'Coping {os.path.basename(test)}...'))
shutil.copy(test, os.path.join(target_dir, os.path.splitext(os.path.basename(test))[1]))

def clear_files(self, target_dir: str):
"""
Clears unnecessary files from target directory.
:param target_dir: Directory to clear files from.
"""
files_to_remove = ['doc/*~', 'doc/*.aux', 'doc/*.log', 'doc/*.dvi', 'doc/*.err', 'doc/*.inf']
for pattern in files_to_remove:
for f in glob.glob(os.path.join(target_dir, pattern)):
os.remove(f)

def create_makefile_in(self, target_dir: str, config: dict):
"""
Creates required `makefile.in` file.
:param target_dir: Directory to create files in.
:param config: Config dictionary.
"""
with open(os.path.join(target_dir, 'makefile.in'), 'w') as f:
cxx_flags = '-std=c++17'
c_flags = '-std=c17'
cxx_flags = '-std=c++20'
c_flags = '-std=gnu99'
def format_multiple_arguments(obj):
if isinstance(obj, str):
return obj
Expand Down Expand Up @@ -132,6 +142,7 @@ def run(self, args: argparse.Namespace):

self.args = args
self.task_id = package_util.get_task_id()
package_util.validate_test_names(self.task_id)

with open(os.path.join(os.getcwd(), 'config.yml'), 'r') as config_file:
config = yaml.load(config_file, Loader=yaml.FullLoader)
Expand All @@ -143,6 +154,7 @@ def run(self, args: argparse.Namespace):

util.change_stack_size_to_unlimited()
self.copy_package_required_files(export_package_path)
self.clear_files(export_package_path)
self.create_makefile_in(export_package_path, config)
archive = self.compress(export_package_path)

Expand Down
1 change: 1 addition & 0 deletions src/sinol_make/commands/gen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def run(self, args: argparse.Namespace):

self.args = args
self.task_id = package_util.get_task_id()
package_util.validate_test_names(self.task_id)
self.ingen = gen_util.get_ingen(self.task_id, args.ingen_path)
print(util.info(f'Using ingen file {os.path.basename(self.ingen)}'))

Expand Down
13 changes: 5 additions & 8 deletions src/sinol_make/commands/gen/gen_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ def ingen_exists(task_id):
:param task_id: task id, for example abc
:return: True if exists, False otherwise
"""
return len(glob.glob(os.path.join(os.getcwd(), 'prog', task_id + 'ingen.*'))) > 0
return package_util.any_files_matching_pattern(task_id, f'{task_id}ingen.*')


def get_ingen(task_id=None, ingen_path=None):
def get_ingen(task_id, ingen_path=None):
"""
Find ingen source file in `prog/` directory.
If `ingen_path` is specified, then it will be used (if exists).
:param task_id: task id, for example abc. If None, then
will return any ingen matching "*ingen.*"
:param task_id: task id, for example abc.
:param ingen_path: path to ingen source file
:return: path to ingen source file or None if not found
"""
Expand All @@ -35,9 +34,7 @@ def get_ingen(task_id=None, ingen_path=None):
else:
util.exit_with_error(f'Ingen source file {ingen_path} does not exist.')

if task_id is None:
task_id = '*'
ingen = glob.glob(os.path.join(os.getcwd(), 'prog', task_id + 'ingen.*'))
ingen = package_util.get_files_matching_pattern(task_id, f'{task_id}ingen.*')
if len(ingen) == 0:
util.exit_with_error(f'Ingen source file for task {task_id} does not exist.')

Expand Down Expand Up @@ -78,7 +75,7 @@ def get_correct_solution(task_id):
:param task_id: task id, for example abc
:return: path to correct solution or None if not found
"""
correct_solution = glob.glob(os.path.join(os.getcwd(), 'prog', task_id + '.*'))
correct_solution = package_util.get_files_matching_pattern(task_id, f'{task_id}.*')
if len(correct_solution) == 0:
util.exit_with_error(f'Correct solution for task {task_id} does not exist.')
return correct_solution[0]
Expand Down
5 changes: 3 additions & 2 deletions src/sinol_make/commands/inwer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def verify_and_print_table(self) -> Dict[str, TestResult]:
sorted_tests = sorted(self.tests, key=lambda x: x[0])
executions: List[InwerExecution] = []
for test in sorted_tests:
results[test] = TestResult(test)
results[test] = TestResult(test, self.task_id)
executions.append(InwerExecution(test, results[test].test_name, self.inwer_executable))

has_terminal, terminal_width, terminal_height = util.get_terminal_size()
Expand Down Expand Up @@ -123,6 +123,7 @@ def run(self, args: argparse.Namespace):
util.exit_if_not_package()

self.task_id = package_util.get_task_id()
package_util.validate_test_names(self.task_id)
self.inwer = inwer_util.get_inwer_path(self.task_id, args.inwer_path)
if self.inwer is None:
if args.inwer_path is None:
Expand All @@ -133,7 +134,7 @@ def run(self, args: argparse.Namespace):
print(f'Verifying with inwer {util.bold(relative_path)}')

self.cpus = args.cpus or mp.cpu_count()
self.tests = package_util.get_tests(args.tests)
self.tests = package_util.get_tests(self.task_id, args.tests)

if len(self.tests) == 0:
util.exit_with_error('No tests found.')
Expand Down
2 changes: 1 addition & 1 deletion src/sinol_make/commands/inwer/inwer_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def get_inwer_path(task_id: str, path = None) -> Union[str, None]:
Returns path to inwer executable for given task or None if no inwer was found.
"""
if path is None:
inwers = glob.glob(os.path.join(os.getcwd(), 'prog', f'{task_id}inwer.*'))
inwers = package_util.get_files_matching_pattern(task_id, f'{task_id}inwer.*')
if len(inwers) == 0:
return None
return inwers[0]
Expand Down
4 changes: 2 additions & 2 deletions src/sinol_make/commands/inwer/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ class TestResult:
valid: bool
output: str

def __init__(self, test_path):
def __init__(self, test_path, task_id):
self.test_path = test_path
self.test_name = os.path.split(test_path)[-1]
self.test_group = str(package_util.get_group(self.test_path))
self.test_group = str(package_util.get_group(self.test_path, task_id))

self.verified = False
self.valid = False
Expand Down
Loading

0 comments on commit 34a30b2

Please sign in to comment.