Skip to content
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Postsubmit (C++)
name: Code Health (C++)

on: # yamllint disable-line rule:truthy
push:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Postsubmit (Python)
name: Code Health (Python)

on: # yamllint disable-line rule:truthy
push:
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/presubmit-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ jobs:
CHANGED_CPP_FILES=$(echo "$CHANGED_FILES" | \
grep -E '\.(cc|cpp|cxx|c\+\+|h|hpp|hxx|h\+\+)$' || true)

# Filter for C++ files specifically in the problems directory
CHANGED_CPP_PROBLEMS_FILES=$(echo "$CHANGED_CPP_FILES" | \
grep -E '^problems/' || true)

# Extract unique problem directories from changed C++ files
CHANGED_PROBLEMS=$(echo "$CHANGED_CPP_FILES" | \
CHANGED_PROBLEMS=$(echo "$CHANGED_CPP_PROBLEMS_FILES" | \
grep -E '^problems/[^/]+/' | cut -d'/' -f2 | \
sort -u | tr '\n' ' ' || true)

Expand All @@ -57,13 +61,15 @@ jobs:

echo "Changed C++ files:"
echo "$CHANGED_CPP_FILES"
echo "Changed C++ files in problems/:"
echo "$CHANGED_CPP_PROBLEMS_FILES"
echo "Changed problems: $CHANGED_PROBLEMS"
echo "C++ config changes: $CPP_CONFIG_CHANGES"
echo "Common directory changes: $COMMON_CHANGES"

# Set outputs
echo "changed_problems=$CHANGED_PROBLEMS" >> $GITHUB_OUTPUT
echo "has_cpp_changes=$([ -n "$CHANGED_CPP_FILES" ] && \
echo "has_cpp_changes=$([ -n "$CHANGED_CPP_PROBLEMS_FILES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
echo "has_cpp_config_changes=$([ -n "$CPP_CONFIG_CHANGES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -137,7 +143,7 @@ jobs:
"false" ] && \
[ "${{ steps.detect-changes.outputs.has_common_changes }}" = \
"false" ]; then
echo "- No C++ files changed - skipped all tasks" >> \
echo "- No C++ files in problems/ changed - skipped all tasks" >> \
$GITHUB_STEP_SUMMARY
elif [ "${{ steps.detect-changes.outputs.should_run_all_tests }}" = \
"true" ]; then
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/presubmit-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ jobs:
CHANGED_PYTHON_FILES=$(echo "$CHANGED_FILES" | \
grep '\.py$' || true)

# Filter for Python files specifically in the problems directory
CHANGED_PYTHON_PROBLEMS_FILES=$(echo "$CHANGED_PYTHON_FILES" | \
grep -E '^problems/' || true)

# Extract unique problem directories from changed Python files
CHANGED_PROBLEMS=$(echo "$CHANGED_PYTHON_FILES" | \
CHANGED_PROBLEMS=$(echo "$CHANGED_PYTHON_PROBLEMS_FILES" | \
grep -E '^problems/[^/]+/' | cut -d'/' -f2 | \
sort -u | tr '\n' ' ' || true)

Expand All @@ -55,12 +59,14 @@ jobs:

echo "Changed Python files:"
echo "$CHANGED_PYTHON_FILES"
echo "Changed Python files in problems/:"
echo "$CHANGED_PYTHON_PROBLEMS_FILES"
echo "Changed problems: $CHANGED_PROBLEMS"
echo "Python config changes: $PYTHON_CONFIG_CHANGES"

# Set outputs
echo "changed_problems=$CHANGED_PROBLEMS" >> $GITHUB_OUTPUT
echo "has_python_changes=$([ -n "$CHANGED_PYTHON_FILES" ] && \
echo "has_python_changes=$([ -n "$CHANGED_PYTHON_PROBLEMS_FILES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
echo "has_python_config_changes=$([ -n "$PYTHON_CONFIG_CHANGES" ] && \
echo 'true' || echo 'false')" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -118,7 +124,7 @@ jobs:
"false" ] && \
[ "${{ steps.detect-changes.outputs.has_python_config_changes }}" \
= "false" ]; then
echo "- No Python files changed - skipped all tasks" >> \
echo "- No Python files in problems/ changed - skipped all tasks" >> \
$GITHUB_STEP_SUMMARY
elif [ "${{ steps.detect-changes.outputs.should_run_all_tests }}" = \
"true" ]; then
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/update-badges.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: Update Badges

on: # yamllint disable-line rule:truthy
push:
branches: ["main"]
workflow_dispatch: # Allow manual triggering

jobs:
update-badges:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Update badges
run: |
python3 scripts/update_badges.py

- name: Check for changes
id: verify-changed-files
run: |
if git diff --quiet; then
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "changed=true" >> $GITHUB_OUTPUT
fi

- name: Commit changes
if: steps.verify-changed-files.outputs.changed == 'true'
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add README.md
git commit -m "docs: update problem count badges [skip ci]"
git push
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@ stats:
@echo "Available problems:"
@for prob in $(SNAKE_CASE_PROBLEM_NAMES); do echo " $(call color_cyan,- $$prob)"; done

# Update README badges with current problem counts
.PHONY: update-badges
update-badges:
@echo "$(call color_green,Updating README badges...)"
@./scripts/update_badges.sh

# Debug Google Test configuration
.PHONY: debug-gtest
debug-gtest:
Expand Down Expand Up @@ -329,6 +335,7 @@ help:
@echo "$(call color_yellow,Utility Targets:)"
@echo " clean - Clean build artifacts"
@echo " stats - Show project statistics"
@echo " update-badges - Update README badges with current problem counts"
@echo " debug-gtest - Debug Google Test configuration"
@echo " help - Show this help message"
@echo ""
Expand Down
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# Leetcode
# 🧮 LeetCode Solutions

[![Code Health (C++)](https://github.com/mathusanm6/LeetCode/actions/workflows/postsubmit-cpp.yml/badge.svg)](https://github.com/mathusanm6/LeetCode/actions/workflows/postsubmit-cpp.yml)
[![C++ Linter](https://github.com/mathusanm6/LeetCode/actions/workflows/linter-cpp.yml/badge.svg)](https://github.com/mathusanm6/LeetCode/actions/workflows/linter-cpp.yml)
<div align="center">

[![Code Health (Python)](https://github.com/mathusanm6/LeetCode/actions/workflows/postsubmit-py.yml/badge.svg)](https://github.com/mathusanm6/LeetCode/actions/workflows/postsubmit-py.yml)
[![Python Linter](https://github.com/mathusanm6/LeetCode/actions/workflows/linter-py.yml/badge.svg)](https://github.com/mathusanm6/LeetCode/actions/workflows/linter-py.yml)
### 🔬 Code Health & Testing

[![C++ Tests](https://img.shields.io/github/actions/workflow/status/mathusanm6/LeetCode/code-health-cpp.yml?branch=main&label=C%2B%2B%20Tests&logo=cplusplus&logoColor=white&style=for-the-badge)](https://github.com/mathusanm6/LeetCode/actions/workflows/code-health-cpp.yml)
[![Python Tests](https://img.shields.io/github/actions/workflow/status/mathusanm6/LeetCode/code-health-py.yml?branch=main&label=Python%20Tests&logo=python&logoColor=white&style=for-the-badge)](https://github.com/mathusanm6/LeetCode/actions/workflows/code-health-py.yml)

### 🔍 Code Quality & Linting

[![C++ Linter](https://img.shields.io/github/actions/workflow/status/mathusanm6/LeetCode/linter-cpp.yml?branch=main&label=C%2B%2B%20Linter&logo=cplusplus&logoColor=white&style=for-the-badge&color=blue)](https://github.com/mathusanm6/LeetCode/actions/workflows/linter-cpp.yml)
[![Python Linter](https://img.shields.io/github/actions/workflow/status/mathusanm6/LeetCode/linter-py.yml?branch=main&label=Python%20Linter&logo=python&logoColor=white&style=for-the-badge&color=blue)](https://github.com/mathusanm6/LeetCode/actions/workflows/linter-py.yml)

### 📊 Repository Stats

[![Last Commit](https://img.shields.io/github/last-commit/mathusanm6/LeetCode?style=for-the-badge&logo=git&logoColor=white)](https://github.com/mathusanm6/LeetCode/commits/main)
[![C++ Solutions](https://img.shields.io/badge/C%2B%2B%20Solutions-2-blue?style=for-the-badge&logo=cplusplus&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)
[![Python Solutions](https://img.shields.io/badge/Python%20Solutions-2-green?style=for-the-badge&logo=python&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)

</div>

## Description

Expand Down
111 changes: 111 additions & 0 deletions scripts/update_badges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""
Script to automatically update README badges with current problem counts.
This script counts the number of solved problems in each language and updates the README.md file.
"""

import os
import re
from pathlib import Path


def count_cpp_problems():
"""Count C++ problems in the problems directory."""
problems_dir = Path("problems")
if not problems_dir.exists():
return 0

cpp_count = 0
for problem_dir in problems_dir.iterdir():
if problem_dir.is_dir():
# Check if this problem has C++ files
cpp_files = list(problem_dir.glob("*.cc")) + list(problem_dir.glob("*.cpp"))
if cpp_files:
cpp_count += 1

return cpp_count


def count_python_problems():
"""Count Python problems in the problems directory."""
problems_dir = Path("problems")
if not problems_dir.exists():
return 0

python_count = 0
for problem_dir in problems_dir.iterdir():
if problem_dir.is_dir():
# Check if this problem has Python files
python_files = list(problem_dir.glob("*.py"))
if python_files:
python_count += 1

return python_count


def update_readme_badges(cpp_count, python_count):
"""Update the README.md file with new badge counts."""
readme_path = Path("README.md")
if not readme_path.exists():
print("ERROR: README.md not found!")
return False

# Read the current README content
with open(readme_path, "r", encoding="utf-8") as f:
content = f.read()

# Define the new badge lines
cpp_badge = f"[![C++ Solutions](https://img.shields.io/badge/C%2B%2B%20Solutions-{cpp_count}-blue?style=for-the-badge&logo=cplusplus&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)"
python_badge = f"[![Python Solutions](https://img.shields.io/badge/Python%20Solutions-{python_count}-green?style=for-the-badge&logo=python&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)"

# Update C++ badge
cpp_pattern = r"\[\!\[C\+\+ Solutions\].*?\)\]\(.*?\)"
if re.search(cpp_pattern, content):
content = re.sub(cpp_pattern, cpp_badge, content)
else:
print("WARNING: C++ badge pattern not found in README.md")

# Update Python badge
python_pattern = r"\[\!\[Python Solutions\].*?\)\]\(.*?\)"
if re.search(python_pattern, content):
content = re.sub(python_pattern, python_badge, content)
else:
print("WARNING: Python badge pattern not found in README.md")

# Write the updated content back
with open(readme_path, "w", encoding="utf-8") as f:
f.write(content)

return True


def main():
"""Main function to count problems and update badges."""
print("🔍 Counting solved problems...")

# Count problems in each language
cpp_count = count_cpp_problems()
python_count = count_python_problems()

print(f"📊 Found {cpp_count} C++ problems")
print(f"📊 Found {python_count} Python problems")

# Update the README
if update_readme_badges(cpp_count, python_count):
print("✅ README.md badges updated successfully!")
print(f" C++ Solutions: {cpp_count}")
print(f" Python Solutions: {python_count}")
else:
print("❌ Failed to update README.md")
return 1

return 0


if __name__ == "__main__":
# Change to the repository root directory
script_dir = Path(__file__).parent
repo_root = script_dir.parent
os.chdir(repo_root)

exit(main())
14 changes: 14 additions & 0 deletions scripts/update_badges.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
# Update README badges with current problem counts

set -e

# Get the directory of this script
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"

# Change to repository root
cd "$REPO_ROOT"

# Run the Python script
python3 scripts/update_badges.py