Spaces:
Sleeping
Sleeping
| """Static code analysis checks.""" | |
| import re | |
| from datetime import datetime | |
| from pathlib import Path | |
| from typing import Any | |
| import git | |
| import requests | |
| from bs4 import BeautifulSoup | |
| from shared.logger import setup_logger | |
| logger = setup_logger(__name__) | |
| class StaticChecker: | |
| """Perform static checks on repository.""" | |
| def __init__(self, repo_url: str, commit_sha: str, clone_dir: Path) -> None: | |
| """Initialize static checker. | |
| Args: | |
| repo_url: Repository URL | |
| commit_sha: Commit SHA to check | |
| clone_dir: Directory to clone repo | |
| """ | |
| self.repo_url = repo_url | |
| self.commit_sha = commit_sha | |
| self.clone_dir = clone_dir | |
| self.repo = None | |
| def clone_repo(self) -> None: | |
| """Clone repository and checkout specific commit.""" | |
| logger.info(f"Cloning {self.repo_url} to {self.clone_dir}") | |
| # Clean up if exists | |
| if self.clone_dir.exists(): | |
| import shutil | |
| shutil.rmtree(self.clone_dir) | |
| # Clone | |
| self.repo = git.Repo.clone_from(self.repo_url, self.clone_dir) | |
| # Checkout specific commit | |
| self.repo.git.checkout(self.commit_sha) | |
| logger.info(f"Checked out commit {self.commit_sha}") | |
| def check_created_after_task(self, task_timestamp: datetime) -> dict[str, Any]: | |
| """Check if repo was created after task was sent. | |
| Args: | |
| task_timestamp: When task was sent | |
| Returns: | |
| Check result | |
| """ | |
| try: | |
| # Get first commit timestamp | |
| commits = list(self.repo.iter_commits()) | |
| if not commits: | |
| return { | |
| "passed": False, | |
| "score": 0.0, | |
| "reason": "No commits found", | |
| } | |
| first_commit = commits[-1] | |
| first_commit_time = datetime.fromtimestamp(first_commit.committed_date) | |
| if first_commit_time > task_timestamp: | |
| return { | |
| "passed": True, | |
| "score": 1.0, | |
| "reason": f"Repo created after task ({first_commit_time} > {task_timestamp})", | |
| } | |
| else: | |
| return { | |
| "passed": False, | |
| "score": 0.0, | |
| "reason": f"Repo existed before task ({first_commit_time} <= {task_timestamp})", | |
| } | |
| except Exception as e: | |
| logger.error(f"Error checking repo creation time: {e}") | |
| return {"passed": False, "score": 0.0, "reason": f"Error: {e}"} | |
| def check_mit_license(self) -> dict[str, Any]: | |
| """Check if repo has MIT LICENSE in root. | |
| Returns: | |
| Check result | |
| """ | |
| try: | |
| license_path = self.clone_dir / "LICENSE" | |
| if not license_path.exists(): | |
| return { | |
| "passed": False, | |
| "score": 0.0, | |
| "reason": "No LICENSE file found in root", | |
| } | |
| content = license_path.read_text() | |
| if "MIT License" in content or "MIT" in content[:200]: | |
| return { | |
| "passed": True, | |
| "score": 1.0, | |
| "reason": "MIT LICENSE found", | |
| } | |
| else: | |
| return { | |
| "passed": False, | |
| "score": 0.0, | |
| "reason": "LICENSE file exists but is not MIT", | |
| } | |
| except Exception as e: | |
| logger.error(f"Error checking LICENSE: {e}") | |
| return {"passed": False, "score": 0.0, "reason": f"Error: {e}"} | |
| def check_readme(self) -> dict[str, Any]: | |
| """Check README.md quality. | |
| Returns: | |
| Check result | |
| """ | |
| try: | |
| readme_path = self.clone_dir / "README.md" | |
| if not readme_path.exists(): | |
| return { | |
| "passed": False, | |
| "score": 0.0, | |
| "reason": "No README.md found", | |
| } | |
| content = readme_path.read_text() | |
| # Basic quality checks | |
| has_title = bool(re.search(r"^#\s+.+", content, re.MULTILINE)) | |
| has_sections = content.count("#") >= 3 | |
| has_enough_content = len(content) >= 200 | |
| has_code_blocks = "```" in content | |
| score = sum([has_title, has_sections, has_enough_content, has_code_blocks]) / 4 | |
| return { | |
| "passed": score >= 0.75, | |
| "score": score, | |
| "reason": f"README quality: {score:.0%} (title={has_title}, " | |
| f"sections={has_sections}, content={has_enough_content}, code={has_code_blocks})", | |
| } | |
| except Exception as e: | |
| logger.error(f"Error checking README: {e}") | |
| return {"passed": False, "score": 0.0, "reason": f"Error: {e}"} | |
| def check_no_secrets(self) -> dict[str, Any]: | |
| """Check for common secret patterns in git history. | |
| Returns: | |
| Check result | |
| """ | |
| try: | |
| # Check for common secret patterns | |
| secret_patterns = [ | |
| r"sk-[a-zA-Z0-9]{32,}", # API keys | |
| r"ghp_[a-zA-Z0-9]{36,}", # GitHub tokens | |
| r"AKIA[0-9A-Z]{16}", # AWS keys | |
| r"password\s*=\s*['\"][^'\"]{8,}", # Hardcoded passwords | |
| ] | |
| found_secrets = [] | |
| # Check all files in current commit | |
| for item in self.clone_dir.rglob("*"): | |
| if item.is_file() and not item.name.startswith(".git"): | |
| try: | |
| content = item.read_text(errors="ignore") | |
| for pattern in secret_patterns: | |
| if re.search(pattern, content, re.IGNORECASE): | |
| found_secrets.append(str(item.relative_to(self.clone_dir))) | |
| except Exception: | |
| pass | |
| if found_secrets: | |
| return { | |
| "passed": False, | |
| "score": 0.0, | |
| "reason": f"Potential secrets found in: {', '.join(found_secrets[:3])}", | |
| } | |
| else: | |
| return { | |
| "passed": True, | |
| "score": 1.0, | |
| "reason": "No obvious secrets detected", | |
| } | |
| except Exception as e: | |
| logger.error(f"Error checking secrets: {e}") | |
| return {"passed": True, "score": 1.0, "reason": "Could not check secrets"} | |