<commit_before># Common development tasks.

# Cross-platform adjustments.
SYS := $(shell uname 2> /dev/null)
ifeq ($(SYS),Linux)
GREP_EXE := grep
DATE_EXE := date
else ifeq ($(SYS),Darwin)
GREP_EXE := ggrep
DATE_EXE := gdate
else
$(error Unsupported development platform)
endif

# Application name.
APP_NAME := crimson

# Supported Python versions; latest listed first.
PYTHON_VERSIONS := 3.10.4 3.9.12 3.8.13 3.7.13

# Primary Python version used for virtualenv.
PYTHON_VERSION := $(firstword $(PYTHON_VERSIONS))

# Virtualenv name.
VENV_NAME := $(APP_NAME)-dev

# Dependencies installed via pip.
PIP_DEPS := poetry poetry-dynamic-versioning pre-commit tox

# Various build info.
GIT_TAG    := $(shell git describe --tags --always --dirty 2> /dev/null || echo "untagged")
GIT_COMMIT := $(shell git rev-parse --quiet --verify HEAD || echo "?")
GIT_DIRTY  := $(shell test -n "$(shell git status --porcelain)" && echo "-dirty" || true)
BUILD_TIME := $(shell $(DATE_EXE) -u '+%Y-%m-%dT%H:%M:%SZ')
IS_RELEASE := $(shell ((echo "${GIT_TAG}" | $(GREP_EXE) -qE "^v?[0-9]+\.[0-9]+\.[0-9]+$$") && echo '1') || true)

IMG_NAME   := ghcr.io/bow/$(APP_NAME)
ifeq ($(IS_RELEASE),1)
IMG_TAG    := $(GIT_TAG)
else
IMG_TAG    := latest
endif

WHEEL_DEPS_DIR ?= $(CURDIR)/wheels/deps

## Rules ##

all: help


