diff --git a/.github/filters.yml b/.github/filters.yml index ffee38109..24d98825d 100644 --- a/.github/filters.yml +++ b/.github/filters.yml @@ -164,7 +164,8 @@ assembly: &assembly - 'harpy/snakefiles/assembly.smk' - 'harpy/snakefiles/metassembly.smk' other: &other - - 'harpy/stitchparams.py' + - *common + - 'harpy/imputeparams.py' - 'harpy/popgroup.py' - 'harpy/hpc.py' modules: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 15306f65d..6e5c8d329 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -822,9 +822,9 @@ jobs: resources/buildforCI.sh - name: Clear Space uses: jlumbroso/free-disk-space@main - - name: harpy stitchparams + - name: harpy imputeparams shell: micromamba-shell {0} - run: harpy stitchparams -o params.file + run: harpy imputeparams -o params.file - name: harpy popgroup shell: micromamba-shell {0} run: harpy popgroup test/fastq diff --git a/harpy/__main__.py b/harpy/__main__.py index d7c89baa2..1ef421d33 100644 --- a/harpy/__main__.py +++ b/harpy/__main__.py @@ -16,8 +16,9 @@ from . import simulate from . import snp from . import sv -from .popgroups import popgroup +from .popgroup import popgroup from .imputeparams import imputeparams +from . import view click.rich_click.USE_MARKDOWN = True click.rich_click.SHOW_ARGUMENTS = False @@ -44,6 +45,7 @@ def cli(): # main program cli.add_command(popgroup) cli.add_command(imputeparams) +cli.add_command(view.view) cli.add_command(preflight.preflight) cli.add_command(demultiplex.demultiplex) cli.add_command(qc.qc) @@ -70,7 +72,7 @@ def cli(): }, { "name": "Other Commands", - "commands": sorted(["deconvolve", "hpc", "imputeparams", "popgroup","preflight","resume"]) + "commands": sorted(["deconvolve", "hpc", "imputeparams", "popgroup","preflight","resume", "view"]) } ], } | simulate.commandstring | hpc.docstring diff --git a/harpy/popgroups.py b/harpy/popgroup.py similarity index 100% rename from harpy/popgroups.py rename to harpy/popgroup.py diff --git a/harpy/view.py b/harpy/view.py new file mode 100644 index 000000000..48b2f1c8e --- /dev/null +++ b/harpy/view.py @@ -0,0 +1,72 @@ +"""View the latest log or snakefile of a workflow""" + +import os +import sys +import glob +import subprocess +import rich_click as click +from ._printing import print_error +from ._validations import is_gzip + +@click.command(no_args_is_help = True, context_settings=dict(allow_interspersed_args=False)) +@click.option('-s', '--snakefile', is_flag = True, show_default = True, default = False, help = "View the snakefile, not the log file") +@click.argument('directory', required=True, type=click.Path(exists=True, file_okay=False)) +def view(directory, snakefile): + """ + View a workflow log file or snakefile + + This convenience command lets you view the latest workflow log file + of a Harpy output directory. You can use `--snakefile` to view the workflow + snakefile instead. Output is printed to the screen via `less` and + accepts the typical keyboard shortcuts to navigate the output, e.g.: + + | key | function | + | :---------------------- | :------------------------- | + | `up arrow`/`down arrow` | scroll up/down | + | `Page Up`/`Page Down` | scroll up/down, but faster | + | `q` | exit | + """ + # check if there is a workflow or log folder + # and whether the expected files are in there + err = 0 + if snakefile: + files = [i for i in glob.iglob(f"{directory}/workflow/*.smk")] + err_dir = f"{directory}/workflow/" + err_file = "snakefiles" + if not os.path.exists(f"{directory}/workflow"): + err = 1 + elif not files: + err = 2 + else: + files = [i for i in glob.iglob(f"{directory}/logs/snakemake/*.log*")] + err_dir = f"{directory}/logs/snakemake/" + err_file = "log files" + if not os.path.exists(f"{directory}/logs/snakemake"): + err = 1 + elif not files: + err = 2 + if err == 1: + print_error( + "Directory not found", + f"The file you are trying to view is expected to be in [blue]{err_dir}[/blue], but that directory was not found. Please check that this is the correct folder." + ) + sys.exit(1) + elif err == 2: + print_error( + "File not found", + f"There are no {err_file} in [blue]{err_dir}[/blue]. Please check that this is the correct folder." + ) + sys.exit(1) + # sort and pull only the most recent file (based on modification time) + file = sorted(files, key = os.path.getmtime)[-1] + if not os.access(file, os.R_OK): + print_error( + "Incorrect permissions", + f"[blue]{file}[/blue] does not have read access. Please check the file permissions." + ) + sys.exit(1) + + cat_cmd = "zcat" if is_gzip(file) else "cat" + stream = subprocess.Popen([cat_cmd, file], stdout=subprocess.PIPE) + pygment = subprocess.Popen(["pygmentize", "-l", "yaml"], stdin = stream.stdout, stdout = subprocess.PIPE) + subprocess.run(["less", "-R"], stdin = pygment.stdout) diff --git a/pyproject.toml b/pyproject.toml index 4f8a5e2df..610f9ba8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,8 @@ readme = {file = "README.md", content-type = "text/markdown"} license = {text = "GPL-3.0"} [tool.setuptools.packages.find] -where = ["."] +include = ["harpy"] +exclude = ["test"] [tool.setuptools.package-data] "*" = ["*.*"] @@ -22,7 +23,5 @@ where = ["."] [project.scripts] harpy = "harpy.__main__:cli" -[tool.setuptools_scm] - [project.urls] Homepage = "https://github.com/pdimens/harpy" diff --git a/resources/buildlocal.sh b/resources/buildlocal.sh index 3eadbd8a2..042e1aeeb 100755 --- a/resources/buildlocal.sh +++ b/resources/buildlocal.sh @@ -12,8 +12,8 @@ mkdir -p ${CONDA_PREFIX}/bin g++ harpy/bin/extractReads.cpp -O3 -o ${CONDA_PREFIX}/bin/extractReads # install harpy proper -pip install . --no-deps && \ - rm -r build harpy.egg-info +pip install --no-deps --disable-pip-version-check -e . && \ + rm -rf build #harpy.egg-info # associated scripts chmod +x harpy/bin/*