@@ -57,18 +57,19 @@ PRIMARY_PYTHON?=3.14
5757PYTHON_MIN_VERSION? =3.9
5858
5959# Install packages using the given package installer method.
60- # Supported are `pip` and `uv`. If uv is used, its global availability is
61- # checked. Otherwise, it is installed, either in the virtual environment or
62- # using the `PRIMARY_PYTHON`, dependent on the `VENV_ENABLED` setting. If
63- # `VENV_ENABLED` and uv is selected, uv is used to create the virtual
64- # environment.
60+ # Supported are `pip` and `uv`. When `uv` is selected, a global installation
61+ # is auto-detected and used if available. Otherwise, uv is installed in the
62+ # virtual environment or using `PRIMARY_PYTHON`, depending on the
63+ # `VENV_ENABLED` setting.
6564# Default: pip
6665PYTHON_PACKAGE_INSTALLER? =uv
6766
68- # Flag whether to use a global installed 'uv' or install
69- # it in the virtual environment.
70- # Default: false
71- MXENV_UV_GLOBAL? =true
67+ # Python version for UV to install/use when creating virtual
68+ # environments with global UV. Passed to `uv venv -p VALUE`. Supports version
69+ # specs like `3.11`, `3.14`, `[email protected] `. Defaults to PRIMARY_PYTHON value70+ # for backward compatibility.
71+ # No default value.
72+ UV_PYTHON? =
7273
7374# Flag whether to use virtual environment. If `false`, the
7475# interpreter according to `PRIMARY_PYTHON` found in `PATH` is used.
@@ -233,30 +234,60 @@ else
233234MXENV_PYTHON =$(PRIMARY_PYTHON )
234235endif
235236
236- # Determine the package installer
237+ # Determine the package installer with non-interactive flags
237238ifeq ("$(PYTHON_PACKAGE_INSTALLER ) ","uv")
238- PYTHON_PACKAGE_COMMAND =uv pip
239+ PYTHON_PACKAGE_COMMAND =uv pip --quiet --no-progress
239240else
240241PYTHON_PACKAGE_COMMAND =$(MXENV_PYTHON ) -m pip
241242endif
242243
244+ # Auto-detect global uv availability (simple existence check)
245+ ifeq ("$(PYTHON_PACKAGE_INSTALLER ) ","uv")
246+ UV_AVAILABLE: =$(shell command -v uv >/dev/null 2>&1 && echo "true" || echo "false")
247+ else
248+ UV_AVAILABLE: =false
249+ endif
250+
251+ # Determine installation strategy
252+ USE_GLOBAL_UV: =$(shell [[ "$(PYTHON_PACKAGE_INSTALLER ) " == "uv" && "$(UV_AVAILABLE ) " == "true" ]] && echo "true" || echo "false")
253+ USE_LOCAL_UV: =$(shell [[ "$(PYTHON_PACKAGE_INSTALLER ) " == "uv" && "$(UV_AVAILABLE ) " == "false" ]] && echo "true" || echo "false")
254+
255+ # UV Python version (defaults to PRIMARY_PYTHON for backward compatibility)
256+ UV_PYTHON? =$(PRIMARY_PYTHON )
257+
258+ # Check if global UV is outdated (non-blocking warning)
259+ ifeq ("$(USE_GLOBAL_UV ) ","true")
260+ UV_OUTDATED: =$(shell uv self update --dry-run 2>&1 | grep -q "Would update" && echo "true" || echo "false")
261+ else
262+ UV_OUTDATED: =false
263+ endif
264+
243265MXENV_TARGET: =$(SENTINEL_FOLDER ) /mxenv.sentinel
244266$(MXENV_TARGET ) : $(SENTINEL )
245- ifneq ("$(PYTHON_PACKAGE_INSTALLER )$(MXENV_UV_GLOBAL ) ","uvfalse")
267+ # Validation: Check Python version if not using global uv
268+ ifneq ("$(USE_GLOBAL_UV ) ","true")
246269 @$(PRIMARY_PYTHON) -c "import sys; vi = sys.version_info; sys.exit(1 if (int(vi[0]), int(vi[1])) >= tuple(map(int, '$(PYTHON_MIN_VERSION)'.split('.'))) else 0)" \
247270 && echo "Need Python >= $(PYTHON_MIN_VERSION)" && exit 1 || :
248271else
249- @echo "Use Python $(PYTHON_MIN_VERSION) over uv "
272+ @echo "Using global uv for Python $(UV_PYTHON) "
250273endif
274+ # Validation: Check VENV_FOLDER is set if venv enabled
251275 @[[ "$(VENV_ENABLED)" == "true" && "$(VENV_FOLDER)" == "" ]] \
252276 && echo "VENV_FOLDER must be configured if VENV_ENABLED is true" && exit 1 || :
253- @[[ "$(VENV_ENABLED)$(PYTHON_PACKAGE_INSTALLER)" == "falseuv" ]] \
277+ # Validation: Check uv not used with system Python
278+ @[[ "$(VENV_ENABLED)" == "false" && "$(PYTHON_PACKAGE_INSTALLER)" == "uv" ]] \
254279 && echo "Package installer uv does not work with a global Python interpreter." && exit 1 || :
280+ # Warning: Notify if global UV is outdated
281+ ifeq ("$(UV_OUTDATED ) ","true")
282+ @echo "WARNING: A newer version of uv is available. Run 'uv self update' to upgrade."
283+ endif
284+
285+ # Create virtual environment
255286ifeq ("$(VENV_ENABLED ) ", "true")
256287ifeq ("$(VENV_CREATE ) ", "true")
257- ifeq ("$(PYTHON_PACKAGE_INSTALLER )$( MXENV_UV_GLOBAL ) ","uvtrue ")
258- @echo "Setup Python Virtual Environment using package 'uv' at '$(VENV_FOLDER)'"
259- @uv venv -p $(PRIMARY_PYTHON ) --seed $(VENV_FOLDER)
288+ ifeq ("$(USE_GLOBAL_UV ) ","true ")
289+ @echo "Setup Python Virtual Environment using global uv at '$(VENV_FOLDER)'"
290+ @uv venv --quiet --no-progress - p $(UV_PYTHON ) --seed $(VENV_FOLDER)
260291else
261292 @echo "Setup Python Virtual Environment using module 'venv' at '$(VENV_FOLDER)'"
262293 @$(PRIMARY_PYTHON) -m venv $(VENV_FOLDER)
@@ -266,10 +297,14 @@ endif
266297else
267298 @echo "Using system Python interpreter"
268299endif
269- ifeq ("$(PYTHON_PACKAGE_INSTALLER )$(MXENV_UV_GLOBAL ) ","uvfalse")
270- @echo "Install uv"
300+
301+ # Install uv locally if needed
302+ ifeq ("$(USE_LOCAL_UV ) ","true")
303+ @echo "Install uv in virtual environment"
271304 @$(MXENV_PYTHON) -m pip install uv
272305endif
306+
307+ # Install/upgrade core packages
273308 @$(PYTHON_PACKAGE_COMMAND) install -U pip setuptools wheel
274309 @echo "Install/Update MXStack Python packages"
275310 @$(PYTHON_PACKAGE_COMMAND) install -U $(MXDEV) $(MXMAKE)
0 commit comments