diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5954074..f65d7d5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,41 +11,29 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - name: Setup pixi + uses: prefix-dev/setup-pixi@v0 with: - python-version: "3.11" - - - name: Install poetry - run: pip install poetry - - - name: Install dependencies - run: | - poetry install --sync + environments: dev - name: Check formatting - run: poetry run black --check . + run: pixi run --environment dev format --check . linting: runs-on: ubuntu-latest steps: - name: Check out the code - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - name: Setup pixi + uses: prefix-dev/setup-pixi@v0 with: - python-version: "3.11" - - - name: Install poetry - run: pip install poetry - - - name: Install dependencies - run: | - poetry install --sync + environments: dev - name: Check code - run: poetry run flake8 + run: pixi run --environment dev lint testing: runs-on: ubuntu-latest @@ -58,23 +46,22 @@ jobs: - "8888:3306" options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: koesterlab/setup-slurm-action@v1 - - uses: actions/setup-python@v5 + - name: Setup pixi + uses: prefix-dev/setup-pixi@v0 with: - python-version: "3.11" - - - name: Install poetry - run: pip install poetry + environments: dev - - name: Install dependencies - run: | - poetry install --sync + - name: Install plugin package + run: pixi run --environment dev python -m pip install -e . - name: Run pytest - run: poetry run coverage run -m pytest tests/ -sv --tb=short --disable-warnings + run: | + pixi run --environment dev \ + python -m pytest -vv --capture=no tests - name: Run Coverage - run: poetry run coverage report -m + run: pixi run --environment dev coverage-report diff --git a/.gitignore b/.gitignore index ad6672d8..557dc0ac 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,6 @@ cython_debug/ #.idea/ .aider* +# pixi environments +.pixi/* +!.pixi/config.toml diff --git a/pyproject.toml b/pyproject.toml index 4dc84588..26934a7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,49 +1,113 @@ -[tool.poetry] +[build-system] +requires = ["setuptools>=64"] +build-backend = "setuptools.build_meta" + + +[project] name = "snakemake-executor-plugin-slurm" version = "2.7.1" description = "A Snakemake executor plugin for submitting jobs to a SLURM cluster." +readme = "README.md" +requires-python = ">=3.11,<4" +license = {text = "MIT"} authors = [ - "Christian Meesters ", - "David Lähnemann ", - "Johannes Koester ", + {name = "Christian Meesters", email = "meesters@uni-mainz.de"}, + {name = "David Lähnemann", email = "david.laehnemann@dkfz-heidelberg.de"}, + {name = "Johannes Koester", email = "johannes.koester@uni-due.de"}, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Science/Research", + "Natural Language :: English", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Scientific/Engineering", ] -readme = "README.md" -license = "MIT" -repository = "https://github.com/snakemake/snakemake-executor-plugin-slurm" -documentation = "https://snakemake.github.io/snakemake-plugin-catalog/plugins/executor/slurm.html" keywords = ["snakemake", "plugin", "executor", "cluster", "slurm"] +dependencies = [ + "snakemake-interface-common>=1.23.0,<2", + "snakemake-interface-executor-plugins>=9.4.0,<10", + "snakemake-executor-plugin-slurm-jobstep>=0.6.0,<1", + "pandas>=2.3.3,<4", + "numpy>=2.4.5,<3", + "throttler>=1.2.2,<2", + "pyyaml>=6.0.3,<7", +] -[tool.poetry.dependencies] -python = "^3.11" -snakemake-interface-common = ">=1.23.0,<2" -snakemake-interface-executor-plugins = ">=9.4.0,<10" -snakemake-executor-plugin-slurm-jobstep = ">=0.6.0,<1" -pandas = ">=2.3.3,<4" -numpy = ">=2.4.5,<3" -throttler = ">=1.2.3,<2" -pyyaml = ">=6.0.3,<7" - -[tool.poetry.group.dev.dependencies] -black = "==26.3.1" -flake8 = ">=6.1.0,<7" -coverage = ">=7.14.0,<8" -pytest = ">=9.0.3,<10" -snakemake = ">=9.21.0,<10" -pandas = ">=2.3.3,<4" +[project.urls] +Repository = "https://github.com/snakemake/snakemake-executor-plugin-slurm" +Documentation = "https://snakemake.github.io/snakemake-plugin-catalog/plugins/executor/slurm.html" -[tool.poetry.scripts] +[project.scripts] generate-slurm-partition-config = "snakemake_executor_plugin_slurm.cli:main" +[tool.codespell] +skip = ".git,*.pdf,*.svg,versioneer.py,*.css,test_*" +check-hidden = true + [tool.coverage.run] omit = [".*", "*/site-packages/*", "Snakefile"] -[tool.black] -line-length = 88 -extend-exclude = 'tests/test_scontrol_parsing\.py' +[tool.ruff] +target-version = "py311" +extend-exclude = ["tests/test_scontrol_parsing.py"] [tool.pytest.ini_options] python_files = ["test_*.py", "tests.py"] -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +[tool.pixi] + +# Workspace table (required for preview features) +[tool.pixi.workspace] +#preview = ["pixi-build"] +channels = ["conda-forge", "bioconda"] +platforms = ["linux-64"] + +# Conda-only dependencies (must be a table) +[tool.pixi.dependencies] +python = ">=3.11,<3.14" +pip = ">=24,<26" +packaging = ">=24,<26" + +# Pip-only dependencies (install the plugin from local path) +[tool.pixi.pypi-dependencies] +snakemake-executor-plugin-slurm = { path = "." } + +[tool.pixi.environments] +dev = { features = ["test", "style"] } +quality = { features = ["style"] } +publish = { features = ["build"] } + +[tool.pixi.feature.test.pypi-dependencies] +pytest = ">=9.0.3,<10" +coverage = ">=7.14.0,<8" +snakemake = ">=9.21.0,<10" + +[tool.setuptools.packages.find] +include = ["snakemake_executor_plugin_slurm*"] +# Exclude the `pr_logo` directory (and any sub‑files) from the packaged source +exclude = ["pr_logo*"] + +[dependency-groups] +dev = ["snakemake"] + +[tool.pixi.feature.test.tasks] +test = {cmd = "pytest"} +coverage-report = {cmd = "coverage run -m pytest -vv --capture=no && coverage report -m"} + +[tool.pixi.feature.style.pypi-dependencies] +ruff = ">=0.10.0,<0.11" + +[tool.pixi.feature.style.tasks] +format = {cmd = "ruff format"} +lint = {cmd = "ruff check ."} + +[tool.pixi.feature.build.pypi-dependencies] +build = "*" +twine = "*" + +[tool.pixi.feature.build.tasks] +build-check = {cmd = "python -m build && twine check dist/*"} diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 34599d0e..00000000 --- a/setup.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[flake8] -# Recommend matching the black line length (default 88), -# rather than using the flake8 default of 79: -max-line-length = 88 -extend-ignore = - # See https://github.com/PyCQA/pycodestyle/issues/373 - E203, -per-file-ignores = - tests/test_scontrol_parsing.py:E501 \ No newline at end of file diff --git a/snakemake_executor_plugin_slurm/__init__.py b/snakemake_executor_plugin_slurm/__init__.py index 8c6092c9..cbc56a00 100644 --- a/snakemake_executor_plugin_slurm/__init__.py +++ b/snakemake_executor_plugin_slurm/__init__.py @@ -510,8 +510,7 @@ def __post_init__(self, test_mode: bool = False): "the array_limit setting to enable array job submission." ) raise WorkflowError( - "Array job submission is effectively disabled due to " - "low array_limit." + "Array job submission is effectively disabled due to low array_limit." ) self.slurm_logdir = _select_logdir(self.workflow) # Check the environment variable "SNAKEMAKE_SLURM_PARTITIONS", @@ -675,10 +674,8 @@ def run_jobs(self, jobs: List[JobExecutorInterface]): "all" in self.array_jobs or rule_name in self.array_jobs ) # TODO: use more sensible logging information, once finished - self.logger.debug( - f"Running jobs for rule: {rule_name}, " f"{same_rule_jobs}" - ) - self.logger.debug("Current array job settings: " f"{self.array_jobs}") + self.logger.debug(f"Running jobs for rule: {rule_name}, {same_rule_jobs}") + self.logger.debug(f"Current array job settings: {self.array_jobs}") if array_selected_for_rule: dag = getattr(self.workflow, "dag", None) diff --git a/tests/tests.py b/tests/tests.py index 0f78f1b5..35874bca 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -184,9 +184,9 @@ def test_simple_workflow(self, tmp_path): report_found = True report_path = os.path.join(expected_path, fname) # Verify it's not empty - assert ( - os.stat(report_path).st_size > 0 - ), f"Efficiency report {report_path} is empty" + assert os.stat(report_path).st_size > 0, ( + f"Efficiency report {report_path} is empty" + ) break assert report_found, "Efficiency report file not found" diff --git a/upgrade_dependencies.py b/upgrade_dependencies.py index 398e8952..99ffd36f 100644 --- a/upgrade_dependencies.py +++ b/upgrade_dependencies.py @@ -58,7 +58,7 @@ def sensible_range(ver): if not m: return None major, minor, patch = map(int, m.groups()) - return f">={major}.{minor}.{patch},<{major+1}" + return f">={major}.{minor}.{patch},<{major + 1}" print("Upgrading pyproject.toml dependencies to sensible ranges...") print(f"(dry-run mode: {dry_run})\n")