From 10c886d414941159737e8b53b9a97c62b8a28f0e Mon Sep 17 00:00:00 2001
From: Sorin Sbarnea <ssbarnea@redhat.com>
Date: Tue, 21 Jan 2025 12:45:50 +0000
Subject: [PATCH] Ensure uv uses same constraints as pip

---
 .config/constraints.txt      | 227 ++++++++++++++++++-----------------
 .config/requirements-test.in |   4 +-
 .pre-commit-config.yaml      |  44 ++++---
 pyproject.toml               |  13 ++
 tox.ini                      |   8 +-
 5 files changed, 169 insertions(+), 127 deletions(-)

diff --git a/.config/constraints.txt b/.config/constraints.txt
index 7462520d..34696e3a 100644
--- a/.config/constraints.txt
+++ b/.config/constraints.txt
@@ -1,112 +1,119 @@
-#
-# This file is autogenerated by pip-compile with Python 3.10
-# by the following command:
-#
-#    pip-compile --all-extras --no-annotate --output-file=.config/constraints.txt --strip-extras .config/requirements.in pyproject.toml
-#
-astroid==3.3.8
-babel==2.16.0
-beautifulsoup4==4.12.3
-black==24.10.0
-build==1.2.2.post1
-cachetools==5.5.0
-cairocffi==1.7.1
-cairosvg==2.7.1
-certifi==2024.12.14
-cffi==1.17.1
-cfgv==3.4.0
-chardet==5.2.0
-charset-normalizer==3.4.1
-click==8.1.8
-colorama==0.4.6
-coverage==7.6.10
-csscompressor==0.9.5
-cssselect2==0.7.0
-defusedxml==0.7.1
-dill==0.3.9
-distlib==0.3.9
-dnspython==2.7.0
-docstring-parser-fork==0.0.12
-exceptiongroup==1.2.2
-execnet==2.1.1
-filelock==3.16.1
-flake8==7.1.1
-ghp-import==2.1.0
-griffe==1.5.5
-htmlmin2==0.1.13
-identify==2.6.5
-idna==3.10
-iniconfig==2.0.0
-isort==5.13.2
-jinja2==3.1.5
-jsmin==3.0.1
-linkchecker==10.5.0
-markdown==3.7
-markdown-exec==1.10.0
-markdown-include==0.8.1
-markupsafe==3.0.2
-mccabe==0.7.0
-mergedeep==1.3.4
-mkdocs==1.6.1
-mkdocs-ansible==24.12.0
-mkdocs-autorefs==1.3.0
-mkdocs-gen-files==0.5.0
-mkdocs-get-deps==0.2.0
-mkdocs-htmlproofer-plugin==1.3.0
-mkdocs-macros-plugin==1.3.7
-mkdocs-material==9.5.50
-mkdocs-material-extensions==1.3.1
-mkdocs-minify-plugin==0.8.0
-mkdocs-monorepo-plugin==1.1.0
-mkdocstrings==0.27.0
-mkdocstrings-python==1.13.0
-mypy==1.14.1
-mypy-extensions==1.0.0
-nodeenv==1.9.1
-packaging==24.2
-paginate==0.5.7
-pathspec==0.12.1
-pillow==11.1.0
-pip-tools==7.4.1
-pipdeptree==2.24.0
-platformdirs==4.3.6
-pluggy==1.5.0
-pre-commit==4.0.1
-pycodestyle==2.12.1
-pycparser==2.22
-pydoclint==0.6.0
-pyflakes==3.2.0
-pygments==2.19.1
-pylint==3.3.3
-pymdown-extensions==10.14
-pyproject-api==1.8.0
-pyproject-hooks==1.2.0
-pytest==8.3.4
-pytest-xdist==3.6.1
-python-dateutil==2.9.0.post0
-python-slugify==8.0.4
-pyyaml==6.0.2
-pyyaml-env-tag==0.1
-regex==2024.11.6
-requests==2.32.3
-ruff==0.9.2
-six==1.17.0
-soupsieve==2.6
-termcolor==2.5.0
-text-unidecode==1.3
-tinycss2==1.4.0
-toml-sort==0.24.2
-tomli==2.2.1
-tomlkit==0.13.2
-tox==4.23.2
-types-pyyaml==6.0.12.20241230
-typing-extensions==4.12.2
-urllib3==2.3.0
-virtualenv==20.29.1
-watchdog==6.0.0
-webencodings==0.5.1
-wheel==0.45.1
+# This file was autogenerated by uv via the following command:
+#    tox run deps
+ansible-compat==24.10.0   # via ansible-lint
+ansible-lint==25.1.0      # via ansible-creator (pyproject.toml)
+argcomplete==3.5.3        # via ansible-creator (pyproject.toml)
+astroid==3.3.8            # via pylint
+attrs==24.3.0             # via jsonschema, referencing
+babel==2.16.0             # via mkdocs-material
+beautifulsoup4==4.12.3    # via linkchecker, mkdocs-htmlproofer-plugin
+black==24.10.0            # via ansible-lint, ansible-creator (pyproject.toml)
+bracex==2.5.post1         # via wcmatch
+cachetools==5.5.0         # via tox
+cairocffi==1.7.1          # via cairosvg
+cairosvg==2.7.1           # via mkdocs-ansible
+certifi==2024.12.14       # via requests
+cffi==1.17.1              # via cairocffi, cryptography
+cfgv==3.4.0               # via pre-commit
+chardet==5.2.0            # via tox
+charset-normalizer==3.4.1  # via requests
+click==8.1.8              # via black, mkdocs, mkdocstrings, pydoclint
+colorama==0.4.6           # via griffe, mkdocs-material, tox
+coverage==7.6.10          # via ansible-creator (pyproject.toml)
+cryptography==44.0.0      # via ansible-core
+csscompressor==0.9.5      # via mkdocs-minify-plugin
+cssselect2==0.7.0         # via cairosvg
+defusedxml==0.7.1         # via cairosvg
+dill==0.3.9               # via pylint
+distlib==0.3.9            # via virtualenv
+dnspython==2.7.0          # via linkchecker
+docstring-parser-fork==0.0.12  # via pydoclint
+execnet==2.1.1            # via pytest-xdist
+filelock==3.16.1          # via ansible-lint, tox, virtualenv
+ghp-import==2.1.0         # via mkdocs
+griffe==1.5.5             # via mkdocstrings-python
+hjson==3.1.0              # via mkdocs-macros-plugin, super-collections
+htmlmin2==0.1.13          # via mkdocs-minify-plugin
+identify==2.6.5           # via pre-commit
+idna==3.10                # via requests
+importlib-metadata==8.6.1  # via ansible-lint
+iniconfig==2.0.0          # via pytest
+isort==5.13.2             # via pylint
+jinja2==3.1.5             # via ansible-core, mkdocs, mkdocs-macros-plugin, mkdocs-material, mkdocstrings, ansible-creator (pyproject.toml)
+jsmin==3.0.1              # via mkdocs-minify-plugin
+jsonschema==4.23.0        # via ansible-compat, ansible-lint
+jsonschema-specifications==2024.10.1  # via jsonschema
+linkchecker==10.5.0       # via mkdocs-ansible
+markdown==3.7             # via markdown-include, mkdocs, mkdocs-autorefs, mkdocs-htmlproofer-plugin, mkdocs-material, mkdocstrings, pymdown-extensions
+markdown-exec==1.10.0     # via mkdocs-ansible
+markdown-include==0.8.1   # via mkdocs-ansible
+markupsafe==3.0.2         # via jinja2, mkdocs, mkdocs-autorefs, mkdocstrings
+mccabe==0.7.0             # via pylint
+mergedeep==1.3.4          # via mkdocs, mkdocs-get-deps
+mkdocs==1.6.1             # via mkdocs-ansible, mkdocs-autorefs, mkdocs-gen-files, mkdocs-htmlproofer-plugin, mkdocs-macros-plugin, mkdocs-material, mkdocs-minify-plugin, mkdocs-monorepo-plugin, mkdocstrings
+mkdocs-ansible==24.12.0   # via ansible-creator (pyproject.toml)
+mkdocs-autorefs==1.3.0    # via mkdocstrings, mkdocstrings-python
+mkdocs-gen-files==0.5.0   # via mkdocs-ansible
+mkdocs-get-deps==0.2.0    # via mkdocs
+mkdocs-htmlproofer-plugin==1.3.0  # via mkdocs-ansible
+mkdocs-macros-plugin==1.3.7  # via mkdocs-ansible
+mkdocs-material==9.5.50   # via mkdocs-ansible
+mkdocs-material-extensions==1.3.1  # via mkdocs-ansible, mkdocs-material
+mkdocs-minify-plugin==0.8.0  # via mkdocs-ansible
+mkdocs-monorepo-plugin==1.1.0  # via mkdocs-ansible
+mkdocstrings==0.27.0      # via mkdocs-ansible, mkdocstrings-python
+mkdocstrings-python==1.13.0  # via mkdocs-ansible
+mypy==1.14.1              # via ansible-creator (pyproject.toml)
+mypy-extensions==1.0.0    # via black, mypy
+nodeenv==1.9.1            # via pre-commit
+packaging==24.2           # via ansible-compat, ansible-core, ansible-lint, black, mkdocs, mkdocs-macros-plugin, pipdeptree, pyproject-api, pytest, tox
+paginate==0.5.7           # via mkdocs-material
+pathspec==0.12.1          # via ansible-lint, black, mkdocs, mkdocs-macros-plugin, yamllint
+pillow==11.1.0            # via cairosvg, mkdocs-ansible
+pipdeptree==2.24.0        # via ansible-creator (pyproject.toml)
+platformdirs==4.3.6       # via black, mkdocs-get-deps, mkdocstrings, pylint, tox, virtualenv
+pluggy==1.5.0             # via pytest, tox
+pre-commit==4.1.0         # via ansible-creator (pyproject.toml)
+pycparser==2.22           # via cffi
+pydoclint==0.6.0          # via ansible-creator (pyproject.toml)
+pygments==2.19.1          # via mkdocs-material
+pylint==3.3.3             # via ansible-creator (pyproject.toml)
+pymdown-extensions==10.14  # via markdown-exec, mkdocs-ansible, mkdocs-material, mkdocstrings
+pyproject-api==1.8.0      # via tox
+pytest==8.3.4             # via pytest-xdist, ansible-creator (pyproject.toml)
+pytest-xdist==3.6.1       # via ansible-creator (pyproject.toml)
+python-dateutil==2.9.0.post0  # via ghp-import, mkdocs-macros-plugin
+python-slugify==8.0.4     # via mkdocs-monorepo-plugin
+pyyaml==6.0.2             # via ansible-compat, ansible-core, ansible-lint, mkdocs, mkdocs-get-deps, mkdocs-macros-plugin, pre-commit, pymdown-extensions, pyyaml-env-tag, yamllint, ansible-creator (pyproject.toml)
+pyyaml-env-tag==0.1       # via mkdocs
+referencing==0.36.1       # via jsonschema, jsonschema-specifications
+regex==2024.11.6          # via mkdocs-material
+requests==2.32.3          # via linkchecker, mkdocs-htmlproofer-plugin, mkdocs-material
+rpds-py==0.22.3           # via jsonschema, referencing
+ruamel-yaml==0.18.10      # via ansible-lint
+ruff==0.9.2               # via ansible-creator (pyproject.toml)
+six==1.17.0               # via python-dateutil
+soupsieve==2.6            # via beautifulsoup4
+subprocess-tee==0.4.2     # via ansible-compat, ansible-lint
+super-collections==0.5.3  # via mkdocs-macros-plugin
+termcolor==2.5.0          # via mkdocs-macros-plugin
+text-unidecode==1.3       # via python-slugify
+tinycss2==1.4.0           # via cairosvg, cssselect2
+toml-sort==0.24.2         # via ansible-creator (pyproject.toml)
+tomlkit==0.13.2           # via pylint, toml-sort
+tox==4.23.2               # via ansible-creator (pyproject.toml)
+types-pyyaml==6.0.12.20241230  # via ansible-creator (pyproject.toml)
+urllib3==2.3.0            # via requests
+virtualenv==20.29.1       # via pre-commit, tox
+watchdog==6.0.0           # via mkdocs
+wcmatch==10.0             # via ansible-lint
+webencodings==0.5.1       # via cssselect2, tinycss2
+yamllint==1.35.1          # via ansible-lint
+zipp==3.21.0              # via importlib-metadata
 
