Spaces:
Sleeping
Sleeping
import gradio as gr | |
import requests | |
import subprocess | |
import git | |
import zipfile | |
import io | |
from getpass import getpass | |
import radon.complexity as radon_complexity | |
import pylint.lint | |
from pylint.reporters.text import TextReporter | |
# Function to authenticate GitHub and fetch the user's repositories | |
def authenticate_github(token): | |
headers = { | |
"Authorization": f"token {token}" | |
} | |
# Fetch the list of repositories | |
response = requests.get("https://api.github.com/user/repos", headers=headers) | |
if response.status_code == 200: | |
repos = response.json() | |
repo_names = [repo['name'] for repo in repos] | |
return repo_names | |
else: | |
return "Error: Failed to fetch repositories" | |
# Function to download the repo as a zip file from GitHub API | |
def download_repo(github_url): | |
repo_name = github_url.split('/')[-1] | |
repo_owner = github_url.split('/')[-2] | |
api_url = f"https://github.com/{repo_owner}/{repo_name}/archive/refs/heads/main.zip" | |
# Download the zip file | |
response = requests.get(api_url) | |
# Extract the zip file | |
zip_file = zipfile.ZipFile(io.BytesIO(response.content)) | |
zip_file.extractall(f"/content/repos/{repo_name}") | |
return f"/content/repos/{repo_name}" | |
# Function to fetch the GitHub repo using SSH or token for private repos | |
def fetch_repo(github_url, token=None): | |
try: | |
# Check if the repository is private or public | |
if token: | |
repo_name = github_url.split('/')[-1] | |
repo_owner = github_url.split('/')[-2] | |
clone_url = f"https://{token}@github.com/{repo_owner}/{repo_name}.git" | |
else: | |
repo_name = github_url.split('/')[-1] | |
repo_owner = github_url.split('/')[-2] | |
clone_url = f"[email protected]:{repo_owner}/{repo_name}.git" | |
# Create a temporary directory to clone the repo | |
temp_dir = f"/content/repos/{repo_name}" | |
# Check if repo already exists | |
if not os.path.exists(temp_dir): | |
# If SSH method fails, fallback to downloading as a zip | |
try: | |
git.Repo.clone_from(clone_url, temp_dir) | |
except Exception as e: | |
return download_repo(github_url) | |
return temp_dir | |
except Exception as e: | |
return f"Error: {str(e)}" | |
# Function to calculate cyclomatic complexity using Radon | |
def analyze_complexity(repo_path): | |
result = subprocess.run(['radon', 'cc', repo_path, '--json'], stdout=subprocess.PIPE) | |
complexity_data = result.stdout.decode('utf-8') | |
return complexity_data | |
# Function to run pylint for linting | |
def analyze_linting(repo_path): | |
pylint_output = [] | |
pylint_runner = pylint.lint.Run([repo_path], reporter=TextReporter(pylint_output)) | |
return "\n".join(pylint_output) | |
# Function to check test coverage | |
def analyze_coverage(repo_path): | |
result = subprocess.run(['pytest', '--cov', repo_path], stdout=subprocess.PIPE) | |
coverage_data = result.stdout.decode('utf-8') | |
return coverage_data | |
# Function to check for code duplication with jscpd | |
def analyze_duplication(repo_path): | |
result = subprocess.run(['jscpd', repo_path, '--reporters', 'text'], stdout=subprocess.PIPE) | |
duplication_data = result.stdout.decode('utf-8') | |
return duplication_data | |
# Main function to analyze the repository | |
def analyze_code(github_url, token=None): | |
try: | |
repo_path = fetch_repo(github_url, token) | |
# Perform analysis | |
complexity = analyze_complexity(repo_path) | |
linting = analyze_linting(repo_path) | |
coverage = analyze_coverage(repo_path) | |
duplication = analyze_duplication(repo_path) | |
# Combine results | |
results = f"### Cyclomatic Complexity Analysis\n{complexity}\n\n" | |
results += f"### Linting Results\n{linting}\n\n" | |
results += f"### Test Coverage\n{coverage}\n\n" | |
results += f"### Code Duplication\n{duplication}\n" | |
return results | |
except Exception as e: | |