Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slight updates for the options (trimming) #97

Merged
merged 1 commit into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 288,9 @@ Changelog
========= ======================================================================
Version Description
========= ======================================================================
0.16.7 * add missing --trimming-quality option in list of TrimmingOption
* set default to cutadatp if no fastp available
* better UI for the completion script.
0.16.6 * Set default value for the option trimming to 20
* Fix issue https://github.com/sequana/sequana_pipetools/issues/85
0.16.5 * merge completion standalone into main sequana_pipetools application
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 6,7 @@ build-backend = "poetry.core.masonry.api"
#maintainer ?#maintainer email
[tool.poetry]
name = "sequana_pipetools"
version = "0.16.6"
version = "0.16.7"
description = "A set of tools to help building or using Sequana pipelines"
authors = ["Sequana Team"]
license = "BSD-3"
Expand Down
15 changes: 10 additions & 5 deletions sequana_pipetools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 1,15 @@
import pkg_resources
from importlib import metadata

try:
version = pkg_resources.require("sequana_pipetools")[0].version
except pkg_resources.DistributionNotFound: # pragma: no cover
version = ">=0.2.0"

def get_package_version(package_name):
try:
version = metadata.version(package_name)
return version
except metadata.PackageNotFoundError:
return f"{package_name} not found"


version = get_package_version("sequana_pipetools")

from easydev.logging_tools import Logging

Expand Down
7 changes: 4 additions & 3 deletions sequana_pipetools/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,15 471,15 @@ def __init__(self, input_directory=".", input_pattern="*fastq.gz", add_input_rea
type=click.Path(exists=True, file_okay=False),
# required=True,
show_default=True,
help="""Where to find the FastQ files""",
help="""Where to find the input files""",
),
click.option(
"--input-pattern",
"input_pattern",
default=self.input_pattern,
type=click.STRING,
show_default=True,
help="pattern for the input FastQ files ",
help=f"pattern for the input files ({input_pattern})",
),
]

Expand Down Expand Up @@ -614,6 614,7 @@ class ClickTrimmingOptions:
"--disable-trimming",
"--trimming-cutadapt-mode",
"--trimming-cutadapt-options",
"--trimming-quality",
],
}

Expand All @@ -627,7 628,7 @@ def __init__(self, software=["cutadapt", "atropos", "fastp"], caller=None):
"""

self.software = software
self.software_default = "fastp"
self.software_default = "fastp" if "fastp" in software else software[0]

def quality(x):
x = int(x)
Expand Down
34 changes: 22 additions & 12 deletions sequana_pipetools/scripts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 173,12 @@ def set_option_file(self, option_name):
type=click.STRING,
help="""Name of a pipelines for which you wish to create the completion file. Set to a valid Sequana pipeline name that must be installed""",
)
@click.option("--force", is_flag=True, help="""overwrite files in sequana config pipeline directory""")
@click.option(
"--force",
is_flag=True,
help="""overwrite files in sequana config pipeline directory (used with
--completion)""",
)
@click.option("--stats", is_flag=True, help="""Plot some stats related to the Sequana pipelines (installed)""")
@click.option(
"--config-to-schema",
Expand All @@ -183,7 188,7 @@ def set_option_file(self, option_name):
def main(**kwargs):
"""Pipetools utilities for the Sequana project (sequana.readthedocs.io)

The pipetools package is dedcated to the developers of Sequana pipelines.
The pipetools package is dedicated to the developers of Sequana pipelines.
However, Pipetools provides a set of utilities starting with the completion
script for the different pipeline.

Expand All @@ -200,18 205,23 @@ def main(**kwargs):
click.echo(f"sequana_pipetools v{version}")
return
elif kwargs["completion"]:
if kwargs["force"] is False:
msg = "This will replace files in ./config/sequana/pipelines. " "Do you want to proceed y/n: "
choice = input(msg)
if kwargs["force"] is True:
choice = "y"
else:
msg = "This action will replace files stored in ./config/sequana/pipelines. Do you want to proceed y/n: "
choice = input(msg)
if choice != "y":
sys.exit(0)

name = kwargs["completion"]
try:
c = ClickComplete(name)
c.save_completion_script()
except DistributionNotFound: # pragma: no cover
click.echo(f"# Warning {name} could not be imported. Nothing done")
finally:
click.echo("Please source the files using:: \n")
name = kwargs["completion"]
try:
c = ClickComplete(name)
c.save_completion_script()
click.echo(" source ~/.config/sequana/pipelines/{}.sh".format(name))
except DistributionNotFound: # pragma: no cover
click.echo(f"# Warning {name} could not be imported. Nothing done")
click.echo(" source ~/.config/sequana/pipelines/{}.sh".format(name))
click.echo("\nto activate the completion")
elif kwargs["stats"]:
from sequana_pipetools.snaketools.pipeline_utils import get_pipeline_statistics
Expand Down
9 changes: 4 additions & 5 deletions sequana_pipetools/sequana_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 131,6 @@ def __init__(self):
# the working directory
self.workdir = Path(options.workdir)

# define the data path of the pipeline
# self.datapath = self._get_package_location()

