From 6ef70627032b04990923221e12d02448adac6b33 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 13:08:49 -0600 Subject: [PATCH 01/15] try and fix issue with client disconnects Signed-off-by: Jonathan Irvin --- main.py | 82 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/main.py b/main.py index 7c8f279..aaa0c44 100644 --- a/main.py +++ b/main.py @@ -50,6 +50,7 @@ # Keys can be "home" and "stream". Each value is a tuple: (container, tile_buttons). board_views = {} +# We won't try to track active clients as it's not reliable across all NiceGUI versions board_iteration = 1 # Global set to track winning patterns (rows, columns, & diagonals) @@ -321,9 +322,24 @@ def check_winner(): ui.notify(sp_message, color="blue", duration=5) def sync_board_state(): - # Update tile styles in every board view (e.g., home and stream) - for view_key, (container, tile_buttons_local) in board_views.items(): - update_tile_styles(tile_buttons_local) + """ + Update tile styles in every board view (e.g., home and stream). + """ + try: + # Update tile styles in every board view (e.g., home and stream) + for view_key, (container, tile_buttons_local) in board_views.items(): + update_tile_styles(tile_buttons_local) + + # Safely run JavaScript + try: + ui.run_javascript( + "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" + "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" + ) + except Exception as e: + logging.debug(f"JavaScript execution failed (likely disconnected client): {e}") + except Exception as e: + logging.debug(f"Error in sync_board_state: {e}") def create_board_view(background_color: str, is_global: bool): """ @@ -334,11 +350,17 @@ def create_board_view(background_color: str, is_global: bool): setup_head(background_color) # Create the board container. For the home view, assign an ID to capture it. if is_global: - container = ui.element("div").classes("home-board-container flex justify-center items-center w-full") - ui.run_javascript("document.querySelector('.home-board-container').id = 'board-container'") + container = ui.element("div").classes("home-board-container flex justify-center items-center w-full") + try: + ui.run_javascript("document.querySelector('.home-board-container').id = 'board-container'") + except Exception as e: + logging.debug(f"Setting board container ID failed: {e}") else: - container = ui.element("div").classes("stream-board-container flex justify-center items-center w-full") - ui.run_javascript("document.querySelector('.stream-board-container').id = 'board-container-stream'") + container = ui.element("div").classes("stream-board-container flex justify-center items-center w-full") + try: + ui.run_javascript("document.querySelector('.stream-board-container').id = 'board-container-stream'") + except Exception as e: + logging.debug(f"Setting stream container ID failed: {e}") if is_global: global home_board_container, tile_buttons, seed_label @@ -346,8 +368,12 @@ def create_board_view(background_color: str, is_global: bool): tile_buttons = {} # Start with an empty dictionary. build_board(container, tile_buttons, toggle_tile) board_views["home"] = (container, tile_buttons) - # Add timers for synchronizing the global board. - ui.timer(1, check_phrases_file_change) + # Add timers for synchronizing the global board + try: + check_timer = ui.timer(1, check_phrases_file_change) + except Exception as e: + logging.warning(f"Error setting up timer: {e}") + global seed_label with ui.row().classes("w-full mt-4 items-center justify-center gap-4"): with ui.button("", icon="refresh", on_click=reset_board).classes("rounded-full w-12 h-12") as reset_btn: @@ -365,12 +391,20 @@ def create_board_view(background_color: str, is_global: bool): @ui.page("/") def home_page(): create_board_view(HOME_BG_COLOR, True) - ui.timer(0.1, sync_board_state) + try: + # Create a timer that deactivates when the client disconnects + timer = ui.timer(0.1, sync_board_state) + except Exception as e: + logging.warning(f"Error creating timer: {e}") @ui.page("/stream") def stream_page(): create_board_view(STREAM_BG_COLOR, False) - ui.timer(0.1, sync_board_state) + try: + # Create a timer that deactivates when the client disconnects + timer = ui.timer(0.1, sync_board_state) + except Exception as e: + logging.warning(f"Error creating timer: {e}") def setup_head(background_color: str): """ @@ -532,10 +566,15 @@ def update_tile_styles(tile_buttons_dict: dict): # Update inline style (which may now use a new color due to tile click state). lbl.style(new_label_style) lbl.update() - ui.run_javascript( - "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" - "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" - ) + + # Safely run JavaScript + try: + ui.run_javascript( + "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" + "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" + ) + except Exception as e: + logging.debug(f"JavaScript execution failed (likely disconnected client): {e}") def check_phrases_file_change(): """ @@ -589,10 +628,15 @@ def has_too_many_repeats(phrase, threshold=0.5): tile_buttons_local.clear() # Clear local board dictionary. build_board(container, tile_buttons_local, toggle_tile) container.update() # Force update so new styles are applied immediately. - ui.run_javascript( - "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" - "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" - ) + + # Safely run JavaScript + try: + ui.run_javascript( + "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" + "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" + ) + except Exception as e: + logging.debug(f"JavaScript execution failed (likely disconnected client): {e}") def reset_board(): """ From e5932393964d22bf247219310f75c1e8dfa4e52f Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 13:17:58 -0600 Subject: [PATCH 02/15] fix sync issues Signed-off-by: Jonathan Irvin --- main.py | 122 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 27 deletions(-) diff --git a/main.py b/main.py index aaa0c44..5b08be9 100644 --- a/main.py +++ b/main.py @@ -223,19 +223,54 @@ def segment_length(segment): # Toggle tile click state (for example usage) def toggle_tile(row, col): - # Do not allow toggling for the FREE SPACE cell (center cell) + global clicked_tiles, tile_buttons # Explicitly declare tile_buttons as global if (row, col) == (2, 2): return key = (row, col) if key in clicked_tiles: - logging.debug(f"Tile at {key} unclicked") clicked_tiles.remove(key) else: - logging.debug(f"Tile at {key} clicked") clicked_tiles.add(key) check_winner() - sync_board_state() + + for view_key, (container, tile_buttons_local) in board_views.items(): + for (r, c), tile in tile_buttons_local.items(): + phrase = board[r][c] + if (r, c) in clicked_tiles: + new_card_style = f"background-color: {TILE_CLICKED_BG_COLOR}; color: {TILE_CLICKED_TEXT_COLOR}; border: none; outline: 3px solid {TILE_CLICKED_TEXT_COLOR};" + new_label_color = TILE_CLICKED_TEXT_COLOR + else: + new_card_style = f"background-color: {TILE_UNCLICKED_BG_COLOR}; color: {TILE_UNCLICKED_TEXT_COLOR}; border: none;" + new_label_color = TILE_UNCLICKED_TEXT_COLOR + + tile["card"].style(new_card_style) + lines = split_phrase_into_lines(phrase) + line_count = len(lines) + new_label_style = get_line_style_for_lines(line_count, new_label_color) + + for label_info in tile["labels"]: + lbl = label_info["ref"] + lbl.classes(label_info["base_classes"]) + lbl.style(new_label_style) + lbl.update() + + tile["card"].update() + + container.update() + + try: + js_code = """ + setTimeout(function() { + if (typeof fitty !== 'undefined') { + fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); + fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + } + }, 50); + """ + ui.run_javascript(js_code) + except Exception as e: + logging.debug(f"JavaScript execution failed: {e}") # Check for Bingo win condition def check_winner(): @@ -330,12 +365,18 @@ def sync_board_state(): for view_key, (container, tile_buttons_local) in board_views.items(): update_tile_styles(tile_buttons_local) - # Safely run JavaScript + # Safely run JavaScript to resize text try: - ui.run_javascript( - "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" - "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" - ) + # Add a slight delay to ensure DOM updates have propagated + js_code = """ + setTimeout(function() { + if (typeof fitty !== 'undefined') { + fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); + fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + } + }, 50); + """ + ui.run_javascript(js_code) except Exception as e: logging.debug(f"JavaScript execution failed (likely disconnected client): {e}") except Exception as e: @@ -442,8 +483,10 @@ def setup_head(background_color: str): return; } // Run fitty to ensure text is resized and centered - fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); - fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + if (typeof fitty !== 'undefined') { + fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); + fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + } // Wait a short period to ensure that the board is fully rendered and styles have settled. setTimeout(function() { @@ -460,22 +503,35 @@ def setup_head(background_color: str): }); }, 500); // Adjust delay if necessary } + + // Function to safely apply fitty + function applyFitty() { + if (typeof fitty !== 'undefined') { + fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); + fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + fitty('.fit-header', { multiLine: true, minSize: 10, maxSize: 2000 }); + } + } """) ui.add_head_html(f'') ui.add_head_html("""""") # Use full width with padding so the header spans edge-to-edge @@ -569,10 +625,16 @@ def update_tile_styles(tile_buttons_dict: dict): # Safely run JavaScript try: - ui.run_javascript( - "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" - "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" - ) + # Add a slight delay to ensure DOM updates have propagated + js_code = """ + setTimeout(function() { + if (typeof fitty !== 'undefined') { + fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); + fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + } + }, 50); + """ + ui.run_javascript(js_code) except Exception as e: logging.debug(f"JavaScript execution failed (likely disconnected client): {e}") @@ -631,10 +693,16 @@ def has_too_many_repeats(phrase, threshold=0.5): # Safely run JavaScript try: - ui.run_javascript( - "fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 });" - "fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 });" - ) + # Add a slight delay to ensure DOM updates have propagated + js_code = """ + setTimeout(function() { + if (typeof fitty !== 'undefined') { + fitty('.fit-text', { multiLine: true, minSize: 10, maxSize: 1000 }); + fitty('.fit-text-small', { multiLine: true, minSize: 10, maxSize: 72 }); + } + }, 50); + """ + ui.run_javascript(js_code) except Exception as e: logging.debug(f"JavaScript execution failed (likely disconnected client): {e}") From 753000f6766e36a9093095b66bb3240e1a922df4 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 14:21:08 -0600 Subject: [PATCH 03/15] add claude.md Signed-off-by: Jonathan Irvin --- CLAUDE.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..f2073cb --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,35 @@ +# BINGO Project Guide + +## Build Commands +```bash +# Install dependencies +poetry install + +# Run application +poetry run python main.py + +# Build Docker container +docker build -t bingo . + +# Run Docker container +docker run -p 8080:8080 bingo + +# Helm deployment +cd helm && ./package.sh && helm install bingo ./bingo +``` + +## Code Style Guidelines +- **Imports**: Standard library first, third-party second, local modules last +- **Formatting**: Use f-strings for string formatting +- **Constants**: Defined at top of file in UPPER_CASE +- **Naming**: snake_case for functions/variables, UPPER_CASE for constants +- **Error Handling**: Use try/except blocks with proper logging +- **UI Elements**: Define class constants for styling +- **Logging**: Use Python's logging module with descriptive messages +- **Comments**: Use docstrings for functions and descriptive comments + +## Project Structure +- `main.py`: Core application with NiceGUI implementation +- `phrases.txt`: Contains customizable bingo phrases +- `static/`: Static assets for fonts and styles +- `helm/`: Kubernetes deployment configuration \ No newline at end of file From 8329ca9f9b4cf001afc79184dc30fb686191b0ea Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 14:53:01 -0600 Subject: [PATCH 04/15] chore(build): add semantic versioning configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add python-semantic-release configuration to enable automatic versioning. Configure Black and isort for code formatting standards. Add development dependencies for linting and testing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- pyproject.toml | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7fcebeb..c784d74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,11 @@ [tool.poetry] name = "bingo" version = "0.1.0" -description = "" +description = "A bingo board generator using NiceGUI" authors = ["Offending Commit "] license = "MIT" readme = "README.md" +repository = "https://github.com/offendingcommit/bingo" package-mode = false exclude = [".git", ".git/"] @@ -12,7 +13,43 @@ exclude = [".git", ".git/"] python = "^3.12" nicegui = "^2.11.0" +[tool.poetry.group.dev.dependencies] +pytest = "^7.4.0" +pytest-cov = "^4.1.0" +flake8 = "^7.0.0" +black = "^24.2.0" +isort = "^5.13.2" +python-semantic-release = "^9.1.1" [build-system] requires = ["poetry-core>=1.8"] build-backend = "poetry.core.masonry.api" + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = "test_*.py" +python_classes = "Test*" +python_functions = "test_*" +addopts = "--cov=src" + +[tool.semantic_release] +version_variable = ["pyproject.toml:version"] +branch = "main" +changelog_file = "CHANGELOG.md" +build_command = "poetry build" +dist_path = "dist/" +upload_to_pypi = false +upload_to_release = true +commit_subject = "chore(release): {version}" +commit_message = "chore(release): version {version} [skip ci]" +commit_author = "semantic-release " +major_on_zero = false + +[tool.black] +line-length = 88 +target-version = ["py312"] +include = '\.pyi?$' + +[tool.isort] +profile = "black" +line_length = 88 \ No newline at end of file From 9b31ae30c6dc56b78663421d0c63e19ec702d160 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 14:53:11 -0600 Subject: [PATCH 05/15] ci: add github actions workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CI/CD pipeline with GitHub Actions that: - Runs tests with pytest - Performs linting with flake8, black, and isort - Uploads coverage reports - Automatically creates releases based on semantic versioning 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .github/workflows/ci.yml | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2d04d19 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.12"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + version: 1.8.3 + virtualenvs-create: true + virtualenvs-in-project: true + + - name: Cache Poetry dependencies + uses: actions/cache@v4 + with: + path: .venv + key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }} + + - name: Install dependencies + run: poetry install + + - name: Lint with flake8 + run: | + poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + + - name: Format check with black + run: poetry run black --check . + + - name: Import sorting check with isort + run: poetry run isort --check . + + - name: Test with pytest + run: poetry run pytest --cov=src + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + + release: + needs: test + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + concurrency: release + permissions: + id-token: write + contents: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Python Semantic Release + uses: python-semantic-release/python-semantic-release@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 6f07022e3fb1704fdd4e33601eaad33a5a886d71 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 14:53:21 -0600 Subject: [PATCH 06/15] docs(changelog): add initial changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create CHANGELOG.md for tracking release history. Follow Keep a Changelog format for better release readability. Include entries for unreleased changes and initial 0.1.0 release. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..df4af6a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,28 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Initial project structure +- Bingo board generation functionality +- Interactive UI with NiceGUI +- Board synchronization between views +- Testing framework with pytest +- Modular architecture with separate components +- Semantic versioning with python-semantic-release +- CI pipeline with GitHub Actions +- Developer setup script + +## [0.1.0] - 2025-03-02 + +### Added +- Initial release +- Basic bingo board functionality +- Home and stream views +- Dynamic board generation +- Win pattern detection \ No newline at end of file From e286126e3d3fa391ea77abdcb3c4eef1f1d5eaa5 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 14:53:31 -0600 Subject: [PATCH 07/15] chore(dev): add development helper scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Makefile with common commands for building, testing and running. Create setup.sh script for easy developer onboarding. Configure git hooks for pre-commit checks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- Makefile | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 Makefile create mode 100755 setup.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..636507e --- /dev/null +++ b/Makefile @@ -0,0 +1,58 @@ +.PHONY: help install test lint format clean run build docker-build docker-run + +# Help command +help: + @echo "BINGO Application Makefile Commands" + @echo "" + @echo "Usage:" + @echo " make install - Install dependencies" + @echo " make run - Run the application" + @echo " make test - Run tests" + @echo " make lint - Run linters" + @echo " make format - Format code" + @echo " make clean - Clean build artifacts and cache" + @echo " make build - Build the package" + @echo " make docker-build - Build Docker image" + @echo " make docker-run - Run Docker container" + +# Install dependencies +install: + poetry install + +# Run application +run: + poetry run python app.py + +# Run tests +test: + poetry run pytest --cov=src + +# Run lints +lint: + poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + poetry run black --check . + poetry run isort --check . + +# Format code +format: + poetry run black . + poetry run isort . + +# Clean build artifacts and cache +clean: + rm -rf dist + rm -rf .pytest_cache + rm -rf .coverage + find . -type d -name "__pycache__" -exec rm -rf {} + + +# Build package +build: + poetry build + +# Docker commands +docker-build: + docker build -t bingo . + +docker-run: + docker run -p 8080:8080 bingo \ No newline at end of file diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..4044a75 --- /dev/null +++ b/setup.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -e + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +echo -e "${GREEN}Setting up bingo development environment...${NC}" + +# Check if Poetry is installed +if ! command -v poetry &> /dev/null; then + echo -e "${YELLOW}Poetry not found. Installing poetry...${NC}" + curl -sSL https://install.python-poetry.org | python3 - +fi + +# Install dependencies +echo -e "${GREEN}Installing dependencies...${NC}" +poetry install + +# Set up pre-commit hooks +echo -e "${GREEN}Setting up git hooks...${NC}" +cat > .git/hooks/pre-commit << 'EOF' +#!/bin/bash +set -e + +# Run black +echo "Running black..." +poetry run black . + +# Run isort +echo "Running isort..." +poetry run isort . + +# Run flake8 +echo "Running flake8..." +poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics +poetry run flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + +# Run tests +echo "Running tests..." +poetry run pytest +EOF + +chmod +x .git/hooks/pre-commit + +echo -e "${GREEN}Setup complete! You're ready to start developing.${NC}" +echo -e "${GREEN}Run 'poetry shell' to activate the virtual environment${NC}" +echo -e "${GREEN}Run 'python app.py' to start the application${NC}" \ No newline at end of file From fa43299bc878fdeb4c19af905dacb7fd98411690 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sun, 2 Mar 2025 14:53:41 -0600 Subject: [PATCH 08/15] docs(project): update documentation with CI and semantic versioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update CLAUDE.md with: - Information about semantic versioning principles - CI/CD pipeline details - New build commands - Makefile usage instructions - Linting and formatting guidelines 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CLAUDE.md | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index f2073cb..bb2b3e3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,12 +2,33 @@ ## Build Commands ```bash +# Quick setup for development +./setup.sh + # Install dependencies poetry install -# Run application +# Run application (old monolithic structure) poetry run python main.py +# Run application (new modular structure) +poetry run python app.py + +# Run tests +poetry run pytest + +# Run tests with coverage +poetry run pytest --cov=src --cov-report=html + +# Lint code +poetry run flake8 +poetry run black --check . +poetry run isort --check . + +# Format code +poetry run black . +poetry run isort . + # Build Docker container docker build -t bingo . @@ -16,6 +37,14 @@ docker run -p 8080:8080 bingo # Helm deployment cd helm && ./package.sh && helm install bingo ./bingo + +# Using Makefile +make install # Install dependencies +make run # Run application +make test # Run tests +make lint # Run linters +make format # Format code +make build # Build package ``` ## Code Style Guidelines @@ -27,9 +56,109 @@ cd helm && ./package.sh && helm install bingo ./bingo - **UI Elements**: Define class constants for styling - **Logging**: Use Python's logging module with descriptive messages - **Comments**: Use docstrings for functions and descriptive comments +- **Line Length**: Max 88 characters (Black's default) +- **Code Formatting**: Use Black for code formatting and isort for import sorting ## Project Structure -- `main.py`: Core application with NiceGUI implementation +- `app.py`: Main entry point for modular application +- `src/`: Source code directory + - `config/`: Configuration and constants + - `core/`: Core game logic + - `ui/`: User interface components + - `utils/`: Utility functions - `phrases.txt`: Contains customizable bingo phrases - `static/`: Static assets for fonts and styles -- `helm/`: Kubernetes deployment configuration \ No newline at end of file +- `tests/`: Unit and integration tests +- `helm/`: Kubernetes deployment configuration +- `.github/workflows/`: CI pipeline configuration +- `CHANGELOG.md`: Release history tracking + +## Git Workflow + +### Branch Naming +- Use feature branches for each change: `feature/description-of-change` +- Use bugfix branches for bug fixes: `fix/description-of-bug` +- Use chore branches for maintenance: `chore/description-of-task` + +### Commit Guidelines +Follow conventional changelog format: + +``` +(): + + + +