@@ -3,6 +3,7 @@ set -euo pipefail
33
44DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
55. " $DIR /lib/common.sh"
6+ . " $DIR /lib/install_strategy.sh"
67
78ACTION=" ${1:- install} "
89
@@ -12,34 +13,45 @@ ensure_python_distro() {
1213 if ! have python3 && have apt-get; then sudo apt-get update && sudo apt-get install -y python3 python3-pip; fi
1314}
1415
16+ # Get current Python version managed by uv
17+ get_uv_python_version () {
18+ if command -v uv > /dev/null 2>&1 ; then
19+ # Get the highest installed Python version
20+ uv python list --only-installed 2> /dev/null | grep -E " ^cpython-[0-9]" | head -1 | sed ' s/cpython-\([0-9.]*\).*/\1/' || true
21+ fi
22+ }
23+
24+ # Install or upgrade Python via uv
25+ uv_install_python () {
26+ local PY_SPEC=" ${UV_PYTHON_SPEC:- 3} "
27+
28+ echo " [python] Installing Python $PY_SPEC via uv..." >&2
29+
30+ # Install the requested Python version
31+ if ! uv python install " $PY_SPEC " 2>&1 ; then
32+ # If exact version fails, try without patch version
33+ local ALT_SPEC=" ${PY_SPEC% .* } "
34+ if [ " $ALT_SPEC " != " $PY_SPEC " ]; then
35+ echo " [python] Trying $ALT_SPEC ..." >&2
36+ uv python install " $ALT_SPEC " 2>&1 || true
37+ fi
38+ fi
39+ }
40+
1541# Create/update a default dev venv using uv if available
1642uv_setup_default_venv () {
1743 if command -v uv > /dev/null 2>&1 ; then
18- # Select Python spec: default to latest 3.x; allow override via UV_PYTHON_SPEC (e.g., 3.13)
19- local PY_SPEC
20- PY_SPEC=" ${UV_PYTHON_SPEC:- 3} "
21- # If a fully pinned X.Y.Z isn't available, fall back to X.Y
22- local ALT_SPEC
23- ALT_SPEC=" $PY_SPEC "
44+ local PY_SPEC=" ${UV_PYTHON_SPEC:- 3} "
45+ local ALT_SPEC=" $PY_SPEC "
2446 case " $PY_SPEC " in
2547 * .* .* ) ALT_SPEC=" ${PY_SPEC% .* } " ;;
26- * ) ALT_SPEC=" $PY_SPEC " ;;
2748 esac
28- # Resolve the exact interpreter path, allowing pre-releases when stable is not yet available
49+
50+ # Find the interpreter
2951 local PY_PATH
30- PY_PATH=" $( uv python find " $PY_SPEC " 2> /dev/null || true) "
31- if [ -z " $PY_PATH " ]; then
32- PY_PATH=" $( uv python find " $ALT_SPEC " 2> /dev/null || true) "
33- fi
34- if [ -z " $PY_PATH " ]; then
35- uv python install " $PY_SPEC " > /dev/null 2>&1 || uv python install " $ALT_SPEC " > /dev/null 2>&1 || true
36- PY_PATH=" $( uv python find " $PY_SPEC " 2> /dev/null || true) "
37- if [ -z " $PY_PATH " ]; then
38- PY_PATH=" $( uv python find " $ALT_SPEC " 2> /dev/null || true) "
39- fi
40- fi
52+ PY_PATH=" $( uv python find " $PY_SPEC " 2> /dev/null || uv python find " $ALT_SPEC " 2> /dev/null || true) "
53+
4154 mkdir -p " $HOME /.venvs" || true
42- # Recreate the default venv to ensure it uses the requested interpreter
4355 if [ -n " $PY_PATH " ] && [ -x " $PY_PATH " ]; then
4456 uv venv --python " $PY_PATH " --clear " $HOME /.venvs/dev" > /dev/null 2>&1 || true
4557 else
@@ -82,15 +94,39 @@ install_or_update_py_cli() {
8294}
8395
8496install_py_stack () {
97+ local before after path
98+ before=" $( get_uv_python_version) "
99+
85100 ensure_uv || true
101+ uv_install_python || true
86102 uv_setup_default_venv || true
87103 install_or_update_py_cli install
104+
105+ after=" $( get_uv_python_version) "
106+ path=" $( command -v python3 2> /dev/null || true) "
107+ printf " [%s] before: %s\n" " python" " ${before:- <none>} "
108+ printf " [%s] after: %s\n" " python" " ${after:- <none>} "
109+ if [ -n " $path " ]; then printf " [%s] path: %s\n" " python" " $path " ; fi
110+
111+ refresh_snapshot " python"
88112}
89113
90114update_py_stack () {
115+ local before after path
116+ before=" $( get_uv_python_version) "
117+
91118 ensure_uv || true
119+ uv_install_python || true
92120 uv_setup_default_venv || true
93121 install_or_update_py_cli upgrade
122+
123+ after=" $( get_uv_python_version) "
124+ path=" $( command -v python3 2> /dev/null || true) "
125+ printf " [%s] before: %s\n" " python" " ${before:- <none>} "
126+ printf " [%s] after: %s\n" " python" " ${after:- <none>} "
127+ if [ -n " $path " ]; then printf " [%s] path: %s\n" " python" " $path " ; fi
128+
129+ refresh_snapshot " python"
94130}
95131
96132uninstall_py_tools () {
@@ -112,6 +148,4 @@ case "$ACTION" in
112148 * ) echo " Usage: $0 {install|update|uninstall|reconcile}" ; exit 2 ;;
113149esac
114150
115- echo " python: $ACTION complete (or attempted)."
116-
117151
0 commit comments