chore: implement "aoc run all" subcommand

This commit is contained in:
2026-05-14 18:04:31 +02:00
parent 0bee46a0ad
commit 8bdde87767
2 changed files with 78 additions and 14 deletions
+44 -5
View File
@@ -1,21 +1,49 @@
import argparse import argparse
from pathlib import Path from pathlib import Path
from adventofcode.helper import run, get_input_file, get_auth
from adventofcode.helper import (
MAX_YEAR,
MIN_YEAR,
get_auth,
get_input_file,
get_max_day,
run,
run_all,
)
TEMPLATE = """#!/usr/bin/env python3 TEMPLATE = """#!/usr/bin/env python3
import fileinput
def main(inp): def main(inp):
for l in inp: for l in inp:
print(l) print(l)
if __name__ == '__main__': if __name__ == '__main__':
import fileinput
lines = [x.rstrip() for x in fileinput.input()] lines = [x.rstrip() for x in fileinput.input()]
main(lines) main(lines)
""" """
def year_or_all(value):
"""Custom type function to validate 'year' as either an integer or 'all'."""
if value.lower() == "all":
return value
try:
year = int(value)
if 2015 <= year <= 2025:
return year
else:
raise argparse.ArgumentTypeError(
f"Year must be between 2015 and 2025. Got: {year}"
)
except ValueError:
raise argparse.ArgumentTypeError(
f"Invalid value: {value}. Must be an integer or 'all'."
)
def main(): def main():
parser = argparse.ArgumentParser(description="Advent of Code CLI") parser = argparse.ArgumentParser(description="Advent of Code CLI")
subparsers = parser.add_subparsers(dest="command") subparsers = parser.add_subparsers(dest="command")
@@ -25,13 +53,15 @@ def main():
init_parser.add_argument("day", type=int) init_parser.add_argument("day", type=int)
run_parser = subparsers.add_parser("run", help="Run an aoc day") run_parser = subparsers.add_parser("run", help="Run an aoc day")
run_parser.add_argument("year", type=int) run_parser.add_argument("year", type=year_or_all)
run_parser.add_argument("day", type=int, nargs="?", default=None) run_parser.add_argument("day", type=int, nargs="?", default=None)
args = parser.parse_args() args = parser.parse_args()
if args.command == "init": if args.command == "init":
handle_init(args.year, args.day) handle_init(args.year, args.day)
elif args.command == "run" and args.year == "all":
handle_run_all()
elif args.command == "run": elif args.command == "run":
handle_run(args.year, args.day) handle_run(args.year, args.day)
else: else:
@@ -39,8 +69,13 @@ def main():
def handle_init(year, day): def handle_init(year, day):
if not 1 <= day <= 25: if not MIN_YEAR <= year <= MAX_YEAR:
print(f"Invalid day: {day}. Must be between 1 and 25.") print(f"Invalid year: {year}. Must be between {MIN_YEAR} and {MAX_YEAR}.")
return
max_day = get_max_day(year)
if not 1 <= day <= max_day:
print(f"Invalid day: {day}. Must be between 1 and {max_day}.")
return return
root = Path(__file__).parent root = Path(__file__).parent
@@ -69,5 +104,9 @@ def handle_run(year, day):
run(year, day) run(year, day)
def handle_run_all():
run_all()
if __name__ == "__main__": if __name__ == "__main__":
main() main()
+33 -8
View File
@@ -1,13 +1,21 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import urllib.request import os
import subprocess
import sys import sys
import time import time
import subprocess import urllib.request
import os
from pathlib import Path from pathlib import Path
MIN_YEAR = 2015
MAX_YEAR = 2025
ROOTPATH = Path(os.path.dirname(os.path.realpath(__file__))) ROOTPATH = Path(os.path.dirname(os.path.realpath(__file__)))
def get_max_day(year):
# starting with 2025, advent of code only has 12 days
return 25 if year < 2025 else 12
_auth = None _auth = None
@@ -54,11 +62,30 @@ def get_input_file(year, day):
return res return res
def run(year, day): def resolve_paths(year, day):
if day is not None:
path = ROOTPATH / Path(f"{year}/day{day}") path = ROOTPATH / Path(f"{year}/day{day}")
script_path = path / Path(f"day{day}.py") script_path = path / Path(f"day{day}.py")
input_path = path / Path("input.txt") input_path = path / Path("input.txt")
return script_path, input_path
def run_all():
for year in range(2015, MAX_YEAR + 1):
print(f"Running year {year}")
run(year, None)
def run(year, day):
if not MIN_YEAR <= year <= MAX_YEAR:
print(f"Invalid year {year}", file=sys.stderr)
exit(1)
if day is not None:
if not 1 <= day <= get_max_day(year):
print(f"Invalid day {day}", file=sys.stderr)
exit(1)
script_path, input_path = resolve_paths(year, day)
if not script_path.exists(): if not script_path.exists():
print(f"Invalid day {day}", file=sys.stderr) print(f"Invalid day {day}", file=sys.stderr)
exit(1) exit(1)
@@ -72,9 +99,7 @@ def run(year, day):
run_day(script_path, input_path) run_day(script_path, input_path)
else: else:
for day in range(1, 26): for day in range(1, 26):
path = ROOTPATH / Path(f"{year}/day{day}") script_path, input_path = resolve_paths(year, day)
script_path = path / Path(f"day{day}.py")
input_path = path / Path("input.txt")
if script_path.exists(): if script_path.exists():
if not input_path.exists(): if not input_path.exists():
print(f"- downloading input file {input_path}") print(f"- downloading input file {input_path}")