.PHONY: build
build:  ## Build wheel and source dist.
	poetry build
	twine check dist/*

.PHONY: build-deps
build-deps: | $(WHEEL_DEPS_DIR)  ## Build wheels of dependencies.
	poetry export --without-hashes -f requirements.txt -o /dev/stdout | \
		pip wheel -r /dev/stdin --wheel-dir=$(WHEEL_DEPS_DIR)

$(WHEEL_DEPS_DIR):
	mkdir -p $@


.PHONY: clean
clean:  ## Remove build artifacts, including built Docker images.
	rm -rf build/ dist/ && (docker rmi $(IMG_NAME) 2> /dev/null || true)


.PHONY: clean-venv
clean-venv:  ## Remove the created pyenv virtualenv.
	pyenv uninstall -f $(VENV_NAME) && rm -f .python-version


.PHONY: help
help:  ## Show this help.
	$(eval PADLEN=$(shell $(GREP_EXE) -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
		| cut -d':' -f1 \
		| awk '{cur = length($$0); lengths[cur] = lengths[cur] $$0 ORS; max=(cur > max ? cur : max)} END {printf "%s", max}' \
		|| (true && echo 0)))
	@($(GREP_EXE) --version > /dev/null 2>&1 || (>&2 "error: GNU grep not installed"; exit 1)) \
		&& printf "\033[36m◉ %s dev console\033[0m\n" "$(APP_NAME)" >&2 \
		&& $(GREP_EXE) -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
			| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m» \033[33m%*-s\033[0m \033[36m· \033[0m%s\n", $(PADLEN), $$1, $$2}' \
			| sort


.PHONY: img
img:  ## Build and tag the Docker container.
	docker build --build-arg REVISION=$(GIT_COMMIT)$(GIT_DIRTY) --build-arg BUILD_TIME=$(BUILD_TIME) --tag $(IMG_NAME):$(IMG_TAG) .


.PHONY: install-dev
install-dev:  ## Configure a local development setup.
	@if command -v pyenv virtualenv > /dev/null 2>&1; then \
		printf "Configuring a local dev environment using pyenv ...\n" >&2 \
			&& echo $(PYTHON_VERSIONS) | tr ' ' '\n' | xargs -P 4 -I '{}' pyenv install -s '{}' \
			&& printf "%s\n" "Setting up virtualenv '$(VENV_NAME)' in Python $(PYTHON_VERSION)..." 1>&2 \<commit_msg>chore: Use virtualenv-delete for clean-venv rule<commit_after># Common development tasks.

# Cross-platform adjustments.
SYS := $(shell uname 2> /dev/null)
ifeq ($(SYS),Linux)
GREP_EXE := grep
DATE_EXE := date
else ifeq ($(SYS),Darwin)
GREP_EXE := ggrep
DATE_EXE := gdate
else
$(error Unsupported development platform)
endif

# Application name.
APP_NAME := crimson

# Supported Python versions; latest listed first.
PYTHON_VERSIONS := 3.10.4 3.9.12 3.8.13 3.7.13

# Primary Python version used for virtualenv.
PYTHON_VERSION := $(firstword $(PYTHON_VERSIONS))

# Virtualenv name.
VENV_NAME := $(APP_NAME)-dev

# Dependencies installed via pip.
PIP_DEPS := poetry poetry-dynamic-versioning pre-commit tox

# Various build info.
GIT_TAG    := $(shell git describe --tags --always --dirty 2> /dev/null || echo "untagged")
GIT_COMMIT := $(shell git rev-parse --quiet --verify HEAD || echo "?")
GIT_DIRTY  := $(shell test -n "$(shell git status --porcelain)" && echo "-dirty" || true)
BUILD_TIME := $(shell $(DATE_EXE) -u '+%Y-%m-%dT%H:%M:%SZ')
IS_RELEASE := $(shell ((echo "${GIT_TAG}" | $(GREP_EXE) -qE "^v?[0-9]+\.[0-9]+\.[0-9]+$$") && echo '1') || true)

IMG_NAME   := ghcr.io/bow/$(APP_NAME)
ifeq ($(IS_RELEASE),1)
IMG_TAG    := $(GIT_TAG)
else
IMG_TAG    := latest
endif

WHEEL_DEPS_DIR ?= $(CURDIR)/wheels/deps

## Rules ##

all: help


.PHONY: build
build:  ## Build wheel and source dist.
	poetry build
	twine check dist/*

.PHONY: build-deps
build-deps: | $(WHEEL_DEPS_DIR)  ## Build wheels of dependencies.
	poetry export --without-hashes -f requirements.txt -o /dev/stdout | \
		pip wheel -r /dev/stdin --wheel-dir=$(WHEEL_DEPS_DIR)

$(WHEEL_DEPS_DIR):
	mkdir -p $@


.PHONY: clean
clean:  ## Remove build artifacts, including built Docker images.
	rm -rf build/ dist/ && (docker rmi $(IMG_NAME) 2> /dev/null || true)


.PHONY: clean-venv
clean-venv:  ## Remove the created pyenv virtualenv.
	pyenv virtualenv-delete -f $(VENV_NAME) && rm -f .python-version


.PHONY: help
help:  ## Show this help.
	$(eval PADLEN=$(shell $(GREP_EXE) -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
		| cut -d':' -f1 \
		| awk '{cur = length($$0); lengths[cur] = lengths[cur] $$0 ORS; max=(cur > max ? cur : max)} END {printf "%s", max}' \
		|| (true && echo 0)))
	@($(GREP_EXE) --version > /dev/null 2>&1 || (>&2 "error: GNU grep not installed"; exit 1)) \
		&& printf "\033[36m◉ %s dev console\033[0m\n" "$(APP_NAME)" >&2 \
		&& $(GREP_EXE) -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
			| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m» \033[33m%*-s\033[0m \033[36m· \033[0m%s\n", $(PADLEN), $$1, $$2}' \
			| sort


.PHONY: img
img:  ## Build and tag the Docker container.
	docker build --build-arg REVISION=$(GIT_COMMIT)$(GIT_DIRTY) --build-arg BUILD_TIME=$(BUILD_TIME) --tag $(IMG_NAME):$(IMG_TAG) .


.PHONY: install-dev
install-dev:  ## Configure a local development setup.
	@if command -v pyenv virtualenv > /dev/null 2>&1; then \
		printf "Configuring a local dev environment using pyenv ...\n" >&2 \
			&& echo $(PYTHON_VERSIONS) | tr ' ' '\n' | xargs -P 4 -I '{}' pyenv install -s '{}' \
			&& printf "%s\n" "Setting up virtualenv '$(VENV_NAME)' in Python $(PYTHON_VERSION)..." 1>&2 \
{'fraction_non_alphanumeric': 0.20066256507335542, 'fraction_numerical': 0.023978545511910396, 'mean_word_length': 3.706755753526355, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1280166', 'n_tokens_mistral': 2678, 'n_tokens_neox': 2472, 'n_words': 673}