Skip to content

Commit 6c56a28

Browse files
committed
Updated CI pipeline + pre-commit
1 parent 1fa58b0 commit 6c56a28

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+3056
-2268
lines changed

.github/workflows/python-ci.yml

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,78 +3,77 @@ name: Python CI
33
on:
44
push:
55
branches: [ main ]
6-
76
pull_request:
87
branches: [ main ]
98

109
jobs:
11-
lint:
10+
quality:
1211
name: Code Quality
1312
runs-on: ubuntu-latest
1413
steps:
15-
- uses: actions/checkout@v3
16-
14+
- uses: actions/checkout@v4
15+
1716
- name: Set up Python
18-
uses: actions/setup-python@v4
17+
uses: actions/setup-python@v5
1918
with:
2019
python-version: '3.11'
21-
22-
- name: Install Poetry
23-
uses: snok/install-poetry@v1
24-
with:
25-
version: latest
26-
virtualenvs-create: true
27-
virtualenvs-in-project: true
28-
29-
- name: Load cached venv
30-
id: cached-poetry-dependencies
31-
uses: actions/cache@v3
20+
21+
- name: Install uv
22+
run: |
23+
curl -LsSf https://astral.sh/uv/install.sh | sh
24+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
25+
26+
- name: Set up uv cache
27+
uses: actions/cache@v4
3228
with:
33-
path: .venv
34-
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
35-
29+
path: |
30+
~/.cache/uv
31+
~/.uv
32+
key: ${{ runner.os }}-uv-${{ hashFiles('**/pyproject.toml') }}
33+
restore-keys: |
34+
${{ runner.os }}-uv-
35+
3636
- name: Install dependencies
37-
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
38-
run: poetry install --no-interaction --no-root
37+
run: uv pip install -e '.[dependency-groups.dev]'
38+
39+
- name: Check formatting
40+
run: ruff format --check .
3941

40-
- name: Check imports with isort
41-
run: poetry run isort . --check-only --profile black
42-
43-
- name: Check formatting with Black
44-
run: poetry run black . --check
45-
46-
- name: Lint with flake8
47-
run: poetry run flake8 .
42+
- name: Run linting
43+
run: ruff check .
44+
45+
- name: Run type checking
46+
run: mypy .
4847

4948
test:
5049
name: Tests
51-
needs: lint # This job will only run if lint job passes
50+
needs: quality
5251
runs-on: ubuntu-latest
5352
steps:
54-
- uses: actions/checkout@v3
55-
53+
- uses: actions/checkout@v4
54+
5655
- name: Set up Python
57-
uses: actions/setup-python@v4
56+
uses: actions/setup-python@v5
5857
with:
5958
python-version: '3.11'
60-
61-
- name: Install Poetry
62-
uses: snok/install-poetry@v1
63-
with:
64-
version: latest
65-
virtualenvs-create: true
66-
virtualenvs-in-project: true
67-
68-
- name: Load cached venv
69-
id: cached-poetry-dependencies
70-
uses: actions/cache@v3
59+
60+
- name: Install uv
61+
run: |
62+
curl -LsSf https://astral.sh/uv/install.sh | sh
63+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
64+
65+
- name: Set up uv cache
66+
uses: actions/cache@v4
7167
with:
72-
path: .venv
73-
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
74-
68+
path: |
69+
~/.cache/uv
70+
~/.uv
71+
key: ${{ runner.os }}-uv-${{ hashFiles('**/pyproject.toml') }}
72+
restore-keys: |
73+
${{ runner.os }}-uv-
74+
7575
- name: Install dependencies
76-
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
77-
run: poetry install --no-interaction --no-root
78-
76+
run: uv pip install -e '.[dependency-groups.dev]'
77+
7978
- name: Run tests
80-
run: poetry run pytest tests/
79+
run: pytest tests/

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Byte-compiled / optimized / DLL files
22
__pycache__/
33
.pytest_cache
4+
.pdm-build
5+
.mypy_cache
6+
.ruff_cache
47
*.py[cod]
58
*$py.class
69

