Skip to content

Instantly share code, notes, and snippets.

@renxida
Created September 12, 2024 15:55
Show Gist options
  • Save renxida/4cab6730a44a5a3810bcf6cd62423380 to your computer and use it in GitHub Desktop.
Save renxida/4cab6730a44a5a3810bcf6cd62423380 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Define the range of Python versions to test
versions=("3.12" "3.11" "3.10" "3.9" "3.8" "3.7")
# Function to update pyproject.toml
update_pyproject() {
sed -i 's/python = "^[0-9.]*"/python = "^'"$1"'"/' pyproject.toml
rm -f poetry.lock
}
# Create a temporary Dockerfile
cat << EOF > Dockerfile.temp
FROM python:VERSION-slim
RUN pip install poetry
WORKDIR /app
COPY . /app
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
CMD poetry run pytest
EOF
# Function to download Docker image
download_image() {
echo "Downloading Python $1 image..."
docker pull python:$1-slim
echo "Finished downloading Python $1 image"
}
# Function to run the main script
run_main_script() {
mv poetry.lock poetry.lock.backup 2>/dev/null
# Store original Python version
original_version=$(grep '^python = ' pyproject.toml | cut -d'"' -f2)
# Test versions
for i in "${!versions[@]}"; do
version="${versions[i]}"
echo "Testing Python $version"
update_pyproject $version
# Create a version-specific Dockerfile
sed "s/VERSION/$version/" Dockerfile.temp > Dockerfile
# Signal the download pane to start downloading the next version
if [ $((i+1)) -lt ${#versions[@]} ]; then
echo "${versions[$((i+1))]}" > next_version.txt
else
echo "" > next_version.txt # Signal no more versions to download
fi
# Build and run Docker container
if docker build -t python-test:$version . && docker run --rm python-test:$version; then
echo "Python $version is compatible"
lowest_compatible=$version
else
echo "Python $version is not compatible"
break
fi
done
# Clean up
rm -f Dockerfile Dockerfile.temp
if [ -n "$lowest_compatible" ]; then
echo "Lowest compatible Python version: $lowest_compatible"
update_pyproject $lowest_compatible
echo "Updated pyproject.toml to use Python ^$lowest_compatible"
else
echo "No compatible Python version found"
echo "Restoring original Python version constraint"
update_pyproject ${original_version#^}
mv poetry.lock.backup poetry.lock 2>/dev/null
fi
# Signal that we're done
touch main_script_done.flag
}
# Function to handle downloads
handle_downloads() {
while true; do
if [[ -f next_version.txt ]]; then
version=$(cat next_version.txt)
rm -f next_version.txt
if [[ -n $version ]]; then
download_image $version
fi
fi
if [[ -f main_script_done.flag ]]; then
break
fi
sleep 1
done
}
# Start a new tmux session
tmux new-session -d -s pytest_session
# Split the window horizontally
tmux split-window -h
# Set up both panes with all necessary functions
for pane in left right; do
tmux send-keys -t $pane "$(declare -f update_pyproject)" C-m
tmux send-keys -t $pane "$(declare -f download_image)" C-m
tmux send-keys -t $pane "$(declare -f run_main_script)" C-m
tmux send-keys -t $pane "$(declare -f handle_downloads)" C-m
tmux send-keys -t $pane "versions=(${versions[*]})" C-m
done
# Run the main script in the left pane
tmux send-keys -t left "run_main_script" C-m
# Run the download handler in the right pane
tmux send-keys -t right "handle_downloads" C-m
# Attach to the tmux session
tmux attach-session -t pytest_session
# After the tmux session ends, perform cleanup
tmux kill-session -t pytest_session
rm -f next_version.txt main_script_done.flag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment