Spaces:
Running
Running
File size: 4,145 Bytes
f0b7f76 0a5d37a f0b7f76 0a5d37a f0b7f76 8790563 f0b7f76 0a5d37a f0b7f76 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
import gradio as gr
import requests
import git
import os
import subprocess
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 download 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"git@github.com:{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:
return f"Error: {str(e)}"
# Create Gradio Interface
def gradio_interface():
gr.Interface(
fn=analyze_code,
inputs=[
gr.Textbox(label="GitHub Repository URL", placeholder="Enter the URL of the GitHub repo"),
gr.Textbox(label="GitHub Token (Optional)", type="password")
],
outputs="text",
live=True,
title="GitHub Code Quality Analyzer",
description="Enter a GitHub repository URL to analyze its code quality (complexity, linting, coverage, duplication)."
).launch(share=True)
gradio_interface()
|