Skip to content

Commit

Permalink
Merge pull request #8 from Stowarzyszenie-Talent/version-bump
Browse files Browse the repository at this point in the history
Version bump and merge upstream
  • Loading branch information
adespawn authored Feb 28, 2024
2 parents a8908b3 + 8dfcd34 commit 95888cf
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 40 deletions.
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# <img src="https://avatars.githubusercontent.com/u/93839068?s=200&v=4" height=60em> st-make
# ![Logo](https://avatars.githubusercontent.com/u/93839068?s=60&v=4) st-make

`st-make` is a CLI tool for creating and verifying problem packages
for [sio2](https://github.com/sio2project/oioioi)
with features such as:

- measuring time and memory in the same deterministic way as sio2,
- running the solutions in parallel,
- keeping a git-friendly report of solutions' scores,
Expand All @@ -11,12 +12,11 @@ with features such as:

This tool is a fork of [sinol-make](https://github.com/sio2project/sinol-make), with features specific to [Talent](https://talent.edu.pl/) contests.

# Contents
## Contents

- [Why?](#why)
- [Installation](#installation)
- [Usage](#usage)
- [Configuarion](#configuration)
- [Reporting bugs and contributing code](#reporting-bugs-and-contributing-code)

### Why?
Expand All @@ -36,9 +36,10 @@ solutions' runtime, called `oiejq`.
It's possible to directly install [st-make](https://pypi.org/project/st-make/)
through Python's package manager pip, which usually is installed alongside Python:

```
```bash
pip3 install st-make
```

`pip` installs the `st-make` executable in `~/.local/bin/` directory,
so make sure this directory is in your `PATH`.
[Here's](https://gist.github.com/nex3/c395b2f8fd4b02068be37c961301caa7) how to add a directory to `PATH`.
Expand All @@ -48,11 +49,12 @@ As `oiejq` works only on Linux-based operating systems,
Nevertheless `st-make` supports those operating systems,
though there are additional installation steps required to use
other tools for measuring time (which are non-deterministic and produce reports different from sio2):

- Debian-based systems (Ubuntu, usually Windows WSL): `apt install time`
- Arch-based systems: `pacman -S time`
- macOS: `brew install gnu-time coreutils`

### Autocompletion (optional)
#### Autocompletion (optional)

If you would like to have autocompletion for `st-make` commands,
run the following command and refresh the shell (e.g. by opening a new terminal):
Expand Down Expand Up @@ -81,8 +83,9 @@ Run `st-make ingen --help` to see available flags.
- `st-make outgen` -- Generate output files using the model solutions. Run `st-make outgen --help` to see available flags.
- `st-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 `st-make inwer --help` to see available flags.
- `st-make export` -- Creates archive ready to upload to sio2 or szkopul. Run `st-make export --help` to see all available flags.
- `st-make export` -- Creates archive ready to upload to Wyzwania, Talent-camp and other sio2 instances. Run `st-make export --help` to see all available flags.
- `st-make doc` -- Compiles all LaTeX files in doc/ directory to PDF. Run `st-make doc --help` to see all available flags.
- `st-make init [id]` -- Creates package from template [on github](https://github.com/Stowarzyszenie-Talent/st-make/tree/main/example_package) and sets task id to provided `[id]`. Requires an internet connection to run.

### Reporting bugs and contributing code

Expand Down
55 changes: 28 additions & 27 deletions src/sinol_make/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# PYTHON_ARGCOMPLETE_OK
import argparse
import traceback
from time import sleep

import argcomplete
import traceback
import argparse
import sys
import os

from sinol_make import util, oiejq


__version__ = "0.0.1"
__version__ = "0.0.2"


def configure_parsers():
Expand All @@ -34,48 +32,51 @@ def configure_parsers():
return parser


def check_oiejq():
if util.is_linux() and not oiejq.check_oiejq():
print(util.warning('`oiejq` in `~/.local/bin/` not found, installing now...'))
try:
if oiejq.install_oiejq():
print(util.info('`oiejq` was successfully installed.'))
else:
util.exit_with_error('`oiejq` could not be installed.\n'
'You can download it from https://oij.edu.pl/zawodnik/srodowisko/oiejq.tar.gz, '
'unpack it to `~/.local/bin/` and rename oiejq.sh to oiejq.\n'
'You can also use --oiejq-path to specify path to your oiejq.')
except Exception as err:
util.exit_with_error('`oiejq` could not be installed.\n' + err)


def main_exn():
parser = configure_parsers()
args = parser.parse_args()
commands = util.get_commands()

for command in commands:
if command.get_name() == args.command:
new_version = util.check_for_updates(__version__)
if new_version is not None:
print(util.warning(
f'New version of st-make is available (your version: {__version__}, available version: {new_version}).\n'
f' You can update it by running `pip3 install st-make --upgrade`.'))

if util.is_linux() and not oiejq.check_oiejq():
print(util.warning('`oiejq` in `~/.local/bin/` not found, installing now...'))

try:
if oiejq.install_oiejq():
print(util.info('`oiejq` was successfully installed.'))
else:
util.exit_with_error('`oiejq` could not be installed.\n'
'You can download it from https://oij.edu.pl/zawodnik/srodowisko/oiejq.tar.gz'
', unpack it to `~/.local/bin/` and rename oiejq.sh to oiejq.\n'
'You can also use --oiejq-path to specify path to your oiejq.')
except Exception as err:
util.exit_with_error('`oiejq` could not be installed.\n' + err)

check_oiejq()
command.run(args)
exit(0)

parser.print_help()


def main():
new_version = None
try:
new_version = util.check_for_updates(__version__)
main_exn()
except argparse.ArgumentError as err:
util.exit_with_error(err)
except SystemExit as err:
exit(err.code)
except:
except Exception:
print(traceback.format_exc())
util.exit_with_error('An error occurred while running the command.\n'
'If that is a bug, please report it or submit a bugfix: '
'https://github.com/Stowarzyszenie-Talent/st-make/#reporting-bugs-and-contributing-code')
finally:
if new_version is not None:
print(util.warning(
f'New version of sinol-make is available (your version: {__version__}, available version: '
f'{new_version}).\nYou can update it by running `pip3 install sinol-make --upgrade`.'))
44 changes: 39 additions & 5 deletions src/sinol_make/commands/doc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class Command(BaseCommand):
def get_name(self):
return "doc"

def compile_file(self, file_path):
print(util.info(f'Compiling {os.path.basename(file_path)}...'))
def compile_file_latex_div(self, file_path):
print(util.info(f'Compiling {os.path.basename(file_path)} (latex to dvi)...'))
os.chdir(os.path.dirname(file_path))
subprocess.run(['latex', file_path])
dvi_file = os.path.splitext(file_path)[0] + '.dvi'
Expand All @@ -34,13 +34,27 @@ def compile_file(self, file_path):
print(util.info(f'Compilation successful for file {os.path.basename(file_path)}.'))
return True

def compile_pdf_latex(self, file_path):
print(util.info(f'Compiling {os.path.basename(file_path)} (pdflatex)...'))
os.chdir(os.path.dirname(file_path))
subprocess.run(['pdflatex', file_path])
pdf_file = os.path.splitext(file_path)[0] + '.pdf'
pdf_file_path = os.path.join(os.path.dirname(file_path), pdf_file)
if not os.path.exists(pdf_file_path):
print(util.error('Compilation failed.'))
return False
return True

def make_file(self, file_path):
"""
Compile the file two times to get the references right.
"""
if not self.compile_file(file_path):
return False
return self.compile_file(file_path)
if self.compilation_method == 'pdflatex':
return self.compile_pdf_latex(file_path)
else:
if not self.compile_file_latex_div(file_path):
return False
return self.compile_file_latex_div(file_path)

def move_logs(self):
output_dir = paths.get_cache_path('doc_logs')
Expand All @@ -56,11 +70,31 @@ def configure_subparser(self, subparser: argparse.ArgumentParser):
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('--latex-compiler', dest='latex_compiler', choices=['auto', 'pdflatex', 'latex_dvi'],
help='Compiler used to compile documents. Available options:\n'
' auto - uses the compiler based on the image types (default option).\n'
' pdflatex - uses pdflatex. Works with .png and .jpg images.\n'
' latex_dvi - uses latex and dvipdf. Works with .ps and .eps images.', default='auto')
parser.add_argument('files', type=str, nargs='*', help='files to compile')

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

if not hasattr(args, 'latex_compiler'):
args.latex_compiler = 'auto'

if args.latex_compiler == 'pdflatex':
self.compilation_method = 'pdflatex'
elif args.latex_compiler == 'latex_dvi':
self.compilation_method = 'latex_dvi'
elif args.latex_compiler == 'auto':
self.compilation_method = 'pdflatex'
for extension in ['ps', 'eps']:
if glob.glob(os.path.join(os.getcwd(), 'doc', f'*.{extension}')) != []:
self.compilation_method = 'latex_dvi'
else:
util.exit_with_error("Unrecognized latex compiler")

if args.files == []:
self.files = glob.glob(os.path.join(os.getcwd(), 'doc', '*.tex'))
else:
Expand Down
52 changes: 52 additions & 0 deletions tests/commands/doc/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,62 @@ def test_argument(capsys, create_package):
command.run(args)
out = capsys.readouterr().out
assert "Compilation was successful for all files." in out
assert "pdflatex" in out # In auto mode this command will use pdflatex

logs_exist = False
logs_dir = paths.get_cache_path('doc_logs')
for pattern in command.LOG_PATTERNS:
assert glob.glob(os.path.join(os.getcwd(), 'doc', pattern)) == []
logs_exist = logs_exist | (glob.glob(os.path.join(logs_dir, pattern)) != [])
assert logs_exist

def run_doc(capsys, command_args, expected, not_expected):
"""
Run doc command
"""
parser = configure_parsers()
args = parser.parse_args(command_args)
command = Command()
command.run(args)
out = capsys.readouterr().out
assert "Compilation was successful for all files." in out
assert expected in out
assert not_expected not in out

@pytest.mark.parametrize("create_package", [util.get_ps_doc_package_path()], indirect=True)
def test_ps_images(capsys, create_package):
"""
Test `doc` command with ps images.
"""
run_doc(
capsys=capsys,
command_args=["doc"],
expected="latex to dvi", # In auto mode this command should use latex and dvipdf
not_expected="pdflatex" # and shouldn't use pdflatex for any compilation
)


@pytest.mark.parametrize("create_package", [util.get_ps_doc_package_path()], indirect=True)
def test_compilation_mode(capsys, create_package):
"""
Test `doc` with compilation mode directly specified.
"""
run_doc(
capsys=capsys,
command_args=["doc", "doc/doczad.tex", "--latex-compiler", "pdflatex"],
expected="pdflatex",
not_expected="latex to dvi"
)


@pytest.mark.parametrize("create_package", [util.get_doc_package_path()], indirect=True)
def test_compilation_mode_2(capsys, create_package):
"""
Test `doc` with compilation mode directly specified.
"""
run_doc(
capsys=capsys,
command_args=["doc", "doc/doczad.tex", "--latex-compiler", "latex_dvi"],
expected="latex to dvi",
not_expected="pdflatex"
)
9 changes: 7 additions & 2 deletions tests/commands/doc/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@


@pytest.mark.parametrize("create_package", [util.get_doc_package_path()], indirect=True)
def test_compile_file(create_package):
def test_compile_pdf_latex(create_package):
command = Command()
assert command.compile_file(os.path.abspath(os.path.join(os.getcwd(), "doc/doczad.tex"))) is True
assert command.compile_pdf_latex(os.path.abspath(os.path.join(os.getcwd(), "doc/doczad.tex"))) is True

@pytest.mark.parametrize("create_package", [util.get_doc_package_path()], indirect=True)
def test_compile_file_latex_div(create_package):
command = Command()
assert command.compile_file_latex_div(os.path.abspath(os.path.join(os.getcwd(), "doc/doczad.tex"))) is True
5 changes: 5 additions & 0 deletions tests/packages/doc/doc/doctest.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{test_image.png}
\end{document}
Binary file added tests/packages/doc/doc/test_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions tests/packages/ps_doc/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
title: Package for testing `doc` command (version with ps images)
time_limit: 1000
memory_limit: 1024
sinol_task_id: doc2
5 changes: 5 additions & 0 deletions tests/packages/ps_doc/doc/doctest.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{test_image.ps}
\end{document}
4 changes: 4 additions & 0 deletions tests/packages/ps_doc/doc/doczad.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
\documentclass{article}
\begin{document}
Hello World!
\end{document}
Binary file added tests/packages/ps_doc/doc/test_image.ps
Binary file not shown.
Empty file.
Empty file.
7 changes: 7 additions & 0 deletions tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ def get_doc_package_path():
return os.path.join(os.path.dirname(__file__), "packages", "doc")


def get_ps_doc_package_path():
"""
Get path to package for testing `doc` command (version with ps images) (/test/packages/ps_doc)
"""
return os.path.join(os.path.dirname(__file__), "packages", "ps_doc")


def get_long_name_package_path():
"""
Get path to package with long name (/test/packages/long_package_name)
Expand Down

0 comments on commit 95888cf

Please sign in to comment.