codeanalyzer / app.py
kevin1911's picture
Update app.py
0a5d37a verified
raw
history blame
4.15 kB
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"[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:
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()