diff --git a/.devcontainer.json b/.devcontainer.json index 16fec551..457487eb 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -28,7 +28,9 @@ "files.trimTrailingWhitespace": true, "python.analysis.autoImportCompletions": true, "python.analysis.autoSearchPaths": false, - "python.analysis.extraPaths": ["/home/vscode/.local/lib/python3.12/"], + "python.analysis.extraPaths": [ + "/home/vscode/.local/lib/python3.12/" + ], "python.analysis.typeCheckingMode": "basic", "python.defaultInterpreterPath": "/usr/local/bin/python", "python.languageServer": "Pylance", @@ -48,7 +50,7 @@ "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": {} }, - "image": "mcr.microsoft.com/devcontainers/python:3", + "image": "jfxs/devcontainer-rye", "name": "Deebot client", // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], @@ -56,5 +58,8 @@ "postStartCommand": "pip install -r requirements-dev.txt && pre-commit install && pip install -e .", // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. "remoteUser": "vscode", - "runArgs": ["-e", "GIT_EDITOR=code --wait"] -} + "runArgs": [ + "-e", + "GIT_EDITOR=code --wait" + ] +} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efb35359..3ec3b1f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,4 @@ +--- name: CI on: @@ -6,34 +7,39 @@ on: - main - dev pull_request: - -env: - DEFAULT_PYTHON: "3.12" + workflow_dispatch: + schedule: + - cron: "0 0 * * *" jobs: code-quality: - runs-on: "ubuntu-latest" - name: Check code quality + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.12"] steps: - - uses: "actions/checkout@v4" - - name: Set up Python ${{ env.DEFAULT_PYTHON }} - id: python - uses: actions/setup-python@v5.1.1 + - uses: actions/checkout@v4 + - uses: eifinger/setup-rye@v4 + id: setup-rye with: - python-version: ${{ env.DEFAULT_PYTHON }} - cache: "pip" - cache-dependency-path: "requirements*" + enable-cache: true + cache-prefix: ${{ matrix.python-version }} + - name: Pin python-version ${{ matrix.python-version }} + run: rye pin ${{ matrix.python-version }} - name: Install dependencies + if: steps.setup-rye.outputs.cache-hit != 'true' + run: | + rye sync --no-lock + - name: Cache pre-commit + uses: actions/cache@v4 + with: + path: ~/.cache/pre-commit + key: pre-commit-|${{ matrix.python-version }}|${{ hashFiles('.pre-commit-config.yaml') }} + - name: Lint run: | - pip install -r requirements.txt - pip install -r requirements-test.txt - # Following steps cannot run by pre-commit.ci as repo = local - - name: Run mypy - run: mypy deebot_client/ - - name: Pylint review - run: pylint deebot_client/ - - name: Verify no getLogger usages - run: scripts/check_getLogger.sh + rye run pre-commit run --all-files + - name: Lint GitHub Actions + uses: eifinger/actionlint-action@v1 tests: runs-on: "ubuntu-latest" @@ -42,20 +48,20 @@ jobs: matrix: python-version: ["3.12"] steps: - - uses: "actions/checkout@v4" - - name: Set up Python ${{ matrix.python-version }} - id: python - uses: actions/setup-python@v5.1.1 + - uses: actions/checkout@v4 + - uses: eifinger/setup-rye@v4 + id: setup-rye with: - python-version: ${{ matrix.python-version }} - cache: "pip" - cache-dependency-path: "requirements*" + enable-cache: true + cache-prefix: ${{ matrix.python-version }} + - name: Pin python-version ${{ matrix.python-version }} + run: rye pin ${{ matrix.python-version }} - name: Install dependencies + if: steps.setup-rye.outputs.cache-hit != 'true' run: | - pip install -r requirements.txt - pip install -r requirements-test.txt - - name: Run pytest - run: pytest --cov=./ --cov-report=xml + rye sync --no-lock + - name: Execute tests + run: rye test -- --cov=./ --cov-report=xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 with: diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index 04e607f3..ca537198 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -21,19 +21,11 @@ jobs: steps: - name: 📥 Checkout the repository uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5.1.1 + - uses: eifinger/setup-rye@v4 with: - python-version: "3.12" - - - name: Install dependencies + enable-cache: true + - name: 📦 Build run: | - python -m pip install --upgrade pip - pip install -q build - - - name: 📦 Build package - run: python -m build - + rye build - name: 📤 Publish package uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.gitignore b/.gitignore index f00ad8e2..47873dc2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ scratch* .idea build dist -venv +.venv # Nosetests files cover/ diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..455808f8 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12.4 diff --git a/pyproject.toml b/pyproject.toml index 26f0cda1..60d3f11c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,6 @@ [build-system] -requires = ["setuptools>=60", - "setuptools-scm>=8.0"] -build-backend = "setuptools.build_meta" +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" [project] name = "deebot-client" @@ -21,27 +20,48 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", ] requires-python = ">=3.12.0" -dynamic = ["dependencies", "version"] +dynamic = ["version"] +dependencies = [ + "aiohttp~=3.10", + "aiomqtt>=2.0.0, <3.0", + "cachetools>=5.0.0,<6.0", + "defusedxml", + "numpy>=1.23.2,<3.0", + "Pillow>=10.0.1,<11.0", + "svg.py>=1.4.2", +] [project.urls] "Homepage" = "https://deebot.readthedocs.io/" "Source Code" = "https://github.com/DeebotUniverse/client.py" "Bug Reports" = "https://github.com/DeebotUniverse/client.py/issues" -[tool.setuptools] -include-package-data = true - -[tool.setuptools.dynamic] -dependencies = {file = ["requirements.txt"]} +[tool.rye] +managed = true +dev-dependencies = [ + "mypy==1.11.1", + "pre-commit==3.8.0", + "pycountry==24.6.1", + "pylint==3.2.6", + "pytest==8.3.2", + "pytest-asyncio==0.23.8", + "pytest-cov==5.0.0", + "pytest-docker-fixtures==1.3.19", + "pytest-timeout==2.3.1", + "testfixtures==8.3.0", + "types-cachetools", + "types-mock", + "types-Pillow", +] -[tool.setuptools.packages.find] -include = ["deebot_client*"] +[tool.hatch.metadata] +allow-direct-references = true -[tool.setuptools_scm] -[tool.black] -target-version = ['py311'] -safe = true +[tool.hatch.build.targets.wheel] +packages = ["src/deebot_client"] +[tool.hatch.version] +source = "vcs" [tool.ruff.lint] @@ -173,4 +193,6 @@ expected-line-ending-format = "LF" overgeneral-exceptions = [ "builtins.BaseException", "builtins.Exception", -] \ No newline at end of file +] + + diff --git a/requirements-dev.lock b/requirements-dev.lock new file mode 100644 index 00000000..94808127 --- /dev/null +++ b/requirements-dev.lock @@ -0,0 +1,113 @@ +# generated by rye +# use `rye lock` or `rye sync` to update this lockfile +# +# last locked with the following flags: +# pre: false +# features: [] +# all-features: false +# with-sources: false +# generate-hashes: false +# universal: false + +-e file:. +aiohappyeyeballs==2.3.4 + # via aiohttp +aiohttp==3.10.0 + # via deebot-client +aiomqtt==2.2.0 + # via deebot-client +aiosignal==1.3.1 + # via aiohttp +astroid==3.2.4 + # via pylint +attrs==23.2.0 + # via aiohttp +cachetools==5.4.0 + # via deebot-client +certifi==2024.7.4 + # via requests +cfgv==3.4.0 + # via pre-commit +charset-normalizer==3.3.2 + # via requests +coverage==7.6.0 + # via pytest-cov +defusedxml==0.7.1 + # via deebot-client +dill==0.3.8 + # via pylint +distlib==0.3.8 + # via virtualenv +docker==7.1.0 + # via pytest-docker-fixtures +filelock==3.15.4 + # via virtualenv +frozenlist==1.4.1 + # via aiohttp + # via aiosignal +identify==2.6.0 + # via pre-commit +idna==3.7 + # via requests + # via yarl +iniconfig==2.0.0 + # via pytest +isort==5.13.2 + # via pylint +mccabe==0.7.0 + # via pylint +multidict==6.0.5 + # via aiohttp + # via yarl +mypy==1.11.1 +mypy-extensions==1.0.0 + # via mypy +nodeenv==1.9.1 + # via pre-commit +numpy==2.0.1 + # via deebot-client +packaging==24.1 + # via pytest +paho-mqtt==2.1.0 + # via aiomqtt +pillow==10.4.0 + # via deebot-client +platformdirs==4.2.2 + # via pylint + # via virtualenv +pluggy==1.5.0 + # via pytest +pre-commit==3.8.0 +pycountry==24.6.1 +pylint==3.2.6 +pytest==8.3.2 + # via pytest-asyncio + # via pytest-cov + # via pytest-docker-fixtures + # via pytest-timeout +pytest-asyncio==0.23.8 +pytest-cov==5.0.0 +pytest-docker-fixtures==1.3.19 +pytest-timeout==2.3.1 +pyyaml==6.0.1 + # via pre-commit +requests==2.32.3 + # via docker + # via pytest-docker-fixtures +svg-py==1.4.3 + # via deebot-client +testfixtures==8.3.0 +tomlkit==0.13.0 + # via pylint +types-cachetools==5.4.0.20240717 +types-mock==5.1.0.20240425 +types-pillow==10.2.0.20240520 +typing-extensions==4.12.2 + # via mypy +urllib3==2.2.2 + # via docker + # via requests +virtualenv==20.26.3 + # via pre-commit +yarl==1.9.4 + # via aiohttp diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 3062f9bc..00000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,2 +0,0 @@ --r requirements.txt --r requirements-test.txt diff --git a/requirements-test.txt b/requirements-test.txt deleted file mode 100644 index c2daae71..00000000 --- a/requirements-test.txt +++ /dev/null @@ -1,13 +0,0 @@ -mypy==1.11.1 -pre-commit==3.8.0 -pycountry==24.6.1 -pylint==3.2.6 -pytest==8.3.2 -pytest-asyncio==0.23.8 -pytest-cov==5.0.0 -pytest-docker-fixtures==1.3.19 -pytest-timeout==2.3.1 -testfixtures==8.3.0 -types-cachetools -types-mock -types-Pillow diff --git a/requirements.lock b/requirements.lock new file mode 100644 index 00000000..890ecce9 --- /dev/null +++ b/requirements.lock @@ -0,0 +1,44 @@ +# generated by rye +# use `rye lock` or `rye sync` to update this lockfile +# +# last locked with the following flags: +# pre: false +# features: [] +# all-features: false +# with-sources: false +# generate-hashes: false +# universal: false + +-e file:. +aiohappyeyeballs==2.3.4 + # via aiohttp +aiohttp==3.10.0 + # via deebot-client +aiomqtt==2.2.0 + # via deebot-client +aiosignal==1.3.1 + # via aiohttp +attrs==23.2.0 + # via aiohttp +cachetools==5.4.0 + # via deebot-client +defusedxml==0.7.1 + # via deebot-client +frozenlist==1.4.1 + # via aiohttp + # via aiosignal +idna==3.7 + # via yarl +multidict==6.0.5 + # via aiohttp + # via yarl +numpy==2.0.1 + # via deebot-client +paho-mqtt==2.1.0 + # via aiomqtt +pillow==10.4.0 + # via deebot-client +svg-py==1.4.3 + # via deebot-client +yarl==1.9.4 + # via aiohttp diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 26177a54..00000000 --- a/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -aiohttp~=3.10 -aiomqtt>=2.0.0,<3.0 -cachetools>=5.0.0,<6.0 -defusedxml -numpy>=1.23.2,<3.0 -Pillow>=10.0.1,<11.0 -svg.py>=1.4.2