From 33f6cf34dd6c9c704211c0ea0e2025300e78f19a Mon Sep 17 00:00:00 2001 From: paulovmr <832830+paulovmr@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:34:10 -0300 Subject: [PATCH] RHOAIENG-10972: Create a script to automate library upgrades --- scripts/README.md | 20 +++ scripts/update_library_version.sh | 205 ++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 scripts/README.md create mode 100755 scripts/update_library_version.sh diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 000000000..aaead3450 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,20 @@ +# Scripts + +## update_library_version.sh + +This script updates the version of a specified library in Pipfile and requirements-elyra.txt files, only if the new version is higher. It can optionally run `pipenv lock` after updating the version. + +### Examples + +Update the `numpy` library to version `2.0.1` in all files under `./myproject`, and run `pipenv lock`: + +```sh +./update_library_version.sh ./myproject numpy 2.0.1 '' '' true +``` + +Update the `pandas` library to version `2.2.2` in all files under `./myproject` where the directory contains `include` or `this`, excluding directories containing `exclude` or `that`, and do not run `pipenv lock`: + +```sh +./update_library_version.sh ./myproject pandas 2.2.2 'include|this' 'exclude|that' false +``` + diff --git a/scripts/update_library_version.sh b/scripts/update_library_version.sh new file mode 100755 index 000000000..fc64875f2 --- /dev/null +++ b/scripts/update_library_version.sh @@ -0,0 +1,205 @@ +#!/bin/bash + +# Check if the script is running on Linux +if [[ "$OSTYPE" != "linux-gnu"* ]]; then + echo "Error: This script can only be run on Linux." + exit 1 +fi + +# Detailed help message +print_help() { + echo "Usage: $0 " + echo + echo "Parameters:" + echo " directory The root directory to start searching for Pipfile and requirements-elyra.txt files." + echo " library_name The name of the library to update." + echo " new_version The new version to set for the library." + echo " include_paths_with A pipe-separated list of substrings; only files in directories containing at least one of these substrings will be processed." + echo " exclude_paths_with A pipe-separated list of substrings; files in directories containing any of these substrings will be excluded." + echo " lock_files Whether to run 'pipenv lock' after updating the library version (true or false)." + echo + echo "Examples:" + echo " $0 ./myproject numpy 2.0.1 '' '' true" + echo " $0 ./myproject pandas 2.2.2 'include|this' 'exclude|that' false" +} + +# Check if the correct number of arguments are passed +if [ "$#" -ne 6 ]; then + print_help + exit 1 +fi + +# Arguments +directory=$1 +library_name=$2 +new_version=$3 +include_paths_with=$4 +exclude_paths_with=$5 +lock_files=$6 + +# Print arguments +echo "Arguments:" +echo " directory = $directory" +echo " library_name = $library_name" +echo " new_version = $new_version" +echo " include_paths_with = $include_paths_with" +echo " exclude_paths_with = $exclude_paths_with" +echo " lock_files = $lock_files" + +# Function to check if one version is higher than the other +# Returns 0 if the first version is greater and 1 if the second is greater or equal +is_version_higher() { + local ver1=$1 + local ver2=$2 + + # Remove any non-numeric, non-dot characters from the beginning (before the first number, which represents the version specifier) + ver1=$(echo "$ver1" | sed 's/^[^0-9.]*//') + ver2=$(echo "$ver2" | sed 's/^[^0-9.]*//') + + # Split each segment of the version numbers + IFS='.' read -r -a ver1_parts <<< "$ver1" + IFS='.' read -r -a ver2_parts <<< "$ver2" + + for ((i = 0; i < ${#ver1_parts[@]} || i < ${#ver2_parts[@]}; i++)); do + # Use 0 if a part is missing + v1=${ver1_parts[i]:-0} + v2=${ver2_parts[i]:-0} + + # Compare the parts + if ((v1 > v2)); then + return 0 + fi + done + + return 1 +} + +# Function to update the library version in Pipfile files, only if the new version is higher +update_library_version_pipfile() { + local file=$1 + local lib=$2 + local new_ver=$3 + local include_paths_with=$4 + local exclude_paths_with=$5 + local lock_files=$6 + local directory=$(dirname "$file") + local filename=$(basename "$file") + + # Determine if this is an architecture-specific Pipfile (with the "gpu" or "cpu" suffixes) and determine the corresponding lock file name + local is_specific=false + local lockfile="" + if [[ "$filename" == Pipfile.gpu ]]; then + is_specific=true + lockfile="Pipfile.lock.gpu" + elif [[ "$filename" == Pipfile.cpu ]]; then + is_specific=true + lockfile="Pipfile.lock.cpu" + else + lockfile="Pipfile.lock" + fi + + # Check if the file directory has at least one of the substrings (separated by "|") in $include_paths_with + # and does not contain any of the substrings (separated by "|") in $exclude_paths_with + if { [[ -z "$include_paths_with" ]] || [[ "$directory" =~ $include_paths_with ]]; } && { [[ -z "$exclude_paths_with" ]] || [[ ! "$directory" =~ $exclude_paths_with ]]; }; then + echo "Processing $file (directory matches the pattern)" + else + echo "Skipping $file (directory does not match the pattern)" + return + fi + + # Extract the current version and qualifier from the Pipfile + current_line=$(grep -E "^\"?$lib\"? = " "$file") + if [[ $current_line =~ ^\"?$lib\"?[[:space:]]*=[[:space:]]*\"?([=>