Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fe6a812
fix: extracting job id from convoluted output, if necessary
cmeesters Nov 14, 2025
44249fe
fix: syntax typo
cmeesters Nov 14, 2025
7b66597
fix: removed sunused import
cmeesters Nov 14, 2025
44a5507
feat: included black configuration!
cmeesters Nov 14, 2025
b9d38fb
fix: line length (formatting)!
cmeesters Nov 14, 2025
0c0c757
Update snakemake_executor_plugin_slurm/validation.py
cmeesters Nov 14, 2025
40783f8
fix: unconditional JOBID validation and renamed the validator function
cmeesters Nov 17, 2025
40a2d82
fix: renamed the validator function - added regex comments
cmeesters Nov 17, 2025
8b7fed7
fix: formatting
cmeesters Nov 17, 2025
b375a32
Merge branch 'fix/jobid_extraction_from_convoluted_output' of github.…
cmeesters Nov 17, 2025
73f341d
fix: linting1
cmeesters Nov 17, 2025
f880423
Update snakemake_executor_plugin_slurm/__init__.py
cmeesters Nov 17, 2025
2ab4acf
fix: formatting - a f****** white space
cmeesters Nov 17, 2025
e0e2107
Merge branch 'fix/jobid_extraction_from_convoluted_output' of github.…
cmeesters Nov 17, 2025
9c21a5d
feat: extended the jobid regex to be more stable (rejecting matching …
cmeesters Nov 17, 2025
aaf3264
test: extended test range for this PR
cmeesters Nov 17, 2025
1282594
fix: corrected test cases
cmeesters Nov 17, 2025
a65bfc0
Update snakemake_executor_plugin_slurm/validation.py
cmeesters Nov 17, 2025
68d58f7
Merge branch 'main' into fix/jobid_extraction_from_convoluted_output
cmeesters Nov 20, 2025
d525b38
Merge branch 'main' into fix/jobid_extraction_from_convoluted_output
cmeesters Nov 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ pandas = "^2.2.3"
[tool.coverage.run]
omit = [".*", "*/site-packages/*", "Snakefile"]

[tool.black]
line-length = 88

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
6 changes: 4 additions & 2 deletions snakemake_executor_plugin_slurm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
)
from .efficiency_report import create_efficiency_report
from .submit_string import get_submit_command
from .validation import validate_slurm_extra
from .validation import validate_slurm_job_id, validate_slurm_extra


@dataclass
Expand Down Expand Up @@ -382,8 +382,10 @@ def run_job(self, job: JobExecutorInterface):
# To extract the job id we split by semicolon and take the first element
# (this also works if no cluster name was provided)
slurm_jobid = out.strip().split(";")[0]
# this slurm_jobid might be wrong: some cluster admin give convulted
# sbatch outputs. So we need to validate it properly:
if not slurm_jobid:
raise WorkflowError("Failed to retrieve SLURM job ID from sbatch output.")
slurm_jobid = validate_slurm_job_id(slurm_jobid, out)
slurm_logfile = slurm_logfile.with_name(
slurm_logfile.name.replace("%j", slurm_jobid)
)
Expand Down
39 changes: 39 additions & 0 deletions snakemake_executor_plugin_slurm/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,45 @@
from snakemake_interface_common.exceptions import WorkflowError


def validate_slurm_job_id(job_id, output):
"""
Validate that the SLURM job ID is a positive integer.
Args:
job_id (str): The SLURM job ID to validate.
output (str): The full sbatch output to parse if job_id is invalid.
Raises:
WorkflowError: If the job ID is not a positive integer or we cannot
determine a valid job ID from the given input string.
"""
if re.match(r"^\d+$", job_id):
return job_id
else:
# Try matching a positive integer, raise an error if more than one match or
# no match found. Match standalone integers, excluding those followed by %, letters,
# or digits (units/percentages/floats). Allows format: "1234" or
# "1234; clustername" (SLURM multi-cluster format).

# If the first attempt to validate the job fails, try parsing the sbatch output
# a bit more sophisticatedly:
matches = re.findall(
r"\b\d+(?![%A-Za-z\d.])", output
)
if len(matches) == 1:
return matches[0]
elif len(matches) > 1:
raise WorkflowError(
f"Multiple possible SLURM job IDs found in: {output}. "
"Was looking for exactly one positive integer."
)
elif not matches:
raise WorkflowError(
f"No valid SLURM job ID found in: {output}. "
"Was looking for exactly one positive integer."
)


def get_forbidden_slurm_options():
"""
Return a dictionary of forbidden SLURM options that the executor manages.
Expand Down
Loading