-# The following packages are considered to be unsafe in a requirements file:
+# The following packages were excluded from the output:
+# ansible-core
 # pip
-# setuptools
+# resolvelib
+# typing-extensions
+# uv
diff --git a/.config/requirements-test.in b/.config/requirements-test.in
index 188c2bb8..18b98ec6 100644
--- a/.config/requirements-test.in
+++ b/.config/requirements-test.in
@@ -1,9 +1,8 @@
-argcomplete
 ansible-lint
+argcomplete
 black
 coverage[toml]
 mypy
-pip-tools
 pre-commit
 pydoclint
 pylint
@@ -13,3 +12,4 @@ ruff
 toml-sort
 tox
 types-PyYAML
+uv
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index fbce4f9f..84c50e46 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,6 +4,11 @@ ci:
   autoupdate_commit_msg: "chore: pre-commit autoupdate"
   autoupdate_schedule: monthly
   autofix_commit_msg: "chore: auto fixes from pre-commit.com hooks"
+  skip:
+    # https://github.com/pre-commit-ci/issues/issues/55
+    - ccv
+    - pip-compile
+    # No docker on pre-commit.ci
 
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
@@ -106,19 +111,30 @@ repos:
         # Override default pre-commit '--ignore-missing-imports'
         args: [--strict]
 
