Skip to content

Commit bad8743

Browse files
committed
feat: add automated dependency lock generation script (pylock_generator.sh)
1 parent bccfcb6 commit bad8743

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

scripts/pylocks_generator.sh

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# ----------------------------
5+
# CONFIGURATION
6+
# ----------------------------
7+
CPU_INDEX="--index-url=https://console.redhat.com/api/pypi/public-rhai/rhoai/3.0/cpu-ubi9/simple/"
8+
CUDA_INDEX="--index-url=https://console.redhat.com/api/pypi/public-rhai/rhoai/3.0/cuda-ubi9/simple/"
9+
ROCM_INDEX="--index-url=https://console.redhat.com/api/pypi/public-rhai/rhoai/3.0/rocm-ubi9/simple/"
10+
11+
MAIN_DIRS=("jupyter" "runtimes" "rstudio" "codeserver")
12+
13+
# ----------------------------
14+
# HELPER FUNCTIONS
15+
# ----------------------------
16+
info() { echo -e "🔹 \033[1;34m$1\033[0m"; }
17+
warn() { echo -e "⚠️ \033[1;33m$1\033[0m"; }
18+
error() { echo -e "❌ \033[1;31m$1\033[0m"; }
19+
ok() { echo -e "✅ \033[1;32m$1\033[0m"; }
20+
21+
# ----------------------------
22+
# PRE-FLIGHT CHECK
23+
# ----------------------------
24+
if ! command -v uv &>/dev/null; then
25+
error "uv command not found. Please install uv: https://github.com/astral-sh/uv"
26+
exit 1
27+
fi
28+
29+
# (Optional) check uv version (requires version >= 0.4.0)
30+
UV_MIN_VERSION="0.4.0"
31+
UV_VERSION=$(uv --version 2>/dev/null | awk '{print $2}' || echo "0.0.0")
32+
33+
version_ge() {
34+
# returns 0 if $1 >= $2
35+
[ "$(printf '%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]
36+
}
37+
38+
if ! version_ge "$UV_VERSION" "$UV_MIN_VERSION"; then
39+
error "uv version $UV_VERSION found, but >= $UV_MIN_VERSION is required."
40+
error "Please upgrade uv: https://github.com/astral-sh/uv"
41+
exit 1
42+
fi
43+
44+
# ----------------------------
45+
# GET TARGET DIRECTORIES
46+
# ----------------------------
47+
if [ $# -gt 0 ]; then
48+
TARGET_DIRS=("$1")
49+
else
50+
info "Scanning main directories for Python projects..."
51+
TARGET_DIRS=()
52+
for base in "${MAIN_DIRS[@]}"; do
53+
if [ -d "$base" ]; then
54+
while IFS= read -r -d '' pyproj; do
55+
TARGET_DIRS+=("$(dirname "$pyproj")")
56+
done < <(find "$base" -type f -name "pyproject.toml" -print0)
57+
fi
58+
done
59+
fi
60+
61+
if [ ${#TARGET_DIRS[@]} -eq 0 ]; then
62+
error "No directories containing pyproject.toml were found."
63+
exit 1
64+
fi
65+
66+
# ----------------------------
67+
# MAIN LOOP
68+
# ----------------------------
69+
FAILED_DIRS=()
70+
SUCCESS_DIRS=()
71+
72+
for TARGET_DIR in "${TARGET_DIRS[@]}"; do
73+
echo
74+
echo "==================================================================="
75+
info "Processing directory: $TARGET_DIR"
76+
echo "==================================================================="
77+
78+
cd "$TARGET_DIR" || continue
79+
mkdir -p uv.lock
80+
PYTHON_VERSION="${PWD##*-}"
81+
82+
# Validate Python version extraction
83+
if [[ ! "$PYTHON_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
84+
warn "Could not extract valid Python version from directory name: $PWD"
85+
warn "Expected directory format: .../ubi9-python-X.Y"
86+
cd - >/dev/null
87+
continue
88+
fi
89+
90+
# Detect available Dockerfiles (flavors)
91+
HAS_CPU=false
92+
HAS_CUDA=false
93+
HAS_ROCM=false
94+
[ -f "Dockerfile.cpu" ] && HAS_CPU=true
95+
[ -f "Dockerfile.cuda" ] && HAS_CUDA=true
96+
[ -f "Dockerfile.rocm" ] && HAS_ROCM=true
97+
98+
if ! $HAS_CPU && ! $HAS_CUDA && ! $HAS_ROCM; then
99+
warn "No Dockerfiles found in $TARGET_DIR (cpu/cuda/rocm). Skipping."
100+
cd - >/dev/null
101+
continue
102+
fi
103+
104+
echo "📦 Python version: $PYTHON_VERSION"
105+
echo "🧩 Detected flavors:"
106+
$HAS_CPU && echo " • CPU"
107+
$HAS_CUDA && echo " • CUDA"
108+
$HAS_ROCM && echo " • ROCm"
109+
echo
110+
111+
DIR_SUCCESS=true
112+
113+
run_lock() {
114+
local flavor="$1"
115+
local index="$2"
116+
local output="uv.lock/pylock.${flavor}.toml"
117+
118+
echo "➡️ Generating ${flavor^^} lock file..."
119+
set +e
120+
uv pip compile pyproject.toml \
121+
--output-file "$output" \
122+
--format pylock.toml \
123+
--generate-hashes \
124+
--emit-index-url \
125+
--python-version="$PYTHON_VERSION" \
126+
--python-platform linux \
127+
--no-annotate \
128+
$index
129+
local status=$?
130+
set -e
131+
132+
if [ $status -ne 0 ]; then
133+
warn "${flavor^^} lock failed in $TARGET_DIR"
134+
rm -f "$output"
135+
DIR_SUCCESS=false
136+
else
137+
ok "${flavor^^} lock generated successfully."
138+
fi
139+
}
140+
141+
$HAS_CPU && run_lock "cpu" "$CPU_INDEX"
142+
$HAS_CUDA && run_lock "cuda" "$CUDA_INDEX"
143+
$HAS_ROCM && run_lock "rocm" "$ROCM_INDEX"
144+
145+
if $DIR_SUCCESS; then
146+
SUCCESS_DIRS+=("$TARGET_DIR")
147+
else
148+
FAILED_DIRS+=("$TARGET_DIR")
149+
fi
150+
151+
cd - >/dev/null
152+
done
153+
154+
# ----------------------------
155+
# SUMMARY
156+
# ----------------------------
157+
echo
158+
echo "==================================================================="
159+
ok "Lock generation complete."
160+
echo "==================================================================="
161+
162+
if [ ${#SUCCESS_DIRS[@]} -gt 0 ]; then
163+
echo "✅ Successfully generated locks for:"
164+
for d in "${SUCCESS_DIRS[@]}"; do
165+
echo "$d"
166+
done
167+
fi
168+
169+
if [ ${#FAILED_DIRS[@]} -gt 0 ]; then
170+
echo
171+
warn "Failed lock generation for:"
172+
for d in "${FAILED_DIRS[@]}"; do
173+
echo "$d"
174+
echo "Please comment out the missing package to continue and report the missing package to aipcc"
175+
done
176+
fi

0 commit comments

Comments
 (0)