diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..6707eac --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,33 @@ + +files: '\.(py|rst|sh)$' +fail_fast: false + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + #- id: check-executables-have-shebangs + - id: check-ast + +- repo: https://github.com/pycqa/flake8 + rev: 6.1.0 + hooks: + - id: flake8 + args: ["-j8", "--ignore=E203,E501,W503,E722", "--max-line-length=120", "--exit-zero"] + +- repo: https://github.com/psf/black + rev: 22.10.0 + hooks: + - id: black + args: ["--line-length=120"] + exclude: E501 + +- repo: https://github.com/pycqa/isort + rev: 5.12.0 + hooks: + - id: isort + args: ["--profile", "black"] # solves conflicts between black and isort + diff --git a/README.rst b/README.rst index a92c1a3..41e26c8 100644 --- a/README.rst +++ b/README.rst @@ -46,7 +46,7 @@ This tool uses a registry so it will work only with resgistered tools, which lis Type:: - versionix --help + versionix --help to get more help like this example: @@ -67,6 +67,7 @@ Changelog ========= ======================================================================== Version Description ========= ======================================================================== +0.2.4 More tools in the registry and added precommit 0.2.3 More tools in the registry 0.2.2 add all tools required by sequana pipelines (oct 2023) 0.2.1 More tools added. diff --git a/pyproject.toml b/pyproject.toml index 730bede..ecb1099 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "versionix" -version = "0.2.3" +version = "0.2.4" description = "Get version of any tools" authors = ["Sequana Team"] license = "BSD-3" diff --git a/test/test_parser.py b/test/test_parser.py index 326ea5f..f4d0a03 100644 --- a/test/test_parser.py +++ b/test/test_parser.py @@ -1,51 +1,52 @@ +import sys + from versionix.parser import get_version as get_version from versionix.scripts import main -import sys - # for testing we do not want to install all those tools/software so # we have set testing=True, in which case some sanity checks and # error won't be raised. # def get_version(standalone): # return get_version_orig(standalone, testing=True) -#The mocker which is set so that when we test the presence of e.G. macs3, which is not installed, -#no error is raise +# The mocker which is set so that when we test the presence of e.G. macs3, which is not installed, +# no error is raise + def test_sequana(fp, mocker): - mocker.patch('shutil.which', return_value="something") + mocker.patch("shutil.which", return_value="something") fp.register(["sequana_coverage", "--version"], stdout=["sequana_coverage, version 0.15.4"]) assert get_version("sequana_coverage") == "0.15.4" def test_macs3(fp, mocker): - mocker.patch('shutil.which', return_value="something") + mocker.patch("shutil.which", return_value="something") fp.register(["macs3", "--version"], stdout=["macs3 3.0.0b1"]) assert get_version("macs3") == "3.0.0b1" def test_kallisto(fp, mocker): - mocker.patch('shutil.which', return_value="something") + mocker.patch("shutil.which", return_value="something") fp.register(["kallisto", "version"], stdout=["kallisto, version 0.48.0"]) assert get_version("kallisto") == "0.48.0" def test_pigz(fp, mocker): # stderr parser - mocker.patch('shutil.which', return_value="something") + mocker.patch("shutil.which", return_value="something") fp.register(["pigz", "--version"], stderr=["pigz 2.4"]) assert get_version("pigz") == "2.4" def test_fastqc(fp, mocker): # stderr parser - mocker.patch('shutil.which', return_value="something") + mocker.patch("shutil.which", return_value="something") fp.register(["fastqc", "--version"], stderr=["fastqc v1.0.0"]) assert get_version("fastqc") == "1.0.0" def _test_bwa(fp, mocker): - mocker.patch('shutil.which', return_value="something") + mocker.patch("shutil.which", return_value="something") fp.register( ["bwa"], stderr=[ @@ -92,7 +93,10 @@ def test_script(fp, mocker): runner.invoke(main, ["--registered"]) runner.invoke(main, ["--stats"]) - runner.invoke(main, ) + runner.invoke( + main, + ) + def test_bedtools_error(fp, mocker): # registered tool but if not installed, should raise a SystemExit error diff --git a/versionix/__init__.py b/versionix/__init__.py index 6e181f6..3edcbd2 100644 --- a/versionix/__init__.py +++ b/versionix/__init__.py @@ -2,5 +2,5 @@ try: version = pkg_resources.require("versionix")[0].version -except: #pragma: no cover +except: # pragma: no cover version = ">=0.1.0" diff --git a/versionix/parser.py b/versionix/parser.py index d312551..0715f3b 100644 --- a/versionix/parser.py +++ b/versionix/parser.py @@ -52,6 +52,6 @@ def get_version(standalone, verbose=True): version = parser(p) return version - except Exception as err: #pragma: no cover + except Exception as err: # pragma: no cover print(err) sys.exit(1) diff --git a/versionix/registry.py b/versionix/registry.py index 0e241c0..cc0bccf 100644 --- a/versionix/registry.py +++ b/versionix/registry.py @@ -12,7 +12,7 @@ # default parser performs stdout.strip() -#v1.5.0 +# v1.5.0 def parser_strip_v(x): return x.stdout.strip("v").strip() @@ -24,6 +24,7 @@ def parser_split_2(x): except IndexError: return x.stderr.split()[1] + # versionix v1.0.0 def parser_split_2_strip_v(x): try: @@ -31,72 +32,34 @@ def parser_split_2_strip_v(x): except IndexError: return x.stderr.split()[1][1:] + # versionix version 1.0.0 parser_split_3 = lambda x: x.stdout.split()[2] metadata = { - "apptainer": { - "options": "version" - }, - "bamtools": { - "options": "--version", - "parser": parser_split_2 - }, + "apptainer": {"options": "version"}, + "bamtools": {"options": "--version", "parser": parser_split_2}, "bcl2fastq": { "options": "--version", - "parser": lambda data: [x.split()[1][1:] for x in data.stderr.split("\n") if x.startswith("bcl2fastq")][0] - }, - "bedtools": { - "options": "--version", - "parser": parser_split_2_strip_v - }, - "blastn": { - "options": "-version", - "parser": parser_split_2 - }, - "blastp": { - "options": "-version", - "parser": parser_split_2 - }, - "blastx": { - "options": "-version", - "parser": parser_split_2 - }, - "bowtie": { - "options": "--version", - "parser": parser_split_3 - }, - "bowtie2": { - "options": "--version", - "parser": parser_split_3 + "parser": lambda data: [x.split()[1][1:] for x in data.stderr.split("\n") if x.startswith("bcl2fastq")][0], }, - "bwa": { - "parser": lambda x: x.stderr.strip().split("\n")[1].split()[1] - }, - #"canu": { + "bedtools": {"options": "--version", "parser": parser_split_2_strip_v}, + "blastn": {"options": "-version", "parser": parser_split_2}, + "blastp": {"options": "-version", "parser": parser_split_2}, + "blastx": {"options": "-version", "parser": parser_split_2}, + "bowtie": {"options": "--version", "parser": parser_split_3}, + "bowtie2": {"options": "--version", "parser": parser_split_3}, + "bwa": {"parser": lambda x: x.stderr.strip().split("\n")[1].split()[1]}, + # "canu": { # "options": , - # "parser": - #}, - "checkm": { - "options": "", - "parser": lambda x: x.stdout.split()[2][1:] - }, - "circlator": { - "options": "version", - "parser": lambda x: x.stdout.strip() - }, - "ccs": { - "options": "--version", - "parser": parser_split_2 - }, - "cutadapt": { - "options": "--version" - }, - "deeptools": { - "options": "--version", - "parser": parser_split_2 - }, + # "parser": + # }, + "checkm": {"options": "", "parser": lambda x: x.stdout.split()[2][1:]}, + "circlator": {"options": "version", "parser": lambda x: x.stdout.strip()}, + "ccs": {"options": "--version", "parser": parser_split_2}, + "cutadapt": {"options": "--version"}, + "deeptools": {"options": "--version", "parser": parser_split_2}, "DESeq2": { "caller": "Rscript -e \"library(DESeq2)\\npackageVersion('DESeq2')\"", "parser": lambda x: x.stdout.split()[1].strip("’‘"), @@ -105,182 +68,76 @@ def parser_split_2_strip_v(x): "options": "-V", "parser": lambda x: x.stderr.split()[4].strip(), }, - "falco": { - "options": "--version", - "parser": parser_split_2 - }, - "fastqc": { - "options": "--version", - "parser": parser_split_2_strip_v - }, - "fastp": { - "options": "--version", - "parser": parser_split_2 - }, + "falco": {"options": "--version", "parser": parser_split_2}, + "fastqc": {"options": "--version", "parser": parser_split_2_strip_v}, + "fastp": {"options": "--version", "parser": parser_split_2}, "featureCounts": { "options": "-v", - "parser": lambda x: x.stderr.split("\n")[1].split()[1][1:], + "parser": lambda x: x.stderr.split("\n")[1].split()[1][1:], }, "filter-abund.py": { "options": "--version", - "parser": lambda x: [y.split()[1] for y in x.stderr.split("\n") if y.startswith("khmer")][0] + "parser": lambda x: [y.split()[1] for y in x.stderr.split("\n") if y.startswith("khmer")][0], }, "flye": { "options": "--version", }, - "freebayes": { - "options": "--version", - "parser": parser_split_2_strip_v - }, - "gffread": { - "options": "--version" - }, - #"hifiasm": { + "freebayes": {"options": "--version", "parser": parser_split_2_strip_v}, + "gffread": {"options": "--version"}, + # "hifiasm": { # "options": , - # "parser": - #}, - "idr": { - "options": "--version", - "parser": lambda x: x.stdout.split("\n")[0].split()[1] - }, + # "parser": + # }, + "idr": {"options": "--version", "parser": lambda x: x.stdout.split("\n")[0].split()[1]}, "igvtools": { "options": "version", - "parser": lambda data: [x.split()[2] for x in data.stdout.split("\n") if x.startswith("IGV Version")][0] - }, - "jellyfish": { - "options": "--version", - "parser": parser_split_2 - }, - "kallisto": { - "options": "version", - "parser": parser_split_3 - }, - "kraken2": { - "options": "--version", - "parser": parser_split_3 - }, - "ktImportText": { - "options": "", - "parser": lambda x: x.stdout.split("\n")[1].split()[2] - }, - "liftoff": { - "options": "--version", - "parser": parser_strip_v + "parser": lambda data: [x.split()[2] for x in data.stdout.split("\n") if x.startswith("IGV Version")][0], }, + "jellyfish": {"options": "--version", "parser": parser_split_2}, + "kallisto": {"options": "version", "parser": parser_split_3}, + "kraken2": {"options": "--version", "parser": parser_split_3}, + "ktImportText": {"options": "", "parser": lambda x: x.stdout.split("\n")[1].split()[2]}, + "liftoff": {"options": "--version", "parser": parser_strip_v}, "macs3": { "options": "--version", "parser": parser_split_2, }, - "mafft": { - "options": "--version", - "parser": lambda x: x.stderr.split()[0][1:] - }, - "minimap2": { - "options": "--version" - }, - "multiqc": { - "options": "--version", - "parser": parser_split_3 - }, + "mafft": {"options": "--version", "parser": lambda x: x.stderr.split()[0][1:]}, + "minimap2": {"options": "--version"}, + "multiqc": {"options": "--version", "parser": parser_split_3}, "normalize-by-median.py": { "options": "--version", - "parser": lambda x: [y.split()[1] for y in x.stderr.split("\n") if y.startswith("khmer")][0] - }, - "pbindex": { - "options": "--version", - "parser": parser_split_2 - }, - "picard": { - "options": "SortVcf --version", - "parser": lambda x: x.stderr.split("\n")[1].split(":")[1].split("-")[0] - }, - "pigz": { - "options": "--version", - "parser": parser_split_2 - }, - "plotCorrelation": { - "options": "--version", - "parser": parser_split_2 - }, - "plotFingerprint": { - "options": "--version", - "parser": parser_split_2 - }, - "prokka": { - "options": "--version", - "parser": parser_split_2 - }, - "pycoQC": { - "options": "--version", - "parser": parser_split_2_strip_v - }, - "quast": { - "options": "", - "parser": lambda x: x.stderr.split("\n")[1].split()[1] - }, - "quast.py": { - "options": "", - "parser": lambda x: x.stderr.split("\n")[1].split()[1] - }, - "salmon": { - "options": "--version", - "parser": parser_split_2 - }, - "sambamba": { - "options": "--version", - "parser": lambda x: x.stderr.split()[1] - }, - "samtools": { - "options": "--version", - "parser": parser_split_2 - }, - "seqtk": { - "parser": lambda x: x.stderr.split("\n")[2].split()[1] - }, - "seqkit": { - "options": "version", - "parser": parser_split_2_strip_v - }, - "sequana": { - "options": "--version", - "parser": parser_split_3 - }, - "sequana_coverage": { - "options": "--version", - "parser": parser_split_3 - }, - "sequana_taxonomy": { - "options": "--version", - "parser": parser_split_3 - }, - "sequana_pipeotools": { - "options": "--version", - "parser": parser_split_3 - }, - "singularity": { - "options": "version" - }, - "spades.py": { - "options": "--version", - "parser": parser_split_2_strip_v - }, + "parser": lambda x: [y.split()[1] for y in x.stderr.split("\n") if y.startswith("khmer")][0], + }, + "pbindex": {"options": "--version", "parser": parser_split_2}, + "picard": {"options": "SortVcf --version", "parser": lambda x: x.stderr.split("\n")[1].split(":")[1].split("-")[0]}, + "pigz": {"options": "--version", "parser": parser_split_2}, + "plotCorrelation": {"options": "--version", "parser": parser_split_2}, + "plotFingerprint": {"options": "--version", "parser": parser_split_2}, + "prokka": {"options": "--version", "parser": parser_split_2}, + "pycoQC": {"options": "--version", "parser": parser_split_2_strip_v}, + "quast": {"options": "", "parser": lambda x: x.stderr.split("\n")[1].split()[1]}, + "quast.py": {"options": "", "parser": lambda x: x.stderr.split("\n")[1].split()[1]}, + "salmon": {"options": "--version", "parser": parser_split_2}, + "sambamba": {"options": "--version", "parser": lambda x: x.stderr.split()[1]}, + "samtools": {"options": "--version", "parser": parser_split_2}, + "seqtk": {"parser": lambda x: x.stderr.split("\n")[2].split()[1]}, + "seqkit": {"options": "version", "parser": parser_split_2_strip_v}, + "sequana": {"options": "--version", "parser": parser_split_3}, + "sequana_coverage": {"options": "--version", "parser": parser_split_3}, + "sequana_taxonomy": {"options": "--version", "parser": parser_split_3}, + "sequana_pipeotools": {"options": "--version", "parser": parser_split_3}, + "singularity": {"options": "version"}, + "spades.py": {"options": "--version", "parser": parser_split_2_strip_v}, "split-paired-reads.py": { "options": "--version", - "parser": lambda x: [y.split()[1] for y in x.stderr.split("\n") if y.startswith("khmer")][0] - }, - "STAR": { - "options": "--version" - }, - "snpEff": { - "options": "-version", - "parser": parser_split_2 + "parser": lambda x: [y.split()[1] for y in x.stderr.split("\n") if y.startswith("khmer")][0], }, + "STAR": {"options": "--version"}, + "snpEff": {"options": "-version", "parser": parser_split_2}, "syri": { "options": "--version", - #"parser": parser_split_2 - }, - "vt": { - "options": "--version", - "parser": parser_split_2_strip_v + # "parser": parser_split_2 }, + "vt": {"options": "--version", "parser": parser_split_2_strip_v}, } diff --git a/versionix/scripts.py b/versionix/scripts.py index 2f79d58..0732c2b 100755 --- a/versionix/scripts.py +++ b/versionix/scripts.py @@ -20,14 +20,13 @@ # If not, see . # ########################################################################### """.. rubric:: Standalone application dedicated to Damona""" -import rich_click as click import sys +import rich_click as click from versionix import version from versionix.parser import get_version - __all__ = ["main"] CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) @@ -59,15 +58,19 @@ def main(**kwargs): """ if kwargs["stats"]: from versionix.registry import metadata - click.echo(f"There are currently {len(metadata.keys())} registered tools in Versionix") + + click.echo(f"There are currently {len(metadata.keys())} registered tools in Versionix") elif kwargs["registered"]: from versionix.registry import metadata + names = sorted(metadata.keys()) for name in names: - click.echo(f"{name}") + click.echo(f"{name}") else: if kwargs["standalone"] is None: - click.echo("No standalone was provided. You must provide one. You can use --registered to see the current list'") + click.echo( + "No standalone was provided. You must provide one. You can use --registered to see the current list'" + ) sys.exit(1) else: click.echo(get_version(kwargs["standalone"]))