diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..887a2c1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# SCM syntax highlighting & preventing 3-way merges +pixi.lock merge=binary linguist-language=YAML linguist-generated=true diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 4766b98..f2758d0 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -17,34 +17,27 @@ jobs: release-type: python package-name: snakemake-interface-executor-plugins - publish: + publish-pypi: runs-on: ubuntu-latest needs: release-please if: ${{ needs.release-please.outputs.release_created }} - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-python@v2 - with: - python-version: "3.11" - - name: Install poetry - run: pip install poetry - - - name: Determine dependencies - run: poetry lock + steps: + - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - name: Install Pixi + uses: prefix-dev/setup-pixi@v0.8.3 with: - python-version: "3.11" - cache: poetry + environments: publish + pixi-version: v0.42.1 - - name: Install Dependencies using Poetry + - name: Build source and wheel distribution + check build + # this will build the source and wheel into the dist/ directory run: | - poetry install + pixi run --environment publish check-build - - name: Publish to PyPi + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 env: PYPI_USERNAME: __token__ PYPI_PASSWORD: ${{ secrets.PYPI_TOKEN }} - run: poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2057e74..ce99fd5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,88 +7,52 @@ on: pull_request: branches-ignore: [] +permissions: + contents: read + checks: write + issues: write + pull-requests: write + jobs: - formatting: + quality-control: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@v3 - - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - - - name: Install poetry - run: pip install poetry - - - name: Determine dependencies - run: poetry lock - - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - cache: poetry + uses: actions/checkout@v4 - - name: Install Dependencies using Poetry - run: poetry install - - - name: Check formatting - run: poetry run black --check . - - linting: - runs-on: ubuntu-latest - steps: - - name: Check out the code - uses: actions/checkout@v3 - - - uses: actions/setup-python@v4 + - name: Install Pixi + uses: prefix-dev/setup-pixi@v0.8.3 with: - python-version: "3.11" - - - name: Install poetry - run: pip install poetry + environments: dev + pixi-version: v0.42.1 - - name: Determine dependencies - run: poetry lock - - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - cache: poetry + - name: Ruff Format + if: always() + run: | + pixi run --environment dev format --check - - name: Install Dependencies using Poetry - run: poetry install + - name: Ruff lint + if: always() + run: | + pixi run --environment dev lint --diff + # - name: Mypy + # if: always() + # run: | + # pixi run --environment dev type-check - - name: Check code - run: poetry run flake8 + - name: Collect QC + run: echo "All quality control checks passed" testing: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - name: Install Pixi + uses: prefix-dev/setup-pixi@v0.8.3 with: - python-version: "3.11" - - - name: Install poetry - run: pip install poetry - - - name: Determine dependencies - run: poetry lock - - - uses: actions/setup-python@v4 - with: - python-version: "3.11" - cache: poetry - - - name: Install dependencies - run: | - pip install connection-pool # because it is incompatible with poetry - poetry install - - - name: Run pytest - run: poetry run coverage run -m pytest tests/tests.py + environments: dev + pixi-version: v0.42.1 - - name: Run Coverage - run: poetry run coverage report -m + - name: Run tests + run: pixi run --environment dev test --show-capture=all -s -vv diff --git a/.gitignore b/.gitignore index bcc3d59..ec4391f 100644 --- a/.gitignore +++ b/.gitignore @@ -159,4 +159,8 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ -poetry.lock \ No newline at end of file +poetry.lock +# pixi environments +.pixi +*.egg-info +pixi.lock diff --git a/pyproject.toml b/pyproject.toml index 61236a1..154c889 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,26 +1,16 @@ -[tool.poetry] -authors = ["Johannes Köster "] -description = "This package provides a stable interface for interactions between Snakemake and its executor plugins." -license = "MIT" +[project] name = "snakemake-interface-executor-plugins" -packages = [{include = "snakemake_interface_executor_plugins"}] -readme = "README.md" version = "9.3.3" - -[tool.poetry.dependencies] -argparse-dataclass = "^2.0.0" -python = "^3.11" -throttler = "^1.2.2" -snakemake-interface-common = "^1.17.4" - -[tool.poetry.dev-dependencies] -black = "^24.0.0" -coverage = {extras = ["toml"], version = "^6.3.1"} -flake8 = "^4.0.1" -flake8-bugbear = "^22.1.11" -pytest = "^7.0" -snakemake = {git="https://github.com/snakemake/snakemake.git"} -snakemake-executor-plugin-cluster-generic = {git = "https://github.com/snakemake/snakemake-executor-plugin-cluster-generic.git"} +description = "This package provides a stable interface for interactions between Snakemake and its executor plugins." +authors = [{ name = "Johannes Köster", email = "johannes.koester@uni-due.de" }] +license = { text = "MIT" } +readme = "README.md" +requires-python = ">=3.11" +dependencies = [ + "snakemake-interface-common>=1.17.4", + "throttler>=1.2.2", + "argparse-dataclass>=2.0.0", +] [tool.coverage.run] omit = [".*", "*/site-packages/*"] @@ -31,3 +21,57 @@ fail_under = 63 [build-system] build-backend = "poetry.core.masonry.api" requires = ["poetry-core"] + +[tool.pixi.project] +channels = ["conda-forge"] +platforms = ["osx-arm64", "linux-64"] + +[tool.pixi.pypi-dependencies] + +[tool.pixi.tasks] + +[tool.pixi.environments] +dev = { features = ["dev"] } +publish = { features = ["publish"] } + +[tool.pixi.feature.dev.pypi-dependencies] +snakemake-interface-executor-plugins = { path = ".", editable = true } +snakemake = { git = "https://github.com/snakemake/snakemake.git" } +snakemake-executor-plugin-cluster-generic = { git = "https://github.com/snakemake/snakemake-executor-plugin-cluster-generic.git" } + +[tool.pixi.feature.dev.tasks.test] +cmd = [ + "pytest", + "--cov=snakemake_interface_executor_plugins", + "--cov-report=xml:coverage-report/coverage.xml", + "--cov-report=term-missing", + "tests/tests.py" +] +description = "Run tests and generate coverage report" + + +[tool.pixi.feature.dev.dependencies] +pytest = ">=8.3.5,<9" +ruff = ">=0.10.0,<0.11" +mypy = ">=1.15.0,<2" +pytest-cov = ">=6.0.0,<7" + +[tool.pixi.feature.dev.tasks] +format = "ruff format snakemake_interface_executor_plugins" +lint = "ruff check" +type-check = "mypy snakemake_interface_executor_plugins/" +qc = { depends-on = ["format", "lint", "type-check"] } + +[tool.mypy] +ignore_missing_imports = true + +# Publish +[tool.pixi.feature.publish.dependencies] +twine = ">=6.1.0,<7" +python-build = ">=1.2.2,<2" + +[tool.pixi.feature.publish.tasks] +build = { cmd = "python -m build", description = "Build the package into the dist/ directory" } +check-build = { cmd = "python -m twine check dist/*", depends-on = [ + "build", +], description = "Check that the package can be uploaded" } diff --git a/snakemake_interface_executor_plugins/executors/base.py b/snakemake_interface_executor_plugins/executors/base.py index 1be689f..1f16f36 100644 --- a/snakemake_interface_executor_plugins/executors/base.py +++ b/snakemake_interface_executor_plugins/executors/base.py @@ -46,7 +46,8 @@ def isdigit(i): for resource, value in job.resources.items() if isinstance(value, int) # need to check bool seperately because bool is a subclass of int - and isdigit(value) and resource not in excluded_resources + and isdigit(value) + and resource not in excluded_resources } def get_resource_declarations(self, job: JobExecutorInterface):