-  - repo: https://github.com/jazzband/pip-tools
-    rev: 7.4.1
+  # Keep last due to being considerably slower than the others:
+  - repo: local
     hooks:
+      - id: pip-compile-upgrade
+        # To run it execute: `pre-commit run pip-compile-upgrade --hook-stage manual`
+        name: Upgrade constraints files and requirements
+        files: ^(pyproject\.toml|requirements\.txt)$
+        language: python
+        entry: python3 -m uv pip compile -q --all-extras --output-file=.config/constraints.txt pyproject.toml --upgrade
+        pass_filenames: false
+        stages:
+          - manual
+        additional_dependencies:
+          - uv>=0.4.3
       - id: pip-compile
-        name: deps
-        alias: deps
-        stages: [manual]
-        entry: >-
-          pip-compile .config/requirements.in
-          --upgrade
-          --all-extras
-          --no-annotate
-          --strip-extras
-          --output-file=.config/constraints.txt pyproject.toml
-        files: ^.config\/.*requirements.*$
-        language_version: "3.10" # minimal we support officially
+        name: Check constraints files and requirements
+        files: ^(pyproject\.toml|requirements\.txt)$
+        language: python
+        entry: python3 -m uv pip compile -q --all-extras --output-file=.config/constraints.txt pyproject.toml
+        pass_filenames: false
+        additional_dependencies:
+          - uv>=0.4.3
+  - repo: https://github.com/mashi/codecov-validator
+    rev: "1.0.1"
+    hooks:
+      - id: ccv
+        name: codecov
diff --git a/pyproject.toml b/pyproject.toml
index d1c67fc5..d818098c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -383,9 +383,22 @@ git_describe_command = [
   "v*.*"
 ]
 local_scheme = "no-local-version"
+tag_regex = "^(?P<prefix>v)?(?P<version>\\d+[^\\+]*)(?P<suffix>.*)?$"
 write_to = "src/ansible_creator/_version.py"
 
 [tool.tomlsort]
 in_place = true
 sort_inline_tables = true
 sort_table_keys = true
+
+[tool.uv.pip]
+annotation-style = "line"
+custom-compile-command = "tox run deps"
+no-emit-package = [
+  "ansible-core",
+  "pip",
+  "resolvelib",
+  "ruamel-yaml-clib",
+  "typing_extensions",
+  "uv"
+]
diff --git a/tox.ini b/tox.ini
index 2c258f0b..6b874e22 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,7 @@
 [tox]
 requires =
-    tox>=4.11.3
+    tox>=4.23.2
+    tox-uv>=1.19
 env_list =
     py
     deps
@@ -27,6 +28,7 @@ pass_env =
     USER
 set_env =
     !milestone: PIP_CONSTRAINT = {toxinidir}/.config/constraints.txt
+    !milestone: UV_CONSTRAINT = {toxinidir}/.config/constraints.txt
     COVERAGE_COMBINED = {envdir}/.coverage
     COVERAGE_FILE = {env:COVERAGE_FILE:{envdir}/.coverage.{envname}}
     COVERAGE_PROCESS_START = {toxinidir}/pyproject.toml
@@ -57,6 +59,7 @@ deps =
 extras =
 set_env =
     PIP_CONSTRAINT = /dev/null
+    UV_CONSTRAINT = /dev/null
 commands_pre =
 commands =
     -pre-commit run --all-files --show-diff-on-failure --hook-stage manual deps
@@ -81,8 +84,10 @@ description = Enforce quality standards under {basepython}
 skip_install = true
 deps =
     pre-commit
+    pre-commit-uv>=4.1.4
 set_env =
     PIP_CONSTRAINT = /dev/null
+    UV_CONSTRAINT = /dev/null
 commands =
     pre-commit run --show-diff-on-failure --all-files
 
@@ -94,6 +99,7 @@ deps =
 set_env =
     {[testenv]set_env}
     PIP_CONSTRAINT = /dev/null
+    UV_CONSTRAINT = /dev/null
 
 [testenv:pkg]
 description =