Spaces:
Sleeping
Sleeping
| 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() | |