Skip to content

Commit

Permalink
much nicer printing
Browse files Browse the repository at this point in the history
  • Loading branch information
pdimens authored Jan 8, 2025
1 parent 66c7f77 commit b2e2796
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
27 changes: 23 additions & 4 deletions harpy/_launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ def iserror(text):
"""logical check for erroring trigger words in snakemake output"""
return "Exception" in text or "Error" in text or "MissingOutputException" in text

def highlight_params(text):
"""make important snakemake attributes like 'input:' highlighted in the error output"""
if text.startswith(" jobid:"):
return text.replace("jobid:", "[bold default]jobid:[/bold default]").rstrip()
if text.startswith(" input:"):
return text.replace("input:", "[bold default]input:[/bold default]").rstrip()
if text.startswith(" output:"):
return text.replace("output:", "[bold default]output:[/bold default]").rstrip()
if text.startswith(" log:"):
return text.replace("log:", "[bold default]log:[/bold default]").rstrip()
if text.startswith(" conda-env:"):
return text.replace("conda-env:", "[bold default]conda-env:[/bold default]").rstrip()
if text.startswith(" container:"):
return text.replace("container:", "[bold default]container:[/bold default]").rstrip()
if text.startswith(" shell:"):
return text.replace("shell:", "[bold default]shell:[/bold default]").rstrip()
return text.rstrip()

def purge_empty_logs(target_dir):
"""scan target_dir and remove empty files, then scan it again and remove empty directories"""
for logfile in glob.glob(f"{target_dir}/logs/**/*", recursive = True):
Expand Down Expand Up @@ -166,17 +184,18 @@ def launch_snakemake(sm_args, workflow, starttext, outdir, sm_logfile, quiet, su
elif exitcode == 3:
print_onerror(sm_logfile)
while output and not output.endswith("]") and not output.startswith("Shutting down"):
console = Console(stderr = True, tab_size = 4, highlight=False)
if "Exception" in output or "Error" in output:
rprint("[yellow bold]" + output.rstrip(), file = sys.stderr)
console.print("[yellow bold]" + output.rstrip(), overflow = "ignore", crop = False)
output = process.stderr.readline()
continue
if output.startswith("Logfile"):
rprint("[yellow]" + output.rstrip(), file = sys.stderr)
if output.startswith("Logfile") or output.startswith("======"):
console.print("[yellow bold]" + output.rstrip(), overflow = "ignore", crop = False)
output = process.stderr.readline()
continue
if output:
if not output.startswith("Complete log"):
rprint("[red]" + output.replace("\t"," ").rstrip(), file = sys.stderr)
console.print("[red]" + highlight_params(output), overflow = "ignore", crop = False)
if output.startswith("Removing output files of failed job"):
break
output = process.stderr.readline()
Expand Down
4 changes: 2 additions & 2 deletions harpy/_printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from rich.table import Table
from rich.panel import Panel

console = Console()
console = Console(stderr=True)

def print_error(errortitle, errortext):
"""Print a yellow panel with error text"""
Expand Down Expand Up @@ -98,5 +98,5 @@ def print_onsuccess(outdir, summary = None, time = None):
def print_onerror(logfile):
"""Print a red panel with error text. To be used in place of onerror: inside a snakefile. Expects the erroring rule printed after it."""
console.rule("[bold]Workflow Error", style = "red")
console.print(f"The workflow terminated from an error. See the full log for more info:\n[bold]{logfile}[/bold]")
console.print(f"The workflow stopped because of an error. Full workflow log:\n[bold]{logfile}[/bold]")
console.rule("[bold]Where Error Occurred", style = "red")
12 changes: 6 additions & 6 deletions harpy/snakefiles/qc.smk
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,19 @@ if not deconvolve:
log:
serr = outdir + "/logs/fastp/{sample}.log"
params:
static = "--trim_poly_g --cut_right",
minlen = f"--length_required {min_len}",
maxlen = f"--max_len1 {max_len}",
trim_adapters = trim_arg,
dedup = "-D" if dedup else "",
title = lambda wc: f"-R \"{wc.sample} QC Report\"",
extra = extra
threads:
workflow.cores
conda:
f"{envdir}/qc.yaml"
shell:
"""
fastp --trim_poly_g --cut_right {params} --thread {threads} -i {input.fw} -I {input.rv} -o {output.fw} -O {output.rv} -h {output.html} -j {output.json} -R "{wildcards.sample} QC Report" 2> {log.serr}
"""
"fastp {params} --thread {threads} -i {input.fw} -I {input.rv} -o {output.fw} -O {output.rv} -h {output.html} -j {output.json} 2> {log.serr}"
else:
rule fastp:
priority: 100
Expand All @@ -85,19 +85,19 @@ else:
log:
serr = outdir + "/logs/fastp/{sample}.log"
params:
static = "--trim_poly_g --cut_right",
minlen = f"--length_required {min_len}",
maxlen = f"--max_len1 {max_len}",
trim_adapters = trim_arg,
dedup = "-D" if dedup else "",
title = lambda wc: f"-R \"{wc.sample} QC Report\"",
extra = extra
threads:
workflow.cores
conda:
f"{envdir}/qc.yaml"
shell:
"""
fastp --trim_poly_g --cut_right {params} --thread {threads} -i {input.fw} -I {input.rv} --stdout -h {output.html} -j {output.json} -R "{wildcards.sample} QC Report" 2> {log.serr} > {output.fq}
"""
"fastp {params} --thread {threads} -i {input.fw} -I {input.rv} --stdout -h {output.html} -j {output.json} 2> {log.serr} > {output.fq}"

rule deconvolve:
input:
Expand Down

0 comments on commit b2e2796

Please sign in to comment.