diff --git a/.flake8 b/.flake8 deleted file mode 100644 index ce81d75..0000000 --- a/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -max-line-length=88 -extend-ignore=E203,D104,D100,I004,E501 -exclude=tests/data/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a321cbe --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: CI + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + fail-fast: false + + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Setup Pixi + uses: prefix-dev/setup-pixi@28eb668aafebd9dede9d97c4ba1cd9989a4d0004 # v0.9.2 + with: + pixi-version: latest + cache: true + + - name: Check formatting + run: pixi run fmt-check + + - name: Run linter + run: pixi run lint-check + + - name: Run tests + run: pixi run test diff --git a/.github/workflows/enforce-sha.yml b/.github/workflows/enforce-sha.yml new file mode 100644 index 0000000..1273982 --- /dev/null +++ b/.github/workflows/enforce-sha.yml @@ -0,0 +1,17 @@ +on: + push: + branches: [ main, master ] + pull_request: + +name: Security + +permissions: read-all + +jobs: + ensure-pinned-actions: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - name: Ensure SHA pinned actions + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@9e9574ef04ea69da568d6249bd69539ccc704e74 # v4 diff --git a/pixi.lock b/pixi.lock index 13bac6d..da28273 100644 --- a/pixi.lock +++ b/pixi.lock @@ -9,7 +9,6 @@ environments: linux-64: - conda: https://prefix.dev/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://prefix.dev/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/brotli-python-1.2.0-py314hdfeb8a1_0.conda - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda @@ -18,13 +17,11 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.22.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/flake8-7.3.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda @@ -45,19 +42,13 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/license-expression-30.4.4-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda - - conda: https://prefix.dev/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://prefix.dev/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/pycodestyle-2.14.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pyflakes-3.4.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda @@ -73,6 +64,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/rospkg-1.6.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/ruamel.yaml-0.17.17-py314h5bd0f2a_4.conda - conda: https://prefix.dev/conda-forge/linux-64/ruamel.yaml.clib-0.2.14-py314h5bd0f2a_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/ruff-0.14.2-ha3a3aed_0.conda - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda @@ -85,7 +77,6 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - pypi: ./ osx-64: - - conda: https://prefix.dev/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/brotli-python-1.2.0-py314hd4d9bf7_0.conda - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda @@ -94,13 +85,11 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/cffi-2.0.0-py314h8ca4d5a_1.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.22.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/flake8-7.3.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda @@ -117,19 +106,13 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/license-expression-30.4.4-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda - - conda: https://prefix.dev/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - conda: https://prefix.dev/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.4-h230baf5_0.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/pycodestyle-2.14.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pyflakes-3.4.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda @@ -145,6 +128,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/rospkg-1.6.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/ruamel.yaml-0.17.17-py314h6482030_4.conda - conda: https://prefix.dev/conda-forge/osx-64/ruamel.yaml.clib-0.2.14-py314h6482030_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/ruff-0.14.2-hba89d1c_0.conda - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://prefix.dev/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda @@ -157,7 +141,6 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda - pypi: ./ osx-arm64: - - conda: https://prefix.dev/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/brotli-python-1.2.0-py314h95ef04c_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda @@ -166,13 +149,11 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/cffi-2.0.0-py314h44086f9_1.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.22.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/flake8-7.3.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda @@ -190,19 +171,13 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/license-expression-30.4.4-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda - - conda: https://prefix.dev/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - conda: https://prefix.dev/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/pycodestyle-2.14.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pyflakes-3.4.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda @@ -218,6 +193,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/rospkg-1.6.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ruamel.yaml-0.17.17-py314h0612a62_4.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ruamel.yaml.clib-0.2.14-py314h0612a62_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/ruff-0.14.2-h492a034_0.conda - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda @@ -230,7 +206,6 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda - pypi: ./ win-64: - - conda: https://prefix.dev/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/win-64/brotli-python-1.2.0-py314ha608bb1_0.conda - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda @@ -239,13 +214,11 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/certifi-2025.10.5-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/win-64/cffi-2.0.0-py314h5a2d7ad_1.conda - conda: https://prefix.dev/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/click-8.3.0-pyh7428d3b_0.conda - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/distro-1.9.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/docutils-0.22.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/empy-3.3.4-pyh9f0ad1d_1.tar.bz2 - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/flake8-7.3.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda @@ -261,18 +234,12 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/license-expression-30.4.4-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda - - conda: https://prefix.dev/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - conda: https://prefix.dev/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.4-h725018a_0.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/noarch/pycodestyle-2.14.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - - conda: https://prefix.dev/conda-forge/noarch/pyflakes-3.4.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda - conda: https://prefix.dev/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda @@ -287,6 +254,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/rospkg-1.6.0-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/win-64/ruamel.yaml-0.17.17-py314h5a2d7ad_4.conda - conda: https://prefix.dev/conda-forge/win-64/ruamel.yaml.clib-0.2.14-py314h5a2d7ad_0.conda + - conda: https://prefix.dev/conda-forge/win-64/ruff-0.14.2-h3e3edff_0.conda - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda - conda: https://prefix.dev/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda @@ -325,22 +293,6 @@ packages: purls: [] size: 23621 timestamp: 1650670423406 -- conda: https://prefix.dev/conda-forge/noarch/black-25.1.0-pyh866005b_0.conda - sha256: c68f110cd491dc839a69e340930862e54c00fb02cede5f1831fcf8a253bd68d2 - md5: b9b0c42e7316aa6043bdfd49883955b8 - depends: - - click >=8.0.0 - - mypy_extensions >=0.4.3 - - packaging >=22.0 - - pathspec >=0.9 - - platformdirs >=2 - - python >=3.11 - license: MIT - license_family: MIT - purls: - - pkg:pypi/black?source=hash-mapping - size: 172678 - timestamp: 1742502887437 - conda: https://prefix.dev/conda-forge/noarch/boolean.py-5.0-pyhd8ed1ab_0.conda sha256: 6195e09f7d8a3a5e2fc0dddd6d1e87198e9c3d2a1982ff04624957a6c6466e54 md5: 26c3480f80364e9498a48bb5c3e35f85 @@ -580,31 +532,6 @@ packages: - pkg:pypi/charset-normalizer?source=hash-mapping size: 50965 timestamp: 1760437331772 -- conda: https://prefix.dev/conda-forge/noarch/click-8.3.0-pyh707e725_0.conda - sha256: c6567ebc27c4c071a353acaf93eb82bb6d9a6961e40692a359045a89a61d02c0 - md5: e76c4ba9e1837847679421b8d549b784 - depends: - - __unix - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click?source=compressed-mapping - size: 91622 - timestamp: 1758270534287 -- conda: https://prefix.dev/conda-forge/noarch/click-8.3.0-pyh7428d3b_0.conda - sha256: 0a008359973e833b568d0a18cf04556b12a4f5182e745dfc8ade32c38fa1fca5 - md5: 4601476ee4ad7ad522e5ffa5a579a48e - depends: - - __win - - colorama - - python >=3.10 - license: BSD-3-Clause - license_family: BSD - purls: - - pkg:pypi/click?source=hash-mapping - size: 92148 - timestamp: 1758270588199 - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda sha256: ab29d57dc70786c1269633ba3dff20288b81664d3ff8d21af995742e2bb03287 md5: 962b9857ee8e7018c22f2776ffa0b2d7 @@ -659,20 +586,6 @@ packages: - pkg:pypi/exceptiongroup?source=hash-mapping size: 21284 timestamp: 1746947398083 -- conda: https://prefix.dev/conda-forge/noarch/flake8-7.3.0-pyhd8ed1ab_0.conda - sha256: a32e511ea71a9667666935fd9f497f00bcc6ed0099ef04b9416ac24606854d58 - md5: 04a55140685296b25b79ad942264c0ef - depends: - - mccabe >=0.7.0,<0.8.0 - - pycodestyle >=2.14.0,<2.15.0 - - pyflakes >=3.4.0,<3.5.0 - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/flake8?source=hash-mapping - size: 111916 - timestamp: 1750968083921 - conda: https://prefix.dev/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 @@ -1152,17 +1065,6 @@ packages: - pkg:pypi/markupsafe?source=hash-mapping size: 15499 timestamp: 1759055275624 -- conda: https://prefix.dev/conda-forge/noarch/mccabe-0.7.0-pyhd8ed1ab_1.conda - sha256: 9b0037171dad0100f0296699a11ae7d355237b55f42f9094aebc0f41512d96a1 - md5: 827064ddfe0de2917fb29f1da4f8f533 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mccabe?source=hash-mapping - size: 12934 - timestamp: 1733216573915 - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 md5: 592132998493b3ff25fd7479396e8351 @@ -1174,17 +1076,6 @@ packages: - pkg:pypi/mdurl?source=hash-mapping size: 14465 timestamp: 1733255681319 -- conda: https://prefix.dev/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - sha256: 6ed158e4e5dd8f6a10ad9e525631e35cee8557718f83de7a4e3966b1f772c4b1 - md5: e9c622e0d00fa24a6292279af3ab6d06 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/mypy-extensions?source=hash-mapping - size: 11766 - timestamp: 1745776666688 - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 md5: 47e340acb35de30501a76c7c799c41d7 @@ -1289,29 +1180,6 @@ packages: - pkg:pypi/packaging?source=hash-mapping size: 62477 timestamp: 1745345660407 -- conda: https://prefix.dev/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_1.conda - sha256: 9f64009cdf5b8e529995f18e03665b03f5d07c0b17445b8badef45bde76249ee - md5: 617f15191456cc6a13db418a275435e5 - depends: - - python >=3.9 - license: MPL-2.0 - license_family: MOZILLA - purls: - - pkg:pypi/pathspec?source=hash-mapping - size: 41075 - timestamp: 1733233471940 -- conda: https://prefix.dev/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda - sha256: 7efd51b48d908de2d75cbb3c4a2e80dd9454e1c5bb8191b261af3136f7fa5888 - md5: 5c7a868f8241e64e1cf5fdf4962f23e2 - depends: - - python >=3.10 - - python - license: MIT - license_family: MIT - purls: - - pkg:pypi/platformdirs?source=hash-mapping - size: 23625 - timestamp: 1759953252315 - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda sha256: a8eb555eef5063bbb7ba06a379fa7ea714f57d9741fe0efdb9442dbbc2cccbcc md5: 7da7ccd349dbf6487a7778579d2bb971 @@ -1323,17 +1191,6 @@ packages: - pkg:pypi/pluggy?source=hash-mapping size: 24246 timestamp: 1747339794916 -- conda: https://prefix.dev/conda-forge/noarch/pycodestyle-2.14.0-pyhd8ed1ab_0.conda - sha256: 1950f71ff44e64163e176b1ca34812afc1a104075c3190de50597e1623eb7d53 - md5: 85815c6a22905c080111ec8d56741454 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pycodestyle?source=hash-mapping - size: 35182 - timestamp: 1750616054854 - conda: https://prefix.dev/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda sha256: 79db7928d13fab2d892592223d7570f5061c192f27b9febd1a418427b719acc6 md5: 12c566707c80111f9799308d9e265aef @@ -1346,17 +1203,6 @@ packages: - pkg:pypi/pycparser?source=hash-mapping size: 110100 timestamp: 1733195786147 -- conda: https://prefix.dev/conda-forge/noarch/pyflakes-3.4.0-pyhd8ed1ab_0.conda - sha256: 4b6fb3f7697b4e591c06149671699777c71ca215e9ec16d5bd0767425e630d65 - md5: dba204e749e06890aeb3756ef2b1bf35 - depends: - - python >=3.9 - license: MIT - license_family: MIT - purls: - - pkg:pypi/pyflakes?source=hash-mapping - size: 59592 - timestamp: 1750492011671 - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda sha256: 5577623b9f6685ece2697c6eb7511b4c9ac5fb607c9babc2646c811b428fd46a md5: 6b6ece66ebcae2d5f326c77ef2c5a066 @@ -1778,6 +1624,67 @@ packages: - pkg:pypi/ruamel-yaml-clib?source=hash-mapping size: 105692 timestamp: 1760564690504 +- conda: https://prefix.dev/conda-forge/linux-64/ruff-0.14.2-ha3a3aed_0.conda + noarch: python + sha256: d6c3ee6381ce275107a3fb3cfe82499f3cb74da1d95e134a93ed5e4851b4ec01 + md5: ba27344e81c9c460c9502fcbf7bd1e5c + depends: + - python + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=hash-mapping + size: 11071649 + timestamp: 1761253375744 +- conda: https://prefix.dev/conda-forge/osx-64/ruff-0.14.2-hba89d1c_0.conda + noarch: python + sha256: 2e9cde0ed16334f991292b56b1de3ea90f62be90911f5726864dc641f3d94e68 + md5: 6c76d7b3fd40b65ac03385bfaf1eee1e + depends: + - python + - __osx >=10.13 + constrains: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=hash-mapping + size: 10968811 + timestamp: 1761253502632 +- conda: https://prefix.dev/conda-forge/osx-arm64/ruff-0.14.2-h492a034_0.conda + noarch: python + sha256: 34fef6ff3447a243abd7ca98a95f6199af7a38aeb182c7d5d93a7e8681530571 + md5: 22bcd3c3680cd6dcefe9bc73612a7132 + depends: + - python + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=hash-mapping + size: 10033698 + timestamp: 1761253464229 +- conda: https://prefix.dev/conda-forge/win-64/ruff-0.14.2-h3e3edff_0.conda + noarch: python + sha256: 325d09623420156ec7384ba56c20cd3482609d95d2c33ac913b96fc898b3a14c + md5: c946d9d4e16b2aa505695f610c1ecb78 + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/ruff?source=hash-mapping + size: 11568203 + timestamp: 1761253422638 - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda sha256: 972560fcf9657058e3e1f97186cc94389144b46dbdf58c807ce62e83f977e863 md5: 4de79c071274a53dcaf2a8c749d1499e diff --git a/pixi.toml b/pixi.toml index cffa0fa..1b9ef03 100644 --- a/pixi.toml +++ b/pixi.toml @@ -9,8 +9,10 @@ version = "0.1.0" test = "pytest vinca/" # Code quality -format = "black --safe --quiet ." -lint = "flake8 vinca/" +fmt = "ruff format ." +fmt-check = "ruff format --check ." +lint = "ruff check --fix ." +lint-check = "ruff check ." [dependencies] python = ">=3.14.0,<3.15" @@ -28,8 +30,7 @@ license-expression = ">=30.0.0" # Development dependencies pytest = "*" -black = "*" -flake8 = "*" +ruff = "*" [pypi-dependencies] vinca = { path = ".", editable = true} diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..0f59be6 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,12 @@ +line-length = 88 +target-version = "py37" + +[lint] +# Ignore rules that were excluded in .flake8: +# D104: Missing docstring in public package +# E501: Line too long (handled by line-length setting) +ignore = ["D104", "D100", "E501"] + +[lint.extend-per-file-ignores] +# Exclude tests/data/* from all checks +"tests/data/*" = ["ALL"] diff --git a/vinca/distro.py b/vinca/distro.py index e27685a..83e25d6 100644 --- a/vinca/distro.py +++ b/vinca/distro.py @@ -110,7 +110,6 @@ def get_depends(self, pkg, ignore_pkgs=None): def get_released_repo(self, pkg_name): if self.snapshot and pkg_name in self.snapshot: - # In the case of snapshot, for rosdistro_additional_recipes # we also support a 'rev' field, so depending on what is available # we return either the tag or the rev, and the third argument is either 'rev' or 'tag' diff --git a/vinca/generate_azure.py b/vinca/generate_azure.py index 75b68e4..7a7df77 100644 --- a/vinca/generate_azure.py +++ b/vinca/generate_azure.py @@ -428,7 +428,6 @@ def get_full_tree(): def main(): - args = parse_command_line(sys.argv) full_tree = get_full_tree() diff --git a/vinca/generate_gha.py b/vinca/generate_gha.py index ec9762d..86f2e45 100644 --- a/vinca/generate_gha.py +++ b/vinca/generate_gha.py @@ -356,8 +356,6 @@ def build_win_pipeline(stages, trigger_branch, outfile="win.yml", azure_template with open(".scripts/build_win.bat", "r") as fi: script = lu(fi.read()) - jobs = [] - job_names = [] prev_batch_keys = [] for i, s in enumerate(stages): stage_name = f"stage_{i}" diff --git a/vinca/license_utils.py b/vinca/license_utils.py index 38711bc..1cc1171 100644 --- a/vinca/license_utils.py +++ b/vinca/license_utils.py @@ -149,9 +149,7 @@ def convert_to_spdx_license( # Split by comma and process each part # Filter out empty strings from malformed input # (trailing/double commas) - parts = [ - part.strip() for part in lic_str.split(",") if part.strip() - ] + parts = [part.strip() for part in lic_str.split(",") if part.strip()] sub_licenses = [] seen_sub = set() for part in parts: diff --git a/vinca/main.py b/vinca/main.py index bdb065b..65066fc 100644 --- a/vinca/main.py +++ b/vinca/main.py @@ -251,7 +251,7 @@ def read_vinca_yaml(filepath): def read_snapshot(vinca_conf): - if not "rosdistro_snapshot" in vinca_conf: + if "rosdistro_snapshot" not in vinca_conf: return None, None yaml = ruamel.yaml.YAML() @@ -395,17 +395,17 @@ def generate_output(pkg_shortname, vinca_conf, distro, version, all_pkgs=None): # Dummy recipes do not actually build anything, so we set the script to empty output["build"]["script"] = "" elif pkg.get_build_type() in ["cmake", "catkin"]: - output["build"][ - "script" - ] = "${{ '$RECIPE_DIR/build_catkin.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_catkin.bat' }}" + output["build"]["script"] = ( + "${{ '$RECIPE_DIR/build_catkin.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_catkin.bat' }}" + ) elif pkg.get_build_type() in ["ament_cmake"]: - output["build"][ - "script" - ] = "${{ '$RECIPE_DIR/build_ament_cmake.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_ament_cmake.bat' }}" + output["build"]["script"] = ( + "${{ '$RECIPE_DIR/build_ament_cmake.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_ament_cmake.bat' }}" + ) elif pkg.get_build_type() in ["ament_python"]: - output["build"][ - "script" - ] = "${{ '$RECIPE_DIR/build_ament_python.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_ament_python.bat' }}" + output["build"]["script"] = ( + "${{ '$RECIPE_DIR/build_ament_python.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_ament_python.bat' }}" + ) resolved_setuptools = resolve_pkgname("python-setuptools", vinca_conf, distro) output["requirements"]["host"].extend(resolved_setuptools) else: @@ -474,10 +474,6 @@ def generate_output(pkg_shortname, vinca_conf, distro, version, all_pkgs=None): ) for dep in build_deps: - if dep in ["REQUIRE_OPENGL", "REQUIRE_GL"]: - output["requirements"]["host"].append(dep) - continue - resolved_dep = resolve_pkgname(dep, vinca_conf, distro) if not resolved_dep: unsatisfied_deps.add(dep) @@ -492,10 +488,6 @@ def generate_output(pkg_shortname, vinca_conf, distro, version, all_pkgs=None): run_deps += gdeps for dep in run_deps: - if dep in ["REQUIRE_OPENGL", "REQUIRE_GL"]: - output["requirements"]["host"].append(dep) - continue - resolved_dep = resolve_pkgname(dep, vinca_conf, distro, is_rundep=True) if not resolved_dep: unsatisfied_deps.add(dep) @@ -589,49 +581,6 @@ def sortkey(k): {"if": "build_platform == target_platform", "then": [pkg_move_to_build]} ] - # fix up OPENGL support for Unix - if ( - "REQUIRE_OPENGL" in output["requirements"]["run"] - or "REQUIRE_OPENGL" in output["requirements"]["host"] - ): - # add requirements for opengl - while "REQUIRE_OPENGL" in output["requirements"]["run"]: - output["requirements"]["run"].remove("REQUIRE_OPENGL") - while "REQUIRE_OPENGL" in output["requirements"]["host"]: - output["requirements"]["host"].remove("REQUIRE_OPENGL") - - output["requirements"]["host"] += [ - { - "if": "linux", - "then": ["libgl-devel", "libopengl-devel"], - } - ] - - output["requirements"]["host"] += [ - {"if": "unix", "then": ["xorg-libx11", "xorg-libxext"]}, - ] - output["requirements"]["run"] += [ - {"if": "unix", "then": ["xorg-libx11", "xorg-libxext"]}, - ] - - # fix up GL support for Unix - if ( - "REQUIRE_GL" in output["requirements"]["run"] - or "REQUIRE_GL" in output["requirements"]["host"] - ): - # add requirements for gl - while "REQUIRE_GL" in output["requirements"]["run"]: - output["requirements"]["run"].remove("REQUIRE_GL") - while "REQUIRE_GL" in output["requirements"]["host"]: - output["requirements"]["host"].remove("REQUIRE_GL") - - output["requirements"]["host"] += [ - { - "if": "linux", - "then": ["libgl-devel"], - } - ] - # remove duplicates for dep_type in ["build", "host", "run"]: tmp_nonduplicate = [] @@ -797,6 +746,7 @@ def generate_source_version(distro, vinca_conf): entry["git"] = url entry[ref_type] = ref pkg_names = resolve_pkgname(pkg_shortname, vinca_conf, distro) + version = distro.get_version(pkg_shortname) if vinca_conf.get("trigger_new_versions"): if ( not pkg_names @@ -866,7 +816,6 @@ def get_selected_packages(distro, vinca_conf): ) selected_packages = selected_packages.union(additional_packages) elif vinca_conf["packages_select_by_deps"]: - if ( "packages_skip_by_deps" in vinca_conf and vinca_conf["packages_skip_by_deps"] is not None @@ -1140,51 +1089,9 @@ def parse_package(pkg, distro, vinca_conf, path): ) if pkg.get_build_type() in ["cmake", "catkin"]: - recipe["build"][ - "script" - ] = "${{ '$RECIPE_DIR/build_catkin.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_catkin.bat' }}" - - # fix up OPENGL support for Unix - if ( - "REQUIRE_OPENGL" in recipe["requirements"]["run"] - or "REQUIRE_OPENGL" in recipe["requirements"]["host"] - ): - # add requirements for opengl - while "REQUIRE_OPENGL" in recipe["requirements"]["run"]: - recipe["requirements"]["run"].remove("REQUIRE_OPENGL") - while "REQUIRE_OPENGL" in recipe["requirements"]["host"]: - recipe["requirements"]["host"].remove("REQUIRE_OPENGL") - - recipe["requirements"]["host"] += [ - { - "if": "linux", - "then": ["libgl-devel", "libopengl-devel"], - } - ] - recipe["requirements"]["host"] += [ - {"if": "unix", "then": ["xorg-libx11", "xorg-libxext"]}, - ] - recipe["requirements"]["run"] += [ - {"if": "unix", "then": ["xorg-libx11", "xorg-libxext"]}, - ] - - # fix up GL support for Unix - if ( - "REQUIRE_GL" in recipe["requirements"]["run"] - or "REQUIRE_GL" in recipe["requirements"]["host"] - ): - # add requirements for gl - while "REQUIRE_GL" in recipe["requirements"]["run"]: - recipe["requirements"]["run"].remove("REQUIRE_GL") - while "REQUIRE_GL" in recipe["requirements"]["host"]: - recipe["requirements"]["host"].remove("REQUIRE_GL") - - recipe["requirements"]["host"] += [ - { - "if": "linux", - "then": ["libgl-devel"], - } - ] + recipe["build"]["script"] = ( + "${{ '$RECIPE_DIR/build_catkin.sh' if unix or wasm32 else '%RECIPE_DIR%\\\\bld_catkin.bat' }}" + ) return recipe @@ -1197,8 +1104,6 @@ def main(): base_dir = os.path.abspath(arguments.dir) vinca_yaml = os.path.join(base_dir, "vinca.yaml") vinca_conf = read_vinca_yaml(vinca_yaml) - snapshot = vinca_conf.get("snapshot", None) - additional_packages_snapshot = vinca_conf.get("_additional_packages_snapshot", None) if arguments.trigger_new_versions: vinca_conf["trigger_new_versions"] = True @@ -1283,10 +1188,6 @@ def main(): if "://" in fn: selected_bn = vinca_conf.get("build_number", 0) - explicitly_selected_pkgs = [ - f"ros-{distro}-{pkg.replace('_', '-')}" - for pkg in ensure_list(vinca_conf["packages_select_by_deps"]) - ] all_pkgs = repodata.get("packages", {}) all_pkgs.update(repodata.get("packages.conda", {})) for _, pkg in all_pkgs.items():