Skip to content

Commit

Permalink
feat: print reason summary in case of dryrun (#1778)
Browse files Browse the repository at this point in the history
* feat: print summary of needrun reasons on dryrun

* fmt

* display more rules

* use str of reason

* fix bug

* fix adding rulename

* polishing

Co-authored-by: Felix Mölder <felix.moelder@uni-due.de>
  • Loading branch information
johanneskoester and FelixMoelder committed Jul 28, 2022
1 parent d01e777 commit bd2a68b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
16 changes: 16 additions & 0 deletions snakemake/dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -2362,6 +2362,22 @@ def edge(a, b):
],
)

def print_reasons(self):
"""Print summary of execution reasons."""
reasons = defaultdict(set)
for job in self.needrun_jobs(exclude_finished=False):
for reason in self.reason(job).get_names():
reasons[reason].add(job.rule.name)
if reasons:
msg = "Reasons:\n (check individual jobs above for details)"
for reason, rules in sorted(reasons.items()):
rules = sorted(rules)
if len(rules) > 50:
rules = rules[:50] + ["..."]
rules = ", ".join(rules)
msg += f"\n {reason}:\n {rules}"
logger.info(msg)

def stats(self):
from tabulate import tabulate

Expand Down
30 changes: 29 additions & 1 deletion snakemake/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,34 @@ def mark_finished(self):
"called if the job has been run"
self.finished = True

def get_names(self):
if self.forced:
yield "forced"
if self.noio:
yield "neither input nor output"
if self.nooutput:
yield "run or shell but no output"
if self._missing_output:
yield "missing output files"
if self._incomplete_output:
yield "incomplete output files"
if self._updated_input:
yield "updated input files"
if self._updated_input_run:
yield "input files updated by another job"
if self.pipe:
yield "pipe output needed by consuming job"
if self.service:
yield "provides service for consuming job"
if self.input_changed:
yield "set of input files has changed since last execution"
if self.code_changed:
yield "code has changed since last execution"
if self.params_changed:
yield "params have changed since last execution"
if self.software_stack_changed:
yield "software environment definition has changed since last execution"

def __str__(self):
def format_file(f):
if is_flagged(f, "sourcecache_entry"):
Expand All @@ -1619,7 +1647,7 @@ def format_files(files):
else:
if self.noio:
s.append(
"Rules with neither input nor " "output files are always executed."
"Rules with neither input nor output files are always executed."
)
elif self.nooutput:
s.append(
Expand Down
1 change: 1 addition & 0 deletions snakemake/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ def log_provenance_info():
if dryrun:
if len(dag):
logger.run_info("\n".join(dag.stats()))
dag.print_reasons()
log_provenance_info()
logger.info("")
logger.info(
Expand Down

0 comments on commit bd2a68b

Please sign in to comment.