From fc3c6eef97be5ad42671c8d4f9cf5cbffbbe3b90 Mon Sep 17 00:00:00 2001 From: Matthias Bernt Date: Sun, 18 Apr 2021 22:18:14 +0200 Subject: [PATCH 1/6] grep: add option to keep header https://github.com/galaxyproject/tools-iuc/issues/3511 --- tools/filters/grep.py | 9 ++++++++- tools/filters/grep.xml | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/tools/filters/grep.py b/tools/filters/grep.py index fad39281aac..15cc6342e94 100644 --- a/tools/filters/grep.py +++ b/tools/filters/grep.py @@ -44,6 +44,7 @@ def main(): print(" -o Output file") print(" -pattern RegEx pattern") print(" -v true or false (Invert match)") + print(" --keep_header true or false (keep header)") return 0 outputfile = opts.get("-o") @@ -66,6 +67,10 @@ def main(): print("RegEx pattern not specified.") return -4 + keep_header = opts.get("--keep_header") + if keep_header is None: + print("keep header not specified.") + return -5 # All inputs have been specified at this point, now validate. # replace if input has been escaped, remove sq @@ -121,7 +126,9 @@ def main(): open(pattern_file_name, 'w').write(pattern) # generate grep command - commandline = "grep %s %s -f %s %s > %s" % (versionflag, invertflag, pattern_file_name, inputfile, outputfile) + if keep_header == "true": + commandline = "head -n 1 %s > %s" % (inputfile, outputfile) + commandline += "grep %s %s -f %s %s >> %s" % (versionflag, invertflag, pattern_file_name, inputfile, outputfile) # run grep errorcode = subprocess.call(commandline, shell=True) diff --git a/tools/filters/grep.xml b/tools/filters/grep.xml index c904bb4c769..f83c2b6bfd1 100644 --- a/tools/filters/grep.xml +++ b/tools/filters/grep.xml @@ -1,9 +1,9 @@ - + lines that match an expression operation_3695 - grep.py -i $input -o $out_file1 -pattern '$pattern' -v $invert + grep.py -i $input -o $out_file1 -pattern '$pattern' -v $invert --keep_header $keep_header @@ -20,6 +20,7 @@ + @@ -31,6 +32,20 @@ + + + + + + + + + + + + + + CCDS989.1_cds_0_0_chr1_147962193_r From d1e3edfb689229cb689c595cce57bd195ca50775 Mon Sep 17 00:00:00 2001 From: Matthias Bernt Date: Mon, 19 Apr 2021 13:57:57 +0200 Subject: [PATCH 2/6] consider header in tail/head wrapper and remove pl wrapper --- tools/filters/headWrapper.pl | 18 ------------------ tools/filters/headWrapper.xml | 32 +++++++++++++++++++++++++++++--- tools/filters/tailWrapper.pl | 19 ------------------- tools/filters/tailWrapper.xml | 35 +++++++++++++++++++++++++++++++---- 4 files changed, 60 insertions(+), 44 deletions(-) delete mode 100644 tools/filters/headWrapper.pl delete mode 100644 tools/filters/tailWrapper.pl diff --git a/tools/filters/headWrapper.pl b/tools/filters/headWrapper.pl deleted file mode 100644 index 89aa006fb5a..00000000000 --- a/tools/filters/headWrapper.pl +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/env perl - -use strict; -use warnings; - -# a wrapper for head for use in galaxy -# headWrapper.pl [filename] [# lines to show] [output] - -die "Check arguments" unless @ARGV == 3; -die "Line number must be an integer\n" unless $ARGV[1]=~ m/^\d+$/; - -open (OUT, ">$ARGV[2]") or die "Cannot create $ARGV[2]:$!\n"; -open (HEAD, "head -n $ARGV[1] $ARGV[0]|") or die "Cannot run head:$!\n"; -while () { - print OUT; -} -close OUT; -close HEAD; diff --git a/tools/filters/headWrapper.xml b/tools/filters/headWrapper.xml index 477f1f77684..fc366042b4a 100644 --- a/tools/filters/headWrapper.xml +++ b/tools/filters/headWrapper.xml @@ -4,11 +4,21 @@ operation_3695 -perl '$__tool_directory__/headWrapper.pl' '$input' $lineNum '$out_file1' + set -eo pipefail; + ( + #if $header + head -n 1 '$input' && + tail -n +1 '$input' + #else + cat '$input' + #end if + | head -n 1 $lineNum + ) > '$out_file1' - + + @@ -17,7 +27,23 @@ perl '$__tool_directory__/headWrapper.pl' '$input' $lineNum '$out_file1' - + + + + + + + + + + + + + + + + + diff --git a/tools/filters/tailWrapper.pl b/tools/filters/tailWrapper.pl deleted file mode 100644 index 35e7d4ee51c..00000000000 --- a/tools/filters/tailWrapper.pl +++ /dev/null @@ -1,19 +0,0 @@ -#! /usr/bin/env perl - -use strict; -use warnings; - -# a wrapper for tail for use in galaxy -# lessWrapper.pl [filename] [# lines to show] [output] - -die "Check arguments" unless @ARGV == 3; -die "Line number should be an integer\n" unless $ARGV[1]=~ m/^\d+$/; - -open (OUT, ">$ARGV[2]") or die "Cannot create $ARGV[2]:$!\n"; -open (TAIL, "tail -n $ARGV[1] $ARGV[0]|") or die "Cannot run tail:$!\n"; -while () { - print OUT; -} -close OUT; -close TAIL; - diff --git a/tools/filters/tailWrapper.xml b/tools/filters/tailWrapper.xml index 166018ec1d2..f9fd67adb59 100644 --- a/tools/filters/tailWrapper.xml +++ b/tools/filters/tailWrapper.xml @@ -1,10 +1,21 @@ lines from a dataset - -perl '$__tool_directory__/tailWrapper.pl' '$input' $lineNum '$out_file1' + '$out_file1' + ]]> - + + @@ -13,7 +24,23 @@ perl '$__tool_directory__/tailWrapper.pl' '$input' $lineNum '$out_file1' - + + + + + + + + + + + + + + + + + From 8cc1c3bc0fb02d8501227336e7525f4ad298c8a5 Mon Sep 17 00:00:00 2001 From: Matthias Bernt Date: Mon, 3 May 2021 13:15:08 +0200 Subject: [PATCH 3/6] some updates for grep, tail, head - CDATA for all - exit code - remove interpreter - bump versions - and add the tools to WORKFLOW_SAFE_TOOL_VERSION_UPDATES --- lib/galaxy/tools/__init__.py | 3 +++ tools/filters/grep.xml | 4 +++- tools/filters/headWrapper.xml | 4 ++-- tools/filters/tailWrapper.xml | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index 058cfb901c8..32e09407a33 100644 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -197,6 +197,9 @@ WORKFLOW_SAFE_TOOL_VERSION_UPDATES = { '__BUILD_LIST__': safe_update(packaging.version.parse("1.0.0"), packaging.version.parse("1.0.1")), '__APPLY_RULES__': safe_update(packaging.version.parse("1.0.0"), packaging.version.parse("1.1.0")), '__EXTRACT_DATASET__': safe_update(packaging.version.parse("1.0.0"), packaging.version.parse("1.0.1")), + 'Grep1': safe_update(packaging.version.parse("1.0.1"), packaging.version.parse("1.0.2")), + 'Show beginning1': safe_update(packaging.version.parse("1.0.0"), packaging.version.parse("1.0.1")), + 'Show tail1': safe_update(packaging.version.parse("1.0.0"), packaging.version.parse("1.0.1")), } diff --git a/tools/filters/grep.xml b/tools/filters/grep.xml index f83c2b6bfd1..443036e4dab 100644 --- a/tools/filters/grep.xml +++ b/tools/filters/grep.xml @@ -3,7 +3,9 @@ operation_3695 - grep.py -i $input -o $out_file1 -pattern '$pattern' -v $invert --keep_header $keep_header + diff --git a/tools/filters/headWrapper.xml b/tools/filters/headWrapper.xml index fc366042b4a..c3bb077647d 100644 --- a/tools/filters/headWrapper.xml +++ b/tools/filters/headWrapper.xml @@ -3,7 +3,7 @@ operation_3695 - + '$out_file1' - + ]]> diff --git a/tools/filters/tailWrapper.xml b/tools/filters/tailWrapper.xml index f9fd67adb59..e37516b5828 100644 --- a/tools/filters/tailWrapper.xml +++ b/tools/filters/tailWrapper.xml @@ -1,4 +1,4 @@ - + lines from a dataset Date: Tue, 4 May 2021 10:49:23 +0200 Subject: [PATCH 4/6] remove python wrapper for grep tool and fix cli (`-n +2`) for head, tail, grep --- tools/filters/grep.py | 144 ---------------------------------- tools/filters/grep.xml | 40 +++++++--- tools/filters/headWrapper.xml | 13 ++- tools/filters/tailWrapper.xml | 2 +- 4 files changed, 34 insertions(+), 165 deletions(-) delete mode 100644 tools/filters/grep.py diff --git a/tools/filters/grep.py b/tools/filters/grep.py deleted file mode 100644 index 15cc6342e94..00000000000 --- a/tools/filters/grep.py +++ /dev/null @@ -1,144 +0,0 @@ -# Filename: grep.py -# Author: Ian N. Schenck -# Version: 8/23/2005 -# -# This script accepts regular expressions, as well as an "invert" -# option, and applies the regular expression using grep. This wrapper -# provides security and pipeline. -# -# Grep is launched based on these inputs: -# -i Input file -# -o Output file -# -pattern RegEx pattern -# -v true or false (output NON-matching lines) -from __future__ import print_function - -import os -import re -import subprocess -import sys -from subprocess import PIPE, Popen -from tempfile import NamedTemporaryFile - - -# This function is exceedingly useful, perhaps package for reuse? -def getopts(argv): - opts = {} - while argv: - if argv[0][0] == '-': - opts[argv[0]] = argv[1] - argv = argv[2:] - else: - argv = argv[1:] - return opts - - -def main(): - args = sys.argv[1:] - - try: - opts = getopts(args) - except IndexError: - print("Usage:") - print(" -i Input file") - print(" -o Output file") - print(" -pattern RegEx pattern") - print(" -v true or false (Invert match)") - print(" --keep_header true or false (keep header)") - return 0 - - outputfile = opts.get("-o") - if outputfile is None: - print("No output file specified.") - return -1 - - inputfile = opts.get("-i") - if inputfile is None: - print("No input file specified.") - return -2 - - invert = opts.get("-v") - if invert is None: - print("Match style (Invert or normal) not specified.") - return -3 - - pattern = opts.get("-pattern") - if pattern is None: - print("RegEx pattern not specified.") - return -4 - - keep_header = opts.get("--keep_header") - if keep_header is None: - print("keep header not specified.") - return -5 - # All inputs have been specified at this point, now validate. - - # replace if input has been escaped, remove sq - # characters that are allowed but need to be escaped - mapped_chars = {'>': '__gt__', - '<': '__lt__', - '\'': '__sq__', - '"': '__dq__', - '[': '__ob__', - ']': '__cb__', - '{': '__oc__', - '}': '__cc__'} - - # with new sanitizing we only need to replace for single quote, - # but this needs to remain for backwards compatibility - for key, value in mapped_chars.items(): - pattern = pattern.replace(value, key) - - # match filename and invert flag - fileRegEx = re.compile(r"^[A-Za-z0-9./\-_]+$") - invertRegEx = re.compile(r"(true)|(false)") - - # verify that filename and inversion flag are in the correct format - if not fileRegEx.match(outputfile): - print("Illegal output filename.") - return -5 - if not fileRegEx.match(inputfile): - print("Illegal input filename.") - return -6 - if not invertRegEx.match(invert): - print("Illegal invert option.") - return -7 - - # invert grep search? - if invert == "true": - invertflag = "-v" - print("Not matching pattern: %s" % pattern) - else: - invertflag = "" - print("Matching pattern: %s" % pattern) - - # set version flag - versionflag = "-P" - - # MacOS 10.8.2 does not support -P option for perl-regex anymore - versionmatch = Popen("grep -V | grep 'BSD'", shell=True, stdout=PIPE).communicate()[0] - if versionmatch: - versionflag = "-E" - - # create temp file holding pattern - # by using a file to hold the pattern, we don't have worry about sanitizing grep commandline and can include single quotes in pattern - pattern_file_name = NamedTemporaryFile().name - open(pattern_file_name, 'w').write(pattern) - - # generate grep command - if keep_header == "true": - commandline = "head -n 1 %s > %s" % (inputfile, outputfile) - commandline += "grep %s %s -f %s %s >> %s" % (versionflag, invertflag, pattern_file_name, inputfile, outputfile) - - # run grep - errorcode = subprocess.call(commandline, shell=True) - - # remove temp pattern file - os.unlink(pattern_file_name) - - # return error code - return errorcode - - -if __name__ == "__main__": - main() diff --git a/tools/filters/grep.xml b/tools/filters/grep.xml index 443036e4dab..0d26a090a34 100644 --- a/tools/filters/grep.xml +++ b/tools/filters/grep.xml @@ -4,39 +4,45 @@ operation_3695 '$out_file1' && + tail -n +2 '$input' + #else + cat '$input' + #end if + | grep -f '$pattern_file' $invert > '$out_file1' ]]> + + $pattern + - - + + - - - - - + - + - + @@ -45,9 +51,17 @@ - - - CCDS989.1_cds_0_0_chr1_147962193_r + + + + + + + + + + + diff --git a/tools/filters/headWrapper.xml b/tools/filters/headWrapper.xml index c3bb077647d..0b20f766207 100644 --- a/tools/filters/headWrapper.xml +++ b/tools/filters/headWrapper.xml @@ -1,19 +1,18 @@ - + lines from a dataset operation_3695 '$out_file1' && + tail -n +2 '$input' #else cat '$input' #end if - | head -n 1 $lineNum - ) > '$out_file1' + | head -n $lineNum + >> '$out_file1' ]]> @@ -21,7 +20,7 @@ - + diff --git a/tools/filters/tailWrapper.xml b/tools/filters/tailWrapper.xml index e37516b5828..fcf20fa43b9 100644 --- a/tools/filters/tailWrapper.xml +++ b/tools/filters/tailWrapper.xml @@ -5,7 +5,7 @@ ( #if $header head -n 1 '$input' && - tail -n +1 '$input' + tail -n +2 '$input' #else cat '$input' #end if From 181b862250b03be41742ec802a7b083551bfc971 Mon Sep 17 00:00:00 2001 From: M Bernt Date: Tue, 4 May 2021 13:47:29 +0200 Subject: [PATCH 5/6] Apply suggestions from code review - add profile - add requirement Co-authored-by: Marius van den Beek --- tools/filters/grep.xml | 5 ++++- tools/filters/headWrapper.xml | 5 ++++- tools/filters/tailWrapper.xml | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/filters/grep.xml b/tools/filters/grep.xml index 0d26a090a34..d94fc62677e 100644 --- a/tools/filters/grep.xml +++ b/tools/filters/grep.xml @@ -1,4 +1,7 @@ - + + + grep + lines that match an expression operation_3695 diff --git a/tools/filters/headWrapper.xml b/tools/filters/headWrapper.xml index 0b20f766207..30776b148ac 100644 --- a/tools/filters/headWrapper.xml +++ b/tools/filters/headWrapper.xml @@ -1,8 +1,11 @@ - + lines from a dataset operation_3695 + + coreutils + + lines from a dataset + + coreutils + Date: Tue, 4 May 2021 14:59:23 +0200 Subject: [PATCH 6/6] fix test 3 and error detection only error for exit code > 1: --- tools/filters/grep.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/filters/grep.xml b/tools/filters/grep.xml index 0d26a090a34..b2ff78cbc34 100644 --- a/tools/filters/grep.xml +++ b/tools/filters/grep.xml @@ -3,7 +3,10 @@ operation_3695 - + + + '$out_file1' && @@ -54,7 +57,7 @@ - +