@@ -12,4 +15,5 @@ data/*
1215
aoc_headers.json
1316
aoc_session
1417

15-
*.DS_Store
18+
*.DS_Store
19+
*uv.lock

.pre-commit-config.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.3.0
4+
hooks:
5+
- id: ruff
6+
args: [--fix]
7+
- id: ruff-format
8+
9+
- repo: https://github.com/pre-commit/mirrors-mypy
10+
rev: v1.8.0
11+
hooks:
12+
- id: mypy
13+
additional_dependencies: [
14+
"types-requests>=2.32.0",
15+
"types-beautifulsoup4>=4.12.0"
16+
]
17+
18+
- repo: https://github.com/pre-commit/pre-commit-hooks
19+
rev: v4.5.0
20+
hooks:
21+
- id: trailing-whitespace
22+
- id: end-of-file-fixer
23+
- id: check-yaml
24+
- id: check-toml
25+
- id: check-added-large-files

Makefile

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,55 @@
1+
.PHONY: help install lint lint-fix format check test type-check all setup-pre-commit fix-all
2+
13
.DEFAULT: help
24

35
help:
46
@echo "make install"
5-
@echo " install all dependencies specified in pyproject.toml"
7+
@echo " install all dependencies specified in pyproject.toml using uv"
8+
@echo "make setup-pre-commit"
9+
@echo " set up pre-commit hooks"
610
@echo "make lint"
7-
@echo " run flake8 checks"
11+
@echo " run ruff linting checks"
12+
@echo "make lint-fix"
13+
@echo " run ruff linting checks and fix auto-fixable issues"
814
@echo "make format"
9-
@echo " run isort and black to format code"
15+
@echo " run ruff format to format code and organize imports"
16+
@echo "make type-check"
17+
@echo " run mypy for type checking"
1018
@echo "make check"
11-
@echo " run all code quality checks (format + lint)"
19+
@echo " run all code quality checks (format + lint + type-check)"
20+
@echo "make fix-all"
21+
@echo " run all auto-fixes (format + lint-fix)"
1222
@echo "make test"
1323
@echo " run pytest"
1424
@echo "make all"
15-
@echo " run format, lint, and test"
25+
@echo " run format, lint, type-check, and test"
1626
@echo "make help"
1727
@echo " print this help message"
1828

1929
install:
20-
poetry install
30+
uv pip install -e ".[dependency-groups.dev]"
31+
$(MAKE) setup-pre-commit
32+
33+
setup-pre-commit:
34+
pre-commit install
2135

2236
lint:
23-
poetry run flake8 .
37+
ruff check .
38+
39+
lint-fix:
40+
ruff check --fix .
2441

2542
format:
26-
poetry run isort .
27-
poetry run black .
43+
ruff format .
2844

29-
check: format lint
45+
type-check:
46+
mypy .
3047

31-
test:
32-
poetry run pytest tests/
48+
check: format lint type-check
49+
50+
fix-all: format lint-fix
3351

34-
all: format lint test
52+
test:
53+
pytest tests/
3554

36-
.PHONY: help install lint format check test all
55+
all: format lint type-check test

README.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,3 @@ This will output detailed results, showing which tests passed, failed, or encoun
313313
## Acknowledgments
314314

315315
This project structure was inspired by [nitekat1124's Advent of Code 2024 repository](https://github.com/nitekat1124/advent-of-code-2024).
316-
317-
318-
319-
320-

aoc/models/authenticator.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""
2+
Utility for managing Advent of Code authentication credentials.
3+
4+
Provides methods to retrieve project paths and authentication details
5+
for interacting with the Advent of Code platform.
6+
"""
7+
8+
import json
9+
import os
10+
from pathlib import Path
11+
import sys
12+
13+
14+
class Authenticator:
15+
"""Utility class for retrieving Advent of Code authentication details."""
16+
17+
@staticmethod
18+
def get_path() -> Path:
19+
"""
20+
Determine the absolute path to the project directory.
21+
22+
Returns
23+
-------
24+
Path to the directory containing the current script or script's parent.
25+
"""
26+
path = os.path.realpath(sys.argv[0])
27+
return Path(path).parent if not Path(path).is_dir() else Path(path)
28+
29+
@staticmethod
30+
def get_session() -> str:
31+
"""
32+
Retrieve the Advent of Code session token from a local file.
33+
34+
Returns
35+
-------
36+
Stripped session token for authentication.
37+
38+
Raises
39+
------
40+
FileNotFoundError: If the session file is missing.
41+
IOError: If there are issues reading the session file.
42+
"""
43+
session_path = Authenticator.get_path() / "aoc_session"
44+
return session_path.read_text().strip()
45+
46+
@staticmethod
47+
def get_headers() -> dict[str, str]:
48+
"""
49+
Load HTTP headers configuration from a JSON file.
50+
51+
Returns
52+
-------
53+
Dictionary of HTTP headers for API requests.
54+
55+
Raises
56+
------
57+
FileNotFoundError: If the headers configuration file is missing.
58+
json.JSONDecodeError: If the JSON is malformed.
59+
"""
60+
headers_config_path = Authenticator.get_path() / "aoc_headers.json"
61+
headers: dict[str, str] = json.loads(headers_config_path.read_text().strip())
62+
return headers

0 commit comments

Comments
 (0)