From fa11529652babafb8ea17a07fc9651e350b6c695 Mon Sep 17 00:00:00 2001 From: Mathias Fussenegger Date: Mon, 19 Jan 2026 09:03:40 +0100 Subject: [PATCH] Cleanup dev setup - Removes buildout; test_layer now fetches the crate package itself - Removes setup.py - Removes stale bin/test - Removes stale requirements.txt - Updates DEVELOP.rst - Removes poethepoet. Most python developers are familiar with `ruff`, `mypy` and `pytest`, no need to add an extra DSL on top that obfuscates what's being used. - Removes `bootstrap.sh`. `python -m venv` or `uv venv` are trivial enough and Python developers should be familiar with them. - Removes the `devtools/create_tag.sh` script. It used `python setup.py --version` to get the new version, which since https://github.com/crate/crate-python/pull/757 was broken - running into a chicken and egg problem: Can't read the version from git when about to create a new version tag. Must use `git tag -s ` instead. - Updates the release job. It used `python -m build`, which wasn't specified as dependency anywhere. `hatch` is now used which `uv build` will pickup. --- .github/workflows/docs.yml | 24 +++++-- .github/workflows/nightly.yml | 62 ------------------ .github/workflows/release.yml | 15 ++--- .github/workflows/tests.yml | 60 ++++++++---------- DEVELOP.rst | 94 +++++++-------------------- bin/test | 17 ----- bootstrap.sh | 116 ---------------------------------- buildout.cfg | 20 ------ devtools/create_tag.sh | 73 --------------------- devtools/setup_ci.sh | 23 ------- pyproject.toml | 70 +++++--------------- requirements.txt | 3 - setup.py | 101 ----------------------------- tests/testing/test_layer.py | 56 ++++++++++++++++ versions.cfg | 4 -- 15 files changed, 148 insertions(+), 590 deletions(-) delete mode 100644 .github/workflows/nightly.yml delete mode 100755 bin/test delete mode 100644 bootstrap.sh delete mode 100644 buildout.cfg delete mode 100755 devtools/create_tag.sh delete mode 100755 devtools/setup_ci.sh delete mode 100644 requirements.txt delete mode 100644 setup.py delete mode 100644 versions.cfg diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b81fc8476..69a89e79b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,5 +1,5 @@ +--- name: docs - on: workflow_dispatch: pull_request: ~ @@ -13,6 +13,11 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + checks: write + statuses: write + jobs: documentation: @@ -22,13 +27,20 @@ jobs: steps: - name: Acquire sources uses: actions/checkout@v6 + with: + persist-credentials: false - - name: Set up Python - uses: actions/setup-python@v6 + - name: Set up uv + uses: astral-sh/setup-uv@v7 with: - python-version: '3.12' - cache: 'pip' - cache-dependency-path: 'setup.py' + cache-dependency-glob: | + pyproject.toml + enable-cache: true + activate-environment: true + version: "latest" + + - name: Setup env + run: uv pip install --group docs - name: Build docs run: | diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml deleted file mode 100644 index 9f828b052..000000000 --- a/.github/workflows/nightly.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Nightly - -on: - workflow_dispatch: - schedule: - - cron: '0 2 * * *' - - -jobs: - nightly: - name: "Python: ${{ matrix.python-version }} - CrateDB: ${{ matrix.cratedb-version }} - on ${{ matrix.os }}" - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: ['ubuntu-22.04'] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] - cratedb-version: ['nightly'] - - fail-fast: false - - env: - CRATEDB_VERSION: ${{ matrix.cratedb-version }} - - steps: - - uses: actions/checkout@v6 - - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: ${{ matrix.python-version }} - - - name: Set up uv - uses: astral-sh/setup-uv@v7 - with: - cache-dependency-glob: | - pyproject.toml - cache-suffix: ${{ matrix.python-version }} - enable-cache: true - version: "latest" - - - name: Setup env - run: uv sync - - - name: Invoke tests - run: | - - # Propagate build matrix information. - ./devtools/setup_ci.sh - - # Bootstrap environment. - source bootstrap.sh - - # Report about the test matrix slot. - echo "Invoking tests with CrateDB ${CRATEDB_VERSION}" - - # Run linter. - poe lint - - # Run tests. - poe test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f9000c990..68128f457 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,11 @@ name: release on: push +permissions: + contents: read + checks: write + statuses: write + jobs: pypi: name: Build & publish package to pypi @@ -15,11 +20,8 @@ jobs: if: startsWith(github.event.ref, 'refs/tags') steps: - uses: actions/checkout@v6 - - - name: Set up Python - uses: actions/setup-python@v6 with: - python-version: ${{ matrix.python-version }} + persist-credentials: false - name: Set up uv uses: astral-sh/setup-uv@v7 @@ -31,10 +33,7 @@ jobs: version: "latest" - name: Build package - run: | - uv pip install --system build twine wheel - python -m build - twine check dist/* + run: uv build - name: Publish package to PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 35abf3d74..05f76df7e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,15 +1,24 @@ +--- name: Tests on: push: - branches: [ main ] + branches: + - main pull_request: ~ workflow_dispatch: + schedule: + - cron: '0 2 * * *' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + checks: write + statuses: write + jobs: test: name: "Python: ${{ matrix.python-version }} @@ -18,33 +27,23 @@ jobs: strategy: fail-fast: false matrix: - os: ['ubuntu-22.04'] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] - cratedb-version: ['nightly'] + os: ["ubuntu-24.04"] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] - # To save resources, only verify the most recent Python versions on macOS. + # Save resources - only verify the most recent Python versions on macOS. include: - os: 'macos-latest' - cratedb-version: '5.9.2' - python-version: '3.11' - - os: 'macos-latest' - cratedb-version: '5.9.2' - python-version: '3.12' - - os: 'macos-latest' - cratedb-version: '5.9.2' python-version: '3.13' + - os: 'macos-latest' + python-version: '3.14' env: - CRATEDB_VERSION: ${{ matrix.cratedb-version }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: - uses: actions/checkout@v6 - - - name: Set up Python - uses: actions/setup-python@v6 with: - python-version: ${{ matrix.python-version }} + persist-credentials: false - name: Set up uv uses: astral-sh/setup-uv@v7 @@ -53,30 +52,23 @@ jobs: pyproject.toml cache-suffix: ${{ matrix.python-version }} enable-cache: true + activate-environment: true version: "latest" - name: Setup env - run: uv sync + run: uv pip install --group dev -e . - - name: Invoke tests + - name: Run Linters run: | - - # Propagate build matrix information. - ./devtools/setup_ci.sh + ruff check . + mypy - # Bootstrap environment. - source bootstrap.sh - - # Report about the test matrix slot. - echo "Invoking tests with CrateDB ${CRATEDB_VERSION}" - - # Run linter. - poe lint - - # Run tests. - poe test + - name: Run tests + run: | + coverage run -m pytest + coverage combine + coverage xml - # https://github.com/codecov/codecov-action - name: Upload coverage results to Codecov uses: codecov/codecov-action@v5 env: diff --git a/DEVELOP.rst b/DEVELOP.rst index 449c8a138..6675cad58 100644 --- a/DEVELOP.rst +++ b/DEVELOP.rst @@ -5,95 +5,49 @@ CrateDB Python developer guide Setup ===== -Optionally install Python package and project manager `uv`_, -in order to significantly speed up the package installation:: - - {apt,brew,pip,zypper} install uv - alias pip="uv pip" - -To start things off, bootstrap the sandbox environment:: +Clone the repository:: git clone https://github.com/crate/crate-python cd crate-python - source bootstrap.sh - -This command should automatically install all prerequisites for the development -sandbox and drop you into the virtualenv, ready for invoking further commands. - - -Running tests -============= - -All tests will be invoked using the Python interpreter that was used when -creating the Python virtualenv. The test runner is `zope.testrunner`_. - -Some examples are outlined below. In order to learn about more details, -see, for example, `useful command-line options for zope-testrunner`_. - -Run all tests:: - poe test +Setup a virtualenv and install the package:: -Run specific tests:: + python -m venv .venv + source .venv/bin/activate + python -m pip install --group dev --group docs -e . - # Select modules. - bin/test -t test_cursor - bin/test -t client - bin/test -t testing +Or if using `uv`_:: - # Select doctests. - bin/test -t http.rst + uv venv .venv + source .venv/bin/activate + uv pip install --group dev --group docs -e . -Ignore specific test directories:: - bin/test --ignore_dir=testing - -The ``LayerTest`` test cases have quite some overhead. Omitting them will save -a few cycles (~70 seconds runtime):: - - bin/test -t '!LayerTest' - -Invoke all tests without integration tests (~10 seconds runtime):: - - bin/test --layer '!crate.testing.layer.crate' --test '!LayerTest' - -Yet ~60 test cases, but only ~1 second runtime:: +Running tests +============= - bin/test --layer '!crate.testing.layer.crate' --test '!LayerTest' \ - -t '!test_client_threaded' -t '!test_no_retry_on_read_timeout' \ - -t '!test_wait_for_http' -t '!test_table_clustered_by' +Ensure the virtualenv is active and run tests using `pytest`_:: -To inspect the whole list of test cases, run:: + python -m pytest - bin/test --list-tests -The CI setup on GitHub Actions (GHA) provides a full test matrix covering -relevant Python versions. You can invoke the software tests against a specific -Python interpreter or multiple `Python versions`_ on your workstation using -`uv`_, by supplying the ``--python`` command-line option, or by defining the -`UV_PYTHON`_ environment variable prior to invoking ``source bootstrap.sh``. +See also: -*Note*: Before running the tests, make sure to stop all CrateDB instances which -are listening on the default CrateDB transport port to avoid side effects with -the test layer. +- `How to invoke pytest ` for more information. Formatting and linting code =========================== -To use Ruff for code formatting, according to the standards configured in -``pyproject.toml``, use:: - - poe format - -To lint the code base using Ruff and mypy, use:: +Use `ruff`_ for code formatting and linting:: - poe lint + ruff format --check . + ruff check . -Linting and software testing, all together now:: - poe check +Use ``mypy`` for type checking:: + mypy Renew certificates ================== @@ -120,8 +74,8 @@ In the release branch: - Push to origin/ -- Create a tag by running ``./devtools/create_tag.sh``. This will trigger a - Github action which releases the new version to PyPi. +- Create a tag by running ``git tag -s `` and push it ``git push --tags``. + This will trigger a Github action which releases the new version to PyPi. On branch ``main``: @@ -147,7 +101,7 @@ Writing documentation The docs live under the ``docs`` directory. -The docs are written written with ReStructuredText_ and processed with Sphinx_. +The docs are written with ReStructuredText_ and processed with Sphinx_. Build the docs by running:: @@ -171,4 +125,4 @@ nothing special you need to do to get the live docs to update. .. _uv: https://docs.astral.sh/uv/ .. _UV_PYTHON: https://docs.astral.sh/uv/configuration/environment/#uv_python .. _versions hosted on ReadTheDocs: https://readthedocs.org/projects/crate-python/versions/ -.. _zope.testrunner: https://pypi.org/project/zope.testrunner/ +.. _pytest: https://docs.pytest.org/en/stable/ diff --git a/bin/test b/bin/test deleted file mode 100755 index 749ec64bc..000000000 --- a/bin/test +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -import os -import sys -import zope.testrunner - -join = os.path.join -base = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) -base = os.path.dirname(base) - - -sys.argv[0] = os.path.abspath(sys.argv[0]) - -if __name__ == '__main__': - zope.testrunner.run([ - '-vvvv', '--auto-color', - '--path', join(base, 'tests'), - ]) diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100644 index 93795ad7f..000000000 --- a/bootstrap.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -# -# Bootstrap sandbox environment for crate-python -# -# - Create a Python virtualenv -# - Install all dependency packages and modules -# - Install package in editable mode -# - Drop user into an activated virtualenv -# -# Synopsis:: -# -# source bootstrap.sh -# - - -# Trace all invocations. -# set -x - -# Default variables. -CRATEDB_VERSION=${CRATEDB_VERSION:-5.9.2} - - -function print_header() { - printf '=%.0s' {1..42}; echo - echo "$1" - printf '=%.0s' {1..42}; echo -} - -function ensure_virtualenv() { - # Create a Python virtualenv with current version of Python 3. - # TODO: Maybe take `pyenv` into account. - if [[ ! -d .venv ]]; then - python3 -m venv .venv - fi -} - -function activate_virtualenv() { - # Activate Python virtualenv. - source .venv/bin/activate -} - -function before_setup() { - - # When `wheel` is installed, Python will build `wheel` packages from all - # acquired `sdist` packages and will store them into `~/.cache/pip`, where - # they will be picked up by the caching machinery and will be reused on - # subsequent invocations when run on CI. This makes a *significant* - # difference on total runtime on CI, it is about 2x faster. - # - # Otherwise, there will be admonitions like: - # Using legacy 'setup.py install' for foobar, since package 'wheel' is - # not installed. - # - pip install wheel - - # Install Buildout with designated version, allowing pre-releases. - pip install --pre --requirement=requirements.txt - -} - -function setup_package() { - - # Upgrade `pip` to support `--pre` option. - pip install --upgrade pip - - # Conditionally add `--pre` option, to allow installing prerelease packages. - PIP_OPTIONS="${PIP_OPTIONS:-}" - if [ "${PIP_ALLOW_PRERELEASE}" == "true" ]; then - PIP_OPTIONS+=" --pre" - fi - - # Install package in editable mode. - pip install ${PIP_OPTIONS} --editable='.[test]' - -} - -function run_buildout() { - buildout -N -} - -function finalize() { - - # Some steps before dropping into the activated virtualenv. - echo - echo "Sandbox environment ready" - echo - -} - -function activate_uv() { - if command -v uv; then - function pip() { - uv pip "$@" - } - fi -} -function deactivate_uv() { - unset -f pip -} - -function main() { - activate_uv - ensure_virtualenv - activate_virtualenv - before_setup - setup_package - run_buildout - deactivate_uv - finalize -} - -function lint() { - poe lint -} - -main diff --git a/buildout.cfg b/buildout.cfg deleted file mode 100644 index 55e944624..000000000 --- a/buildout.cfg +++ /dev/null @@ -1,20 +0,0 @@ -[buildout] -extends = versions.cfg -versions = versions -show-picked-versions = true -parts = crate - -[crate:linux] -recipe = hexagonit.recipe.download -url = https://cdn.crate.io/downloads/releases/cratedb/x64_linux/crate-${versions:crate_server}.tar.gz -strip-top-level-dir = true - -[crate:macosx] -recipe = hexagonit.recipe.download -url = https://cdn.crate.io/downloads/releases/cratedb/x64_mac/crate-${versions:crate_server}.tar.gz -strip-top-level-dir = true - -[crate:windows] -recipe = hexagonit.recipe.download -url = https://cdn.crate.io/downloads/releases/cratedb/x64_windows/crate-${versions:crate_server}.zip -strip-top-level-dir = true diff --git a/devtools/create_tag.sh b/devtools/create_tag.sh deleted file mode 100755 index 731b4ebce..000000000 --- a/devtools/create_tag.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash -# -# Licensed to CRATE Technology GmbH ("Crate") under one or more contributor -# license agreements. See the NOTICE file distributed with this work for -# additional information regarding copyright ownership. Crate licenses -# this file to you under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. You may -# obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# However, if you have executed another commercial license agreement -# with Crate these terms will supersede the license and you may use the -# software solely pursuant to the terms of the relevant commercial agreement. - -# check if everything is committed -CLEAN=`git status -s` -if [ ! -z "$CLEAN" ] -then - echo "Working directory not clean. Please commit all changes before tagging" - echo "Aborting." - exit -1 -fi - -echo "Fetching origin..." -git fetch origin > /dev/null - -# get current branch -BRANCH=`git branch | grep "^*" | cut -d " " -f 2` -echo "Current branch is $BRANCH." - -# check if main == origin/main -LOCAL_COMMIT=`git show --format="%H" $BRANCH` -ORIGIN_COMMIT=`git show --format="%H" origin/$BRANCH` - -if [ "$LOCAL_COMMIT" != "$ORIGIN_COMMIT" ] -then - echo "Local $BRANCH is not up to date. " - echo "Aborting." - exit -1 -fi - -# check if tag to create has already been created -WORKING_DIR=`dirname $0` -VERSION=`python setup.py --version` -EXISTS=`git tag | grep $VERSION` - -if [ "$VERSION" == "$EXISTS" ] -then - echo "Revision $VERSION already tagged." - echo "Aborting." - exit -1 -fi - -# check if VERSION is in head of CHANGES.rst -REV_NOTE=`grep "[0-9/]\{10\} $VERSION" CHANGES.rst` -if [ -z "$REV_NOTE" ] -then - echo "No notes for revision $VERSION found in CHANGES.rst" - echo "Aborting." - exit -1 -fi - -echo "Creating tag $VERSION..." -git tag -a "$VERSION" -m "Tag release for revision $VERSION" -git push --tags -echo "Done." diff --git a/devtools/setup_ci.sh b/devtools/setup_ci.sh deleted file mode 100755 index 30e7f2ea1..000000000 --- a/devtools/setup_ci.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -set -e - -function main() { - - # Sanity checks. - [ -z ${CRATEDB_VERSION} ] && { - echo "Environment variable 'CRATEDB_VERSION' needed" - exit 1 - } - - # Replace CrateDB version. - if [ ${CRATEDB_VERSION} = "nightly" ]; then - sed -ir "s!releases/cratedb/x64_linux!releases/nightly!g" buildout.cfg - sed -ir "s/crate_server.*/crate_server = latest/g" versions.cfg - else - sed -ir "s/crate_server.*/crate_server = ${CRATEDB_VERSION}/g" versions.cfg - fi - -} - -main "$@" diff --git a/pyproject.toml b/pyproject.toml index 2b90cd4ac..5cd5c1af4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["hatchling >= 1.26", "versioningit"] +requires = ["hatch", "versioningit"] build-backend = "hatchling.build" [tool.hatch.build.targets.sdist] @@ -42,36 +42,40 @@ classifiers = [ "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", + "Programming Language :: SQL", "Topic :: Database", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator", + "Topic :: System :: Networking", ] dependencies = [ "importlib-metadata; python_version<'3.8'", - "orjson>=3.11.3", + "orjson", "urllib3", "verlib2>=0.3.1", ] [dependency-groups] dev = [ - "certifi>=2025.10.5", - "coverage<8", + "backports.zoneinfo<1; python_version<'3.9'", + "certifi", + "coverage", "mypy<1.20", - "poethepoet<1", "pytest<10", - "pytz>=2025.2", + "pytz", "ruff<0.15", - "setuptools>=80.9.0", "stopit<1.2", ] +docs = [ + "sphinx", + "crate-docs-theme", +] [tool.coverage.run] branch = false -omit = [ - "tests/*", -] parallel = true -source = [ "src" ] +source = ["src"] [tool.coverage.report] fail_under = 0 @@ -81,9 +85,6 @@ exclude_lines = [ "raise NotImplemented", ] omit = [ - "*/.buildout/eggs/*", - "buildout-cache/eggs/*", - "eggs/*", "parts/*", "src/crate/client/_pep440.py", ] @@ -108,15 +109,10 @@ non_interactive = true [tool.pytest.ini_options] addopts = "-rA --verbosity=3" minversion = "2.0" -log_level = "DEBUG" -log_cli_level = "DEBUG" testpaths = [ - "src", "tests", ] xfail_strict = true -markers = [ -] [tool.ruff] @@ -176,6 +172,8 @@ lint.per-file-ignores."tests/*" = [ "S101", # Asserts. "S105", # Possible hardcoded password assigned to: "password" "S106", # Possible hardcoded password assigned to argument: "password" + "S202", # CrateDB tarballs are trusted + "S310", # False positive; it's a https url "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes ] lint.per-file-ignores."src/crate/client/{connection.py,http.py}" = [ @@ -185,37 +183,3 @@ lint.per-file-ignores."src/crate/client/{connection.py,http.py}" = [ lint.per-file-ignores."tests/client/test_http.py" = [ "A004", # Import `ConnectionError` is shadowing a Python builtin ] - - -# =================== -# Tasks configuration -# =================== - -[tool.poe.tasks] - -check = [ - "lint", - "test", -] - -format = [ - { cmd = "ruff format ." }, - # Configure Ruff not to auto-fix (remove!): - # unused imports (F401), unused variables (F841), `print` statements (T201), and commented-out code (ERA001). - { cmd = "ruff check --fix --ignore=ERA --ignore=F401 --ignore=F841 --ignore=T20 --ignore=ERA001 ." }, -] - -lint = [ - { cmd = "ruff format --check ." }, - { cmd = "ruff check ." }, - { cmd = "mypy" }, -] - -test = [ - { cmd = "coverage erase" }, - { cmd = "coverage run -m pytest" }, - { cmd = "coverage run bin/test" }, - { cmd = "coverage combine" }, - { cmd = "coverage xml" }, - { cmd = "coverage report" }, -] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 05a476622..000000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -zc.buildout==5.1.1 -zope.interface==8.2 -zope.testrunner>=5,<9 diff --git a/setup.py b/setup.py deleted file mode 100644 index ef52b684c..000000000 --- a/setup.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8; -*- -# -# Licensed to CRATE Technology GmbH ("Crate") under one or more contributor -# license agreements. See the NOTICE file distributed with this work for -# additional information regarding copyright ownership. Crate licenses -# this file to you under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. You may -# obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# However, if you have executed another commercial license agreement -# with Crate these terms will supersede the license and you may use the -# software solely pursuant to the terms of the relevant commercial agreement. - -import os -import re - -from setuptools import find_namespace_packages, setup - - -def read(path): - with open(os.path.join(os.path.dirname(__file__), path)) as f: - return f.read() - - -long_description = read("README.rst") -versionf_content = read("src/crate/client/__init__.py") -version_rex = r'^__version__ = [\'"]([^\'"]*)[\'"]$' -m = re.search(version_rex, versionf_content, re.M) -if m: - version = m.group(1) -else: - raise RuntimeError("Unable to find version string") - -setup( - name="crate", - version=version, - url="https://github.com/crate/crate-python", - author="Crate.io", - author_email="office@crate.io", - description="CrateDB Python Client", - long_description=long_description, - long_description_content_type="text/x-rst", - platforms=["any"], - license="Apache-2.0", - license_files=["LICENSE"], - keywords="cratedb db api dbapi database sql http rdbms olap", - packages=find_namespace_packages("src"), - package_dir={"": "src"}, - install_requires=[ - "orjson<4", - "urllib3", - "verlib2>=0.3", - ], - extras_require={ - "doc": [ - "crate-docs-theme>=0.26.5", - "sphinx>=3.5,<9", - ], - "test": [ - 'backports.zoneinfo<1; python_version<"3.9"', - "certifi", - "createcoverage>=1,<2", - "mypy<1.20", - "poethepoet<1", - "ruff<0.15", - "stopit>=1.1.2,<2", - "pytz", - "zc.customdoctests>=1.0.1,<2", - "zope.testing>=4,<7", - "zope.testrunner>=5,<9", - ], - }, - python_requires=">=3.6", - package_data={"": ["*.txt"]}, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Database", - ], -) diff --git a/tests/testing/test_layer.py b/tests/testing/test_layer.py index 60e88b884..ae799354b 100644 --- a/tests/testing/test_layer.py +++ b/tests/testing/test_layer.py @@ -18,11 +18,17 @@ # However, if you have executed another commercial license agreement # with Crate these terms will supersede the license and you may use the # software solely pursuant to the terms of the relevant commercial agreement. + import json import os +import platform +import sys +import tarfile import tempfile import urllib +import zipfile from io import BytesIO +from pathlib import Path from unittest import TestCase, mock import urllib3 @@ -38,6 +44,34 @@ from .settings import crate_path +URL_TMPL = "https://cdn.crate.io/downloads/releases/cratedb/{arch}_{os}/crate-6.1.2.{ext}" + + +def get_crate_url() -> str: + extension = "tar.gz" + + machine = platform.machine() + if machine.startswith("arm") or machine == "aarch64": + arch = "aarch64" + else: + arch = "x64" + + if sys.platform.startswith("linux"): + os = "linux" + elif sys.platform.startswith("win32"): + os = "windows" + extension = "zip" + elif sys.platform.startswith("darwin"): + os = "mac" + + # there are no aarch64/arm64 distributions available + # x64 should work via emulation layer + arch = "x64" + else: + raise ValueError(f"Unsupported platform: {sys.platform}") + + return URL_TMPL.format(arch=arch, os=os, ext=extension) + class LayerUtilsTest(TestCase): def test_prepend_http(self): @@ -127,6 +161,28 @@ def test_java_home_env_override(self): class LayerTest(TestCase): + @classmethod + def setup_class(cls): + url = get_crate_url() + target_path = Path(crate_path()) + if target_path.exists(): + return + if not url.startswith("https:"): + raise ValueError("Invalid url") + filename, _msg = urllib.request.urlretrieve(url) + if sys.platform.startswith("win32"): + with zipfile.ZipFile(filename) as z: + first_file = z.namelist()[0] + folder_name = os.path.dirname(first_file) + z.extractall(target_path.parent) + (target_path.parent / folder_name).rename(target_path) + else: + with tarfile.open(filename) as t: + first_file = t.getnames()[0] + folder_name = os.path.dirname(first_file) + t.extractall(target_path.parent, filter="data") + (target_path.parent / folder_name).rename(target_path) + def test_basic(self): """ This layer starts and stops a ``Crate`` instance on a given host, port, diff --git a/versions.cfg b/versions.cfg deleted file mode 100644 index 6dd217c8d..000000000 --- a/versions.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[versions] -crate_server = 5.9.2 - -hexagonit.recipe.download = 1.7.1