diff --git a/.github/workflows/python-code-style.yml b/.github/workflows/python-code-style.yml index 3035163..a8efd85 100644 --- a/.github/workflows/python-code-style.yml +++ b/.github/workflows/python-code-style.yml @@ -21,12 +21,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.13" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry poetry-plugin-export - poetry config virtualenvs.create false - poetry install --no-root --with dev + make dev-dependencies - name: Check code style with black run: | make format diff --git a/.github/workflows/python-lint.yml b/.github/workflows/python-lint.yml index b8cc537..1770883 100644 --- a/.github/workflows/python-lint.yml +++ b/.github/workflows/python-lint.yml @@ -21,10 +21,10 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.13" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry tox poetry-plugin-export - make poetry-export + make dev-dependencies - name: Lint with ruff run: make lint diff --git a/.github/workflows/python-quality.yml b/.github/workflows/python-quality.yml index 9af50a2..f14222f 100644 --- a/.github/workflows/python-quality.yml +++ b/.github/workflows/python-quality.yml @@ -21,12 +21,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.13" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry poetry-plugin-export - poetry config virtualenvs.create false - poetry install --no-root --with dev + make dev-dependencies - name: Test & publish code coverage uses: paambaati/codeclimate-action@v9.0.0 env: diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 3b2350b..f91c663 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -28,12 +28,11 @@ jobs: uses: actions/setup-python@v5 with: python-version: "${{ matrix.version }}" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry poetry-plugin-export - poetry config virtualenvs.create false - poetry install --no-root --with dev + make dev-dependencies - name: Test with pytest id: citest run: | @@ -68,7 +67,7 @@ jobs: --body "$BODY") if [[ $PINNED == true ]]; then gh issue pin "$new_issue_url" - fi + fi fi env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/python-typing.yml b/.github/workflows/python-typing.yml index 12d9c72..4090f5c 100644 --- a/.github/workflows/python-typing.yml +++ b/.github/workflows/python-typing.yml @@ -21,10 +21,10 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.13" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry tox poetry-plugin-export - make poetry-export + make dev-dependencies - name: Check typing run: make typing diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cc771f8..d6ac489 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,14 +22,15 @@ jobs: with: python-version: "3.13" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry poetry-dynamic-versioning poetry-plugin-export + make dev-dependencies - name: Build package run: | - poetry build + uv build - name: Archive the dist folder uses: actions/upload-artifact@v4 diff --git a/.github/workflows/reusable-github-pages.yml b/.github/workflows/reusable-github-pages.yml index 5909f7d..095109a 100644 --- a/.github/workflows/reusable-github-pages.yml +++ b/.github/workflows/reusable-github-pages.yml @@ -44,12 +44,11 @@ jobs: with: python-version: "3.13" + - name: Install uv + uses: astral-sh/setup-uv@v6 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install poetry - poetry config virtualenvs.create false - poetry install --no-root --with dev + make dev-dependencies - name: Configure Git user run: | @@ -62,12 +61,12 @@ jobs: - name: Build and deploy static pages run: | - mike deploy ${{ inputs.site-version }} ${{ inputs.version-alias }} --update-aliases --push --branch ${{ inputs.branch }} + uv run mike deploy ${{ inputs.site-version }} ${{ inputs.version-alias }} --update-aliases --push --branch ${{ inputs.branch }} - name: Set default site version if: ${{ inputs.set-default }} run: | - mike set-default ${{ inputs.site-version }} --push --branch ${{ inputs.branch }} + uv run mike set-default ${{ inputs.site-version }} --push --branch ${{ inputs.branch }} # `mike` is specifically built to be used together with GitHub pages. # To upload the website to another service (i.e. AWS S3) uncomment diff --git a/.gitignore b/.gitignore index 4b14d04..5f825d9 100644 --- a/.gitignore +++ b/.gitignore @@ -282,4 +282,5 @@ dmypy.json # Cython debug symbols cython_debug/ -poetry.lock +uv.lock +version.py diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae11d1a..f518506 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,8 +8,9 @@ Please note that this project is released with a Contributor Code of Conduct. By ## Submitting a pull request +Before running any commands, [install `uv`](https://docs.astral.sh/uv/getting-started/installation/): + 0. Fork and clone the repository -0. Install poetry: `pip install -g poetry` 0. Configure and install the dependencies: `make dev-dependencies` 0. Make sure the tests pass on your machine: `make check` 0. Create a new branch: `git checkout -b my-branch-name` diff --git a/Makefile b/Makefile index 9ee8046..78b78d0 100644 --- a/Makefile +++ b/Makefile @@ -1,49 +1,41 @@ -.PHONY: dev-dependencies update-dependencies test docs fix check typing lint format ci-test ci-coverage poetry-export +.PHONY: dev-dependencies update-dependencies test docs fix check typing lint format ci-test ci-coverage ######################### ###### dev commands ##### ######################### dev-dependencies: - poetry install --with dev --no-root - -update-dependencies: - poetry update --with dev + uv lock --upgrade + uv sync --all-groups --frozen test: - poetry run pytest -n auto --cov + uv run pytest -n auto --cov docs: - poetry run mkdocs serve + uv run mkdocs serve fix: - poetry run ruff check . --fix - poetry run ruff format . - -check: poetry-export - tox - -typing: poetry-export - tox -e typing + uv run ruff format . + uv run ruff check . --fix + uv run ruff format . -lint: poetry-export - tox -e lint +check: + uv run tox -format: poetry-export - tox -e format +typing: + uv run tox -e typing +lint: + uv run tox -e lint -######################### -#### Helper commands #### -######################### -poetry-export: - poetry export -f requirements.txt --output /tmp/requirements.txt --with dev +format: + uv run tox -e format ######################### ###### CI commands ###### ######################### ci-test: - poetry run pytest + uv run pytest ci-coverage: - poetry run pytest --cov --cov-report lcov + uv run pytest --cov --cov-report lcov diff --git a/pyproject.toml b/pyproject.toml index 18abe51..0c602a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,16 @@ -[tool.poetry] +[project] name = "sqlalchemy-bind-manager" -version = "0.0.0" +dynamic = ["version"] description = "A manager to easily handle multiple SQLAlchemy configurations" -license = "MIT" -authors = ["Federico Busetti <729029+febus982@users.noreply.github.com>"] -repository = "https://github.com/febus982/sqlalchemy-bind-manager" -homepage = "https://febus982.github.io/sqlalchemy-bind-manager" +authors = [{ name = "Federico Busetti", email = "729029+febus982@users.noreply.github.com" }] +requires-python = ">=3.9,<3.14" readme = "README.md" -packages = [{include = "sqlalchemy_bind_manager"}] -keywords = ["sqlalchemy", "config", "manager"] +license = "MIT" +keywords = [ + "sqlalchemy", + "config", + "manager", +] classifiers = [ "Development Status :: 4 - Beta", "Framework :: AsyncIO", @@ -28,52 +30,63 @@ classifiers = [ "Topic :: Database", "Topic :: Database :: Front-Ends", "Topic :: Software Development :: Libraries :: Python Modules", - "Typing :: Typed" + "Typing :: Typed", +] +dependencies = [ + "pydantic>=2.1.1,<3", + "SQLAlchemy[asyncio, mypy]~=2.0.0", +] + +[project.urls] +Homepage = "https://febus982.github.io/sqlalchemy-bind-manager" +Repository = "https://github.com/febus982/sqlalchemy-bind-manager" + +[dependency-groups] +dev = [ + "aiosqlite>=0.18.0", + "coverage>=6.5.0", + "mike>=2.0.0", + "mkdocs>=1.4.3", + "mkdocstrings[python]>=0.24.0", + "mkdocs-awesome-pages-plugin>=2.9.2,<3", + "mkdocs-gen-files>=0.5.0", + "mkdocs-material>=9.1.16", + "mypy>=0.990", + "poetry-plugin-export", + "pymdown-extensions>=10.0.1", + "pytest>=8.0.0,<9", + "pytest-asyncio>=0.20.3", + "pytest-cov>=4.0.0", + "pytest-factoryboy>=2.5.0", + "pytest-xdist>=3.0.2", + "ruff>=0.0.263", + "tox>=4.14.1,<5", + "tox-uv>=1.26.0", + "uv-dynamic-versioning>=0.8.2", ] [tool.poetry-dynamic-versioning] enable = true [build-system] -requires = ["poetry-core", "poetry-dynamic-versioning"] -build-backend = "poetry_dynamic_versioning.backend" +requires = ["hatchling", "uv-dynamic-versioning"] +build-backend = "hatchling.build" -[tool.poetry.dependencies] -python = ">=3.9,<3.14" -pydantic = "^2.1.1" -SQLAlchemy = { version = "~2.0.0", extras = ["asyncio", "mypy"] } +[tool.hatch.build.targets.sdist] +include = ["sqlalchemy_bind_manager"] -[tool.poetry.group.dev] -optional = true +[tool.hatch.build.targets.wheel] +include = ["sqlalchemy_bind_manager"] -[tool.poetry.group.dev.dependencies] -aiosqlite = ">=0.18.0" -coverage = ">=6.5.0" -mike = ">=2.0.0" -mkdocs = ">=1.4.3" -mkdocstrings = { version = ">=0.24.0", extras = ["python"] } -mkdocs-awesome-pages-plugin = "^2.9.2" -mkdocs-gen-files = ">=0.5.0" -mkdocs-material = ">=9.1.16" -mypy = ">=0.990" -poetry-plugin-export = "*" -pymdown-extensions = ">=10.0.1" -pytest = "^8.0.0" -pytest-asyncio = ">=0.20.3" -pytest-cov = ">=4.0.0" -pytest-factoryboy = ">=2.5.0" -pytest-xdist = ">=3.0.2" -ruff = ">=0.0.263" -tox = "^4.14.1" +[tool.hatch.version] +source = "uv-dynamic-versioning" + +[tool.hatch.build.hooks.version] +path = "sqlalchemy_bind_manager/version.py" -############################ -### Tools configuration ### -############################ [tool.coverage.run] branch = true source = ["sqlalchemy_bind_manager"] -# It's not necessary to setup concurrency here -# because pytest-cov takes care of that [tool.coverage.report] fail_under = 100 @@ -82,6 +95,9 @@ exclude_also = [ "pass", "\\.\\.\\.", ] +omit = [ + "sqlalchemy_bind_manager/version.py", +] [tool.mypy] files = "sqlalchemy_bind_manager" diff --git a/scripts/docs-version.sh b/scripts/docs-version.sh index a94be72..73f1d4c 100755 --- a/scripts/docs-version.sh +++ b/scripts/docs-version.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash -VERSION=$(poetry version -s) +# uv doesn't yet support reading dynamic version: https://github.com/astral-sh/uv/issues/14137 +#VERSION=$(uv version --short) +VERSION=$(uv run scripts/version_from_git.py) SEMVER=( ${VERSION//./ } ) echo "${SEMVER[0]}.${SEMVER[1]}" diff --git a/scripts/version_from_git.py b/scripts/version_from_git.py new file mode 100644 index 0000000..cd9557f --- /dev/null +++ b/scripts/version_from_git.py @@ -0,0 +1,23 @@ +# Copyright (c) 2025 Federico Busetti <729029+febus982@users.noreply.github.com> +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +from dunamai import Version + +version = Version.from_git().serialize() +print(version) diff --git a/tox.ini b/tox.ini index ff1c841..3e86820 100644 --- a/tox.ini +++ b/tox.ini @@ -11,14 +11,8 @@ env_list = format [testenv] -; The file /tmp/requirements.txt is created automatically if you run tox -; using `make check` command, otherwise manually run -; `poetry export -f requirements.txt --output /tmp/requirements.txt --with dev` -; Poetry is really bad in identifying running virtualenvs, so we can't use -; directly poetry install. This is the best hacky way to install poetry -; requirements inside tox. -deps = - -r/tmp/requirements.txt +runner = uv-venv-runner +dependency_groups = dev commands = pytest