temp / instructor /checks /static_checks.py
CheeksTheGeek's picture
Initial commit: LLM Code Deployment System
c5292d8 unverified
Raw
History Blame Contribute Delete
6.67 kB
"""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"}