Last active
May 1, 2025 23:24
-
-
Save CaseOf/7c15e3e93a58ff3264cb8c9a1b56c3d3 to your computer and use it in GitHub Desktop.
Gentoo PYTHON_COMPAT additions post-sync to given ebuilds script generated by Claude 3.7 Sonnet
This file contains hidden or 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
#!/bin/bash | |
# | |
# Script name: fix-python-compat.sh | |
# Description: Adds specified Python versions to PYTHON_COMPAT variables in Gentoo ebuilds | |
# Location: /etc/portage/postsync.d/fix-python-compat | |
# Make sure to: | |
# - chmod +x /etc/portage/postsync.d/fix-python-compat | |
# - Have pkgdev installed: emerge --ask dev-util/pkgdev | |
# | |
# Configuration - add packages and Python versions here | |
declare -A PACKAGES_TO_FIX | |
PACKAGES_TO_FIX=( | |
# Format options: | |
# [category/package]="python_version1 python_version2 ..." # All versions | |
# [category/package::version]="python_version1 python_version2 ..." # Specific version | |
# [category/package::version1,version2]="python_version1 python_version2 ..." # Multiple specific versions | |
# | |
# Examples: | |
["dev-python/example"]="python3_11 python3_12" # All versions | |
["app-misc/another-package::2.0"]="python3_12" # Only version 2.0 | |
["dev-python/specific::1.2,1.3,1.4"]="python3_11 python3_12" # Only versions 1.2, 1.3, and 1.4 | |
["sci-libs/example::3.1-r2"]="python3_11" # Only version 3.1 revision 2 | |
["app-admin/tool::1.0,1.0-r1,1.0-r2"]="python3_12" # Base version 1.0 and specific revisions | |
# Add more packages as needed | |
) | |
# Path to the Gentoo repository | |
PORTDIR="${PORTDIR:-/var/db/repos/gentoo}" | |
# Log file | |
LOG_FILE="/var/log/portage/python-compat-fixes.log" | |
BACKUP_DIR="/var/backup/portage-ebuilds/$(date +%Y%m%d)" | |
# Create log and backup directories if they don't exist | |
mkdir -p "$(dirname "$LOG_FILE")" | |
mkdir -p "$BACKUP_DIR" | |
# Log function | |
log() { | |
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" | |
} | |
# Function to check if a version matches any pattern in a comma-separated list | |
matches_version() { | |
local version="$1" | |
local patterns="$2" | |
local pattern | |
IFS=',' read -ra PATTERN_ARRAY <<< "$patterns" | |
for pattern in "${PATTERN_ARRAY[@]}"; do | |
# Handle exact matches (including revision) | |
if [[ "$version" == "$pattern" ]]; then | |
return 0 # Exact match found | |
fi | |
# Handle base version match (ignoring revision) | |
base_version="${version%%-r*}" | |
if [[ "$pattern" == "$base_version" && "$version" =~ -r[0-9]+ ]]; then | |
return 0 # Base version matches and we have a revision | |
fi | |
# Handle specific revision match | |
if [[ "$pattern" =~ ^([0-9][0-9a-z._]*)-r([0-9]+)$ ]]; then | |
base_pattern="${BASH_REMATCH[1]}" | |
rev_pattern="${BASH_REMATCH[2]}" | |
if [[ "$version" =~ ^${base_pattern}-r${rev_pattern}$ ]]; then | |
return 0 # Revision-specific match | |
fi | |
fi | |
done | |
return 1 # No match | |
} | |
# Check for required dependencies | |
check_dependencies() { | |
local missing_deps=false | |
# Check for pkgdev | |
if ! command -v pkgdev >/dev/null 2>&1; then | |
log "WARNING: pkgdev is not installed. Manifest files won't be updated." | |
log "Install pkgdev with: emerge --ask dev-util/pkgdev" | |
missing_deps=true | |
fi | |
# Return status | |
if [ "$missing_deps" = true ]; then | |
return 1 | |
fi | |
return 0 | |
} | |
log "Starting Python compatibility fixes" | |
# Check dependencies | |
check_dependencies | |
# Process each package | |
for package_key in "${!PACKAGES_TO_FIX[@]}"; do | |
python_versions="${PACKAGES_TO_FIX[$package_key]}" | |
# Check if we have a version constraint | |
package="$package_key" | |
version_constraint="" | |
if [[ "$package_key" == *"::"* ]]; then | |
# Split at the :: delimiter | |
package="${package_key%%::*}" | |
version_constraint="${package_key#*::}" | |
log "Processing package: $package - Versions: $version_constraint - Adding Python versions: $python_versions" | |
else | |
log "Processing package: $package - All versions - Adding Python versions: $python_versions" | |
fi | |
# Find all ebuilds for this package | |
package_dir="$PORTDIR/$package" | |
if [ ! -d "$package_dir" ]; then | |
log "ERROR: Package directory not found: $package_dir" | |
continue | |
fi | |
# Process each ebuild file | |
for ebuild in "$package_dir"/*.ebuild; do | |
if [ ! -f "$ebuild" ]; then | |
log "No ebuilds found for $package" | |
continue | |
fi | |
ebuild_name=$(basename "$ebuild") | |
# Extract version from ebuild filename (including revision numbers) | |
ebuild_version=$(echo "$ebuild_name" | sed -r 's/^[^0-9]*-([0-9][0-9a-z._]*(-r[0-9]+)?)\.ebuild$/\1/') | |
# If we have a version constraint, check if this ebuild matches | |
if [ -n "$version_constraint" ]; then | |
if ! matches_version "$ebuild_version" "$version_constraint"; then | |
log "Skipping ebuild $ebuild_name (doesn't match version constraint: $version_constraint)" | |
continue | |
fi | |
fi | |
log "Examining ebuild: $ebuild_name (version: $ebuild_version)" | |
# Check if the ebuild contains PYTHON_COMPAT | |
if grep -q "PYTHON_COMPAT=" "$ebuild"; then | |
# Create backup | |
backup_file="$BACKUP_DIR/$(dirname "$package")_${ebuild_name}.bak" | |
mkdir -p "$(dirname "$backup_file")" | |
cp "$ebuild" "$backup_file" | |
log "Created backup: $backup_file" | |
# Process the PYTHON_COMPAT line | |
needs_update=false | |
for py_ver in $python_versions; do | |
if ! grep -q "PYTHON_COMPAT=.*$py_ver" "$ebuild"; then | |
needs_update=true | |
log "Need to add $py_ver to $ebuild_name" | |
fi | |
done | |
if [ "$needs_update" = true ]; then | |
# Update the PYTHON_COMPAT line | |
# This sed command finds the PYTHON_COMPAT line and adds the new versions before the closing parenthesis | |
for py_ver in $python_versions; do | |
# Check if it already contains this version | |
if ! grep -q "PYTHON_COMPAT=.*$py_ver" "$ebuild"; then | |
sed -i.tmp -r "s/(PYTHON_COMPAT=\([^)]*)/\1 $py_ver/" "$ebuild" | |
# Clean up the tmp file | |
rm -f "${ebuild}.tmp" | |
log "Added $py_ver to PYTHON_COMPAT in $ebuild_name" | |
fi | |
done | |
log "Updated ebuild: $ebuild_name" | |
# Update manifest after modifying the ebuild | |
if command -v pkgdev >/dev/null 2>&1; then | |
log "Updating Manifest for $package_dir" | |
( | |
cd "$(dirname "$package_dir")" || { log "ERROR: Failed to change directory to $(dirname "$package_dir")"; return 1; } | |
if ! pkgdev manifest -f "$(basename "$package_dir")"; then | |
log "ERROR: Failed to update Manifest for $package_dir" | |
else | |
log "Successfully updated Manifest for $package_dir" | |
fi | |
) | |
else | |
log "WARNING: pkgdev is not installed. Manifest files won't be updated." | |
log "Install pkgdev with: emerge --ask dev-util/pkgdev" | |
fi | |
else | |
log "Ebuild already includes specified Python versions: $ebuild_name" | |
fi | |
else | |
log "WARNING: No PYTHON_COMPAT found in $ebuild_name" | |
fi | |
done | |
done | |
log "Python compatibility fixes completed" | |
# Update eix database if it's installed | |
if command -v eix-update >/dev/null 2>&1; then | |
log "Updating eix database..." | |
if ! eix-update; then | |
log "WARNING: Failed to update eix database" | |
else | |
log "Successfully updated eix database" | |
fi | |
else | |
log "Note: eix is not installed. No need to update its database." | |
fi | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment