Created
October 8, 2024 15:38
-
-
Save andreagrandi/e38c1854a2bc14ba389d106a57bc7b2d to your computer and use it in GitHub Desktop.
Check Python requirements compatibility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import requests | |
import argparse | |
def extract_package_names(file_content): | |
"""Extract package names from the requirements file content.""" | |
package_names = [] | |
# Regular expression to match package names (excluding the version part) | |
package_regex = re.compile(r'^([a-zA-Z0-9-_]+)==[0-9]+(?:\.[0-9]+)*(?:[-a-zA-Z0-9._]*)?$') | |
for line in file_content.splitlines(): | |
line = line.strip() | |
# Ignore lines that start with -r (referencing another file) | |
if line.startswith('-r'): | |
continue | |
match = package_regex.match(line) | |
if match: | |
package_names.append(match.group(1)) | |
return package_names | |
def get_package_info_from_pypi(package_name): | |
"""Fetch the package info from the PyPI API.""" | |
url = f"https://pypi.org/pypi/{package_name}/json" | |
try: | |
response = requests.get(url) | |
response.raise_for_status() | |
return response.json() | |
except requests.RequestException as e: | |
print(f"Failed to fetch info for {package_name}: {e}") | |
return None | |
def check_python_support(package_info, version): | |
"""Check if the package supports the specified Python version.""" | |
classifiers = package_info.get("info", {}).get("classifiers", []) | |
version_string = f"Programming Language :: Python :: {version}" | |
return version_string in classifiers | |
def parse_txt_files(paths): | |
"""Search all .txt files in the provided paths and extract package names.""" | |
all_packages = [] | |
for path in paths: | |
if not os.path.exists(path): | |
print(f"Path does not exist: {path}") | |
continue | |
# Walk through the directory to find all .txt files | |
for root, _, files in os.walk(path): | |
for file in files: | |
if file.endswith('.txt'): | |
file_path = os.path.join(root, file) | |
with open(file_path, 'r') as f: | |
content = f.read() | |
packages = extract_package_names(content) | |
all_packages.extend(packages) | |
return all_packages | |
def main(): | |
# Set up argument parser | |
parser = argparse.ArgumentParser(description="Check package Python version support.") | |
parser.add_argument('-p', '--paths', nargs='+', required=True, help="Paths to search for .txt files") | |
parser.add_argument('-v', '--version', required=True, help="Python version to check support for (e.g., 3.12)") | |
args = parser.parse_args() | |
search_paths = args.paths | |
python_version = args.version | |
packages = parse_txt_files(search_paths) | |
if not packages: | |
print("No package names found.") | |
return | |
print(f"Total packages found: {len(packages)}") | |
no_python_support = [] | |
for pkg in packages: | |
package_info = get_package_info_from_pypi(pkg) | |
if package_info: | |
if not check_python_support(package_info, python_version): | |
no_python_support.append(pkg) | |
# Calculate the percentage | |
total_packages = len(packages) | |
no_python_support_count = len(no_python_support) | |
percentage_no_python_support = (no_python_support_count / total_packages) * 100 | |
print(f"\nPackages without Python {python_version} support:") | |
for pkg in no_python_support: | |
print(pkg) | |
print(f"\nTotal packages without Python {python_version} support: {no_python_support_count}") | |
print(f"Percentage of packages without Python {python_version} support: {percentage_no_python_support:.2f}%") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment