@@ -267,48 +267,121 @@ endif
267267 fi
268268
269269# Helpers -------------------------------------------------
270- # Replace the existing .venv target with the following
271- $( REPO_BASE_DIR) /.venv/bin/activate:
272- # creating virtual environment with tooling (jinja, etc)
273- python3 -m venv $( REPO_BASE_DIR) /.venv
274- $( REPO_BASE_DIR) /.venv/bin/pip3 install --upgrade pip wheel setuptools
275- $( REPO_BASE_DIR) /.venv/bin/pip3 install jinja2 j2cli[yaml] typer
276- @echo " To activate the venv, execute 'source $( REPO_BASE_DIR) /.venv/bin/activate'"
277- .PHONY: .venv
278- .venv: $( REPO_BASE_DIR) /.venv/bin/activate # # Creates a python virtual environment with dev tools (pip, pylint, ...)
279- .PHONY: venv
280- venv: $( REPO_BASE_DIR) /.venv/bin/activate # # Creates a python virtual environment with dev tools (pip, pylint, ...)
270+
271+ # Check that given variables are set and all have non-empty values,
272+ # die with an error otherwise.
273+ #
274+ # Params:
275+ # 1. Variable name(s) to test.
276+ # 2. (optional) Error message to print.
277+ guard-%:
278+ @ if [ " ${${* } } " = " " ]; then \
279+ echo " Argument '$* ' is missing. TIP: make <rule> $* =<value>" ; \
280+ exit 1; \
281+ fi
282+
283+ # Explicitly define optional arguments
284+ # do nothing target https://stackoverflow.com/a/46648773/12124525
285+ guard-optional-%:
286+ @:
287+
288+ # Gracefully use defaults and potentially overwrite them, via https://stackoverflow.com/a/49804748
289+ %: %-default
290+ @ true
291+
292+ #
293+ # Automatic VENV management
294+ #
295+ # Inspired from https://potyarkin.com/posts/2019/manage-python-virtual-environment-from-your-makefile/
296+
297+ VENV_DIR=$( REPO_BASE_DIR) /.venv
298+ VENV_BIN=$( VENV_DIR) /bin
299+
300+ # NOTE: this is because the gitlab CI does not allow to source cargon/env on the fly
301+ UV := $$ HOME/.local/bin/uv
302+
303+ $( UV) :
304+ @if [ ! -f $@ ]; then \
305+ echo " Installing uv..." ; \
306+ curl -LsSf https://astral.sh/uv/install.sh | sh; \
307+ fi
308+
309+ UVX := $$ HOME/.local/bin/uvx
310+ $( UVX) : $( UV)
311+
312+ # Use venv for any target that requires virtual environment to be created and configured
313+ venv: $( VENV_DIR) # # configure repo's virtual environment
314+ $( VENV_BIN) : $( VENV_DIR)
315+
316+ $( VENV_DIR) : $( UV)
317+ @if [ ! -d $@ ]; then \
318+ $< venv $@ ; \
319+ VIRTUAL_ENV=$@ $< pip install --upgrade pip wheel setuptools; \
320+ VIRTUAL_ENV=$@ $< pip install jinja2 j2cli[yaml] typer; \
321+ $( VENV_BIN) /pre-commit install > /dev/null 2>&1 ; \
322+ $( UV) self update || true ; \
323+ fi
324+
325+ # Ensure tool is available or fail otherwise
326+ #
327+ # USAGE:
328+ #
329+ # codestyle: $(VENV_BIN)/pyflakes
330+ # $(VENV_BIN)/pyflakes .
331+ #
332+ $( VENV_BIN) /%: $( VENV_DIR)
333+ @if [ ! -f " $@ " ]; then \
334+ echo " ERROR: '$* ' is not found in $( VENV_BIN) " ; \
335+ exit 1; \
336+ fi
337+
338+ .PHONY: show-venv
339+ show-venv: venv # # show venv info
340+ @$( VENV_BIN) /python -c " import sys; print('Python ' + sys.version.replace('\n',''))"
341+ @$( UV) --version
342+ @echo venv: $( VENV_DIR)
343+
344+ .PHONY: install
345+ install: guard-optional-REQUIREMENTS_FILE venv # # install requirements.txt dependencies
346+ @if [ -z " $( REQUIREMENTS_FILE) " ]; then \
347+ REQUIREMENTS_FILE=./requirements.txt; \
348+ else \
349+ REQUIREMENTS_FILE=$( REQUIREMENTS_FILE) ; \
350+ fi ; \
351+ VIRTUAL_ENV=$( VENV_DIR) $( UV) pip install --requirement $$ REQUIREMENTS_FILE
281352
282353# https://github.com/kolypto/j2cli?tab=readme-ov-file#customization
283354ifeq ($( shell test -f j2cli_customization.py && echo -n yes) ,yes)
284355
285356define jinja
286- $( REPO_BASE_DIR ) /.venv/bin /j2 --format=env $( 1) $( 2) -o $( 3) \
357+ ${VENV_BIN} /j2 --format=env $( 1) $( 2) -o $( 3) \
287358 --filters $( REPO_BASE_DIR) /scripts/j2cli_global_filters.py \
288359 --customize j2cli_customization.py
289360endef
290361
291362else
292363
293364define jinja
294- $( REPO_BASE_DIR ) /.venv/bin /j2 --format=env $( 1) $( 2) -o $( 3) \
365+ ${VENV_BIN} /j2 --format=env $( 1) $( 2) -o $( 3) \
295366 --filters $( REPO_BASE_DIR) /scripts/j2cli_global_filters.py
296367endef
297368
298369endif
299370
300- # Check that given variables are set and all have non-empty values,
301- # die with an error otherwise.
302371#
303- # Params:
304- # 1. Variable name(s) to test.
305- # 2. (optional) Error message to print.
306- guard-%:
307- @ if [ " ${${* } } " = " " ]; then \
308- echo " Argument '$* ' is missing. TIP: make <rule> $* =<value>" ; \
309- exit 1; \
310- fi
372+ # wait-fot-it functionality
373+ #
311374
312- # Gracefully use defaults and potentially overwrite them, via https://stackoverflow.com/a/49804748
313- %: %-default
314- @ true
375+ WAIT_FOR_IT := $( REPO_BASE_DIR) /scripts/wait4x
376+
377+ alias: $( WAIT_FOR_IT)
378+
379+ # https://github.com/wait4x/wait4x
380+ $( WAIT_FOR_IT) : # # installs wait4x utility for WAIT_FOR_IT functionality
381+ # installing wait4x
382+ @mkdir --parents /tmp/wait4x
383+ @cd /tmp/wait4x && curl --silent --location --remote-name https://github.com/wait4x/wait4x/releases/download/v3.5.0/wait4x-linux-amd64.tar.gz
384+ @tar -xf /tmp/wait4x/wait4x-linux-amd64.tar.gz -C /tmp/wait4x
385+ @mv /tmp/wait4x/wait4x $@
386+ @rm -rf /tmp/wait4x
387+ @$@ version
0 commit comments