Skip to content
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

[tools] Separate changing to contest directory and getting problems list #166

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
91 changes: 49 additions & 42 deletions bin/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,37 @@
# Make sure f-strings are supported.
f'f-strings are not supported by your python version. You need at least python 3.6.'

# Get the list of relevant problems.
# Either use the problems.yaml, or check the existence of problem.yaml and sort
# by shortname.
def get_problems():
def is_problem_directory(path):
return (path / 'problem.yaml').is_file()

contest = None
problem = None
level = None

# A path is a problem directory if it contains a `problem.yaml` file.
def is_problem_directory(path):
return (path / 'problem.yaml').is_file()


# Changes the working directory to the root of the contest.
# Returns the "level" of the current command (either 'problem' or 'problemset')
# and, if `level == 'problem'`, the directory of the problem.
def change_directory():
problem_dir = None
level = 'problemset'
if config.args.contest:
contest = config.args.contest.resolve()
os.chdir(contest)
level = 'problemset'
os.chdir(config.args.contest.resolve())
if config.args.problem:
problem = config.args.problem.resolve()
problem_dir = config.args.problem.resolve()
level = 'problem'
os.chdir(problem.parent)
os.chdir(problem_dir.parent)
elif is_problem_directory(Path('.')):
problem = Path().cwd()
problem_dir = Path().cwd()
level = 'problem'
os.chdir('..')
else:
level = 'problemset'

config.level = level
return problem_dir


# Get the list of relevant problems.
# Either use the problems.yaml,
# or check the existence of problem.yaml and sort by shortname.
def get_problems(problem_dir):
# We create one tmpdir per contest.
h = hashlib.sha256(bytes(Path().cwd())).hexdigest()[-6:]
tmpdir = Path(tempfile.gettempdir()) / ('bapctools_' + h)
mpsijm marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -135,24 +141,23 @@ def fallback_problems():
return problems

problems = []
if level == 'problem':
if config.level == 'problem':
# If the problem is mentioned in problems.yaml, use that ID.
problemsyaml = problems_yaml()
if problemsyaml:
problem_labels = parse_problems_yaml(problemsyaml)
for shortname, label in problem_labels:
if shortname == problem.name:
problems = [Problem(Path(problem.name), tmpdir, label)]
if shortname == problem_dir.name:
problems = [Problem(Path(problem_dir.name), tmpdir, label)]
break

if len(problems) == 0:
label = None
for p, l in fallback_problems():
if p.name == problem.name:
if p.name == problem_dir.name:
label = l
problems = [Problem(Path(problem.name), tmpdir, label)]
else:
level = 'problemset'
problems = [Problem(Path(problem_dir.name), tmpdir, label)]
else: # config.level = 'problemset'
# If problems.yaml is available, use it.
problemsyaml = problems_yaml()
if problemsyaml:
Expand Down Expand Up @@ -213,10 +218,8 @@ def get_pos(id):
order = ', '.join(map(lambda p: p.label, problems))
verbose('order: ' + order)

contest = Path().cwd().name

# Filter problems by submissions/testcases, if given.
if level == 'problemset' and (config.args.submissions or config.args.testcases):
if config.level == 'problemset' and (config.args.submissions or config.args.testcases):
submissions = config.args.submissions or []
testcases = config.args.testcases or []

Expand All @@ -233,8 +236,7 @@ def keep_problem(problem):

problems = [p for p in problems if keep_problem(p)]

config.level = level
return (problems, level, contest, tmpdir)
return problems, tmpdir


# NOTE: This is one of the few places that prints to stdout instead of stderr.
Expand Down Expand Up @@ -707,8 +709,11 @@ def run_parsed_arguments(args):
skel.new_problem()
return

# Get problem_paths and cd to contest
problems, level, contest, tmpdir = get_problems()
# Get problems list and cd to contest directory
problem_dir = change_directory()
level = config.level
contest_name = Path().cwd().name
problems, tmpdir = get_problems(problem_dir)

# Check for incompatible actions at the problem/problemset level.
if level != 'problem':
Expand Down Expand Up @@ -759,7 +764,7 @@ def run_parsed_arguments(args):
return

if action == 'gitlabci':
skel.create_gitlab_jobs(contest, problems)
skel.create_gitlab_jobs(contest_name, problems)
return

if action == 'skel':
Expand Down Expand Up @@ -853,30 +858,32 @@ def run_parsed_arguments(args):
print(file=sys.stderr)

if level == 'problemset':
print(f'{Style.BRIGHT}CONTEST {contest}{Style.RESET_ALL}', file=sys.stderr)
print(f'{Style.BRIGHT}CONTEST {contest_name}{Style.RESET_ALL}', file=sys.stderr)

# build pdf for the entire contest
if action in ['pdf']:
success &= latex.build_contest_pdf(contest, problems, tmpdir, web=config.args.web)
success &= latex.build_contest_pdf(contest_name, problems, tmpdir, web=config.args.web)

if action in ['solutions']:
success &= latex.build_contest_pdf(
contest, problems, tmpdir, solutions=True, web=config.args.web
contest_name, problems, tmpdir, solutions=True, web=config.args.web
)

if action in ['zip']:
if not config.args.kattis:
success &= latex.build_contest_pdf(contest, problems, tmpdir)
success &= latex.build_contest_pdf(contest, problems, tmpdir, web=True)
success &= latex.build_contest_pdf(contest_name, problems, tmpdir)
success &= latex.build_contest_pdf(contest_name, problems, tmpdir, web=True)
if not config.args.no_solutions:
success &= latex.build_contest_pdf(contest, problems, tmpdir, solutions=True)
success &= latex.build_contest_pdf(
contest, problems, tmpdir, solutions=True, web=True
contest_name, problems, tmpdir, solutions=True
)
success &= latex.build_contest_pdf(
contest_name, problems, tmpdir, solutions=True, web=True
)

outfile = contest + '.zip'
outfile = contest_name + '.zip'
if config.args.kattis:
outfile = contest + '-kattis.zip'
outfile = contest_name + '-kattis.zip'
export.build_contest_zip(problems, problem_zips, outfile, config.args)
if action in ['export']:
export.export_contest_and_problems(problems)
Expand Down