generate_requirements.pyโข6.23 kB
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""
Generate requirements.txt from pyproject.toml
Ensures consistency in dependency management
"""
import re
import toml
import sys
from pathlib import Path
def generate_requirements():
"""Generate requirements.txt from pyproject.toml"""
# Read pyproject.toml
try:
with open('pyproject.toml', 'r', encoding='utf-8') as f:
pyproject = toml.load(f)
except FileNotFoundError:
print("โ pyproject.toml not found")
sys.exit(1)
# Get main dependencies
dependencies = pyproject.get('project', {}).get('dependencies', [])
# Get development dependencies
dev_dependencies = pyproject.get('project', {}).get('optional-dependencies', {}).get('dev', [])
# Generate requirements.txt
requirements_content = []
# Add header comment
requirements_content.append("# Main dependencies - auto-generated from pyproject.toml")
requirements_content.append("# Do not edit this file manually, use 'python generate_requirements.py' to regenerate")
requirements_content.append("")
# Add main dependencies
requirements_content.append("# === Core Dependencies ===")
for dep in dependencies:
requirements_content.append(dep)
requirements_content.append("")
requirements_content.append("# === Development Dependencies ===")
for dep in dev_dependencies:
requirements_content.append(dep)
# Write requirements.txt
with open('requirements.txt', 'w', encoding='utf-8') as f:
f.write('\n'.join(requirements_content))
print(f"โ
Generated requirements.txt")
print(f" Main dependencies: {len(dependencies)} items")
print(f" Dev dependencies: {len(dev_dependencies)} items")
def generate_requirements_dev():
"""Generate requirements-dev.txt (only development dependencies)"""
pyproject_path = Path("pyproject.toml")
if not pyproject_path.exists():
print("Error: pyproject.toml not found")
return
with open(pyproject_path, 'r', encoding='utf-8') as f:
data = toml.load(f)
# Get development dependencies
dev_dependencies = data.get('project', {}).get('optional-dependencies', {}).get('dev', [])
# Generate requirements-dev.txt
content = []
content.append("# Development dependencies - auto-generated from pyproject.toml")
content.append("# Installation command: pip install -r requirements-dev.txt")
content.append("")
for dep in dev_dependencies:
content.append(dep)
# Write file
dev_requirements_path = Path("requirements-dev.txt")
with open(dev_requirements_path, 'w', encoding='utf-8') as f:
f.write('\n'.join(content))
print(f"โ
Generated requirements-dev.txt ({len(dev_dependencies)} development dependencies)")
def verify_consistency():
"""Verify dependency consistency"""
def extract_packages_from_requirements():
"""Extract package names from requirements.txt"""
packages = set()
try:
with open('requirements.txt', 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
# Extract package name (remove version)
pkg = re.split(r'[>=<\[]', line)[0].strip()
if pkg:
packages.add(pkg.lower())
except FileNotFoundError:
print("requirements.txt not found")
return packages
def extract_packages_from_pyproject():
"""Extract package names from pyproject.toml"""
packages = set()
try:
with open('pyproject.toml', 'r') as f:
data = toml.load(f)
# Get main dependencies
dependencies = data.get('project', {}).get('dependencies', [])
for dep in dependencies:
pkg = re.split(r'[>=<\[]', dep)[0].strip()
if pkg:
packages.add(pkg.lower())
# Get development dependencies
dev_deps = data.get('project', {}).get('optional-dependencies', {}).get('dev', [])
for dep in dev_deps:
pkg = re.split(r'[>=<\[]', dep)[0].strip()
if pkg:
packages.add(pkg.lower())
except FileNotFoundError:
print("pyproject.toml not found")
return packages
req_packages = extract_packages_from_requirements()
toml_packages = extract_packages_from_pyproject()
only_in_req = req_packages - toml_packages
only_in_toml = toml_packages - req_packages
if len(only_in_req) == 0 and len(only_in_toml) == 0:
print("โ
Dependency consistency verification passed!")
return True
else:
print("โ ๏ธ Found dependency inconsistencies:")
if only_in_req:
print(f" Only in requirements.txt: {sorted(only_in_req)}")
if only_in_toml:
print(f" Only in pyproject.toml: {sorted(only_in_toml)}")
return False
if __name__ == "__main__":
print("๐ Generating requirements.txt from pyproject.toml...")
generate_requirements()
generate_requirements_dev()
print()
print("๐ Verifying dependency consistency...")
verify_consistency()
print("โจ Completed!")