# Set wrappers as attribute so that it may be changed by the
# user/developer
self.sequana_wrappers = os.environ.get(
Expand Down Expand Up @@ -272,7 269,9 @@ def check_input_files(self, stop_on_error=True):
cfg = self.config.config

filenames = glob.glob(cfg.input_directory os.sep cfg.input_pattern)
logger.info(f"Found {len(filenames)} files matching your input pattern ({cfg.input_pattern})")
logger.info(
f"Found {len(filenames)} files matching your input pattern ({cfg.input_pattern}) in {cfg.input_directory}"
)

if len(filenames) == 0:
logger.critical(f"Found no files with your matching pattern ({cfg.input_pattern}) in {cfg.input_directory}")
Expand Down Expand Up @@ -480,7 479,7 @@ def teardown(self, check_schema=True, check_input_files=True):
msg = (
"The version {} of your completion file for the {} pipeline seems older than the installed"
" pipeline itself ({}). Please, consider updating the completion file {}"
" using the following command: \n\t sequana_completion --name {}\n"
" using the following command: \n\t sequana_pipetools --completion {}\n"
"available in the sequana_pipetools package (pip install sequana_completion)"
)
msg = msg.format(version, self.name, self._get_package_version(), completion, self.name)
Expand Down
4 changes: 2 additions & 2 deletions sequana_pipetools/snaketools/file_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 332,7 @@ def _get_file(self, tag, r):
if self.read_tag:
read_tag = self.read_tag.replace("[12]", r)

# changed in v0.8.7 tricky hanbling of sample names
# changed in v0.8.7 tricky hanhling of sample names
# https://github.com/sequana/sequana/issues/576
candidates = [
realpath
Expand Down Expand Up @@ -394,7 394,7 @@ def _get_paired(self):
return False
elif R1 == R2:
return True
else:
else: # pragma: no cover
logger.error("Mix of paired and single-end data sets {}".format(self.pattern))
sys.exit(1)

Expand Down
9 changes: 5 additions & 4 deletions tests/scripts/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 20,11 @@ def test_version():

def test_completion(monkeypatch):

monkeypatch.setattr("builtins.input", lambda x: "y")
runner = CliRunner()
results = runner.invoke(main, ["--completion", "rnaseq"])
assert results.exit_code == 0
# FIXME
# monkeypatch.setattr("builtins.input", lambda x: "y")
# runner = CliRunner()
# results = runner.invoke(main, ["--completion", "rnaseq"])
# assert results.exit_code == 0

runner = CliRunner()
results = runner.invoke(main, ["--completion", "fastqc", "--force"])
Expand Down
6 changes: 6 additions & 0 deletions tests/snaketools/test_filefactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 35,12 @@ def inner_test(ff):
ff.get_file2(ff.tags[0])
assert len(ff) == 1

try:
ff = snaketools.FastQFactory(test_dir "/data/Hm2*fastq.gz", verbose=True, read_tag="dummy[12]")
assert False
except ValueError:
assert True


def test_fastqfactory():
with pytest.raises(ValueError):
Expand Down
66 changes: 43 additions & 23 deletions tests/test_options.py
Original file line number Diff line number Diff line change
@@ -1,19 1,22 @@
import argparse
import pytest
import sys

import pytest

from sequana_pipetools.options import (
before_pipeline,
TrimmingOptions,
SnakemakeOptions,
KrakenOptions,
FeatureCountsOptions,
ClickGeneralOptions,
OptionEatAll
FeatureCountsOptions,
KrakenOptions,
OptionEatAll,
SnakemakeOptions,
TrimmingOptions,
before_pipeline,
)

# for test_click_general_options() to work we need to define a global variable
NAME = "TEST"


def test_misc():

sys.argv.append("--version")
Expand Down Expand Up @@ -79,26 82,29 @@ def test_input_options():

def test_general_options():
from sequana_pipetools.options import GeneralOptions

p = argparse.ArgumentParser()
so = GeneralOptions()
so.add_options(p)
p.parse_args([])


def test_click_general_options():
import rich_click as click

from sequana_pipetools.options import (
ClickGeneralOptions,
ClickSlurmOptions,
ClickSnakemakeOptions,
ClickFeatureCountsOptions,
ClickTrimmingOptions,
ClickGeneralOptions,
ClickInputOptions,
ClickKrakenOptions,
ClickInputOptions,
include_options_from,
init_click)
import rich_click as click
ClickSlurmOptions,
ClickSnakemakeOptions,
ClickTrimmingOptions,
include_options_from,
init_click,
)

init_click("TEST", groups={"test":1})
init_click("TEST", groups={"test": 1})

@click.command()
@include_options_from(ClickGeneralOptions)
Expand All @@ -110,26 116,40 @@ def test_click_general_options():
@include_options_from(ClickTrimmingOptions)
def main(**kwargs):
pass

with pytest.raises(SystemExit):
main(["--help"])

with pytest.raises(SystemExit):
main(["--version"])

# with pytest.raises(ValueError, SystemExit):
# main(["--from-project"])

with pytest.raises(ValueError):
main(["--deps"])


def test_click_option_eat_all():
from click.testing import CliRunner
import ast

import click
@click.option("--databases", "databases",
type=click.STRING,
cls=OptionEatAll,
#callback=check_databases
)
from click.testing import CliRunner

def check_databases(ctx, param, value):
if value:
# click transform the input databases (tuple) into a string
# we need to convert it back to a tuple before checking the databases
values = ast.literal_eval(value)
for db in values:
click.echo(f"{db} used")
return ast.literal_eval(value)

@click.option("--databases", "databases", type=click.STRING, cls=OptionEatAll, callback=check_databases)
def main(**options):
pass

main.name = "root"

runner = CliRunner()
runner.invoke(main, ["--databases", "1", "2"])

Loading