linesieve


Namelinesieve JSON
Version 1.0 PyPI version JSON
download
home_pagehttps://github.com/lemon24/linesieve
SummaryAn unholy blend of grep, sed, awk, and Python.
upload_time2023-04-17 20:16:01
maintainer
docs_urlNone
authorlemon24
requires_python>=3.8
licenseBSD-3-Clause
keywords grep sed awk cli command-line terminal text text processing search replace regex
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
.. default-role:: literal


.. begin-intro

*This is my text munging tool. There are many like it, but this one is mine.*

**linesieve** is an unholy blend of grep, sed, awk, and Python,
born out of spite.

.. end-intro


|build-status-github| |code-coverage| |documentation-status| |pypi-status| |code-style|

.. |build-status-github| image:: https://github.com/lemon24/linesieve/workflows/build/badge.svg
  :target: https://github.com/lemon24/linesieve/actions?query=workflow%3Abuild
  :alt: build status (GitHub Actions)

.. |code-coverage| image:: https://codecov.io/gh/lemon24/linesieve/branch/main/graph/badge.svg?token=MrpEP5cg24
  :target: https://codecov.io/gh/lemon24/linesieve
  :alt: code coverage

.. |documentation-status| image:: https://readthedocs.org/projects/linesieve/badge/?version=latest&style=flat
  :target: https://linesieve.readthedocs.io/en/latest/?badge=latest
  :alt: documentation status

.. |pypi-status| image:: https://img.shields.io/pypi/v/linesieve.svg
  :target: https://pypi.python.org/pypi/linesieve
  :alt: PyPI status

.. |type-checking| image:: http://www.mypy-lang.org/static/mypy_badge.svg
  :target: http://mypy-lang.org/
  :alt: checked with mypy

.. |code-style| image:: https://img.shields.io/badge/code%20style-black-000000.svg
  :target: https://github.com/psf/black
  :alt: code style: black



.. begin-main


Features
--------

`linesieve` allows you to:

* split text input into sections
* apply filters to specific sections
* search and highlight success/failure markers
* match/sub/split with the full power of Python's `re`_
* shorten paths, links and module names
* chain filters into pipelines
* color output!

.. _re: https://docs.python.org/3/library/re.html


Installing
----------

Install and update using `pip`_:

.. code-block:: console

    $ pip install --upgrade linesieve

.. _pip: https://pip.pypa.io/en/stable/getting-started/


A simple example
----------------

.. code-block:: console

    $ ls -1 /* | linesieve -s '.*:' show bin match ^d head -n2
    .....
    /bin:
    dash
    date
    ......
    /sbin:
    disklabel
    dmesg
    ...

This prints the first two files starting with `d`
from each directory whose name contains `bin`
(skipped directories are marked with a dot on stderr).


Links
-----

* PyPI Releases: https://pypi.org/project/linesieve/
* Documentation: https://linesieve.readthedocs.io/
* Issue Tracker: https://github.com/lemon24/linesieve/issues
* Source Code: https://github.com/lemon24/linesieve


.. end-main



Examples
--------

.. begin-examples


Java tracebacks
~~~~~~~~~~~~~~~

Assume you're writing some Java tests with JUnit,
on a project that looks like this:

.. code-block:: text

    .
    ├── src
    │   └── com
    │       └── example
    │           └── someproject
    │               └── somepackage
    │                   └── ThingDoer.java
    └── tst
        └── com
            └── example
                └── someproject
                    └── somepackage
                        └── ThingDoerTest.java

This command:

.. code-block:: bash

    linesieve \
    span -v -X \
        --start '^ (\s+) at \s ( org\.junit\. | \S+ \. reflect\.\S+\.invoke )' \
        --end '^ (?! \s+ at \s )' \
        --repl '\1...' \
    match -v '^\s+at \S+\.(rethrowAs|translateTo)IOException' \
    sub-paths --include '{src,tst}/**/*.java' --modules-skip 1 \
    sub -X '^( \s+ at \s+ (?! .+ \.\. | com\.example\. ) .*? ) \( .*' '\1' \
    sub -X '^( \s+ at \s+ com\.example\. .*? ) \ ~\[ .*' '\1' \
    sub -X '
        (?P<pre> \s+ at \s .*)
        (?P<cls> \w+ )
        (?P<mid> .* \( )
        (?P=cls) \.java
        (?P<suf> : .* )
        ' \
        '\g<pre>\g<cls>\g<mid>\g<suf>'

... shortens this 76 line traceback:

.. code-block:: text

    12:34:56.789 [main] ERROR com.example.someproject.somepackage.ThingDoer - exception while notifying done listener
    java.lang.RuntimeException: listener failed
    	at com.example.someproject.somepackage.ThingDoerTest$DummyListener.onThingDone(ThingDoerTest.java:420) ~[tests/:?]
    	at com.example.someproject.somepackage.ThingDoer.doThing(ThingDoer.java:69) ~[library/:?]
    	at com.example.otherproject.Framework.doAllTheThings(Framework.java:1066) ~[example-otherproject-2.0.jar:2.0]
    	at com.example.someproject.somepackage.ThingDoerTest.listenerException(ThingDoerTest.java:666) ~[tests/:?]
    	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    	...
    	... 60+ more lines of JUnit stuff we don't really care about ...
    	...
    12:34:56.999 [main] INFO done

... to just:

.. code-block:: text

    12:34:56.789 [main] ERROR ..ThingDoer - exception while notifying done listener
    java.lang.RuntimeException: listener failed
    	at ..ThingDoerTest$DummyListener.onThingDone(:420) ~[tests/:?]
    	at ..ThingDoer.doThing(:69) ~[library/:?]
    	at com.example.otherproject.Framework.doAllTheThings(:1066)
    	at ..ThingDoerTest.listenerException(:666) ~[tests/:?]
    	...
    12:34:56.999 [main] INFO done

Let's break that `linesieve` command down a bit:

* The `span` gets rid of all the traceback lines coming from JUnit.
* The `match -v` skips some usually useless lines from stack traces.
* The `sub-paths` shortens and highlights the names of classes in the current project;
  `com.example.someproject.somepackage.ThingDoer` becomes `..ThingDoer`
  (presumably that's enough info to open the file).
* The first `sub` gets rid of line numbers and JAR names for everything
  that is not either in the current project or in another `com.example.` package.
* The second `sub` gets rid of JAR names for things in other `com.example.` packages.
* The third `sub` gets rid of the source file name;
  `..ThingDoer.doThing(ThingDoer.java:69)` becomes `..ThingDoer.doThing(:69)`
  (the file name matches the class name).


Apache Ant output
~~~~~~~~~~~~~~~~~

Let's look at why `linesieve` was born in the first place
– cleaning up Apache Ant output.

We'll use Ant's own test output as an example,
since it `builds itself`_.

.. _builds itself: https://github.com/apache/ant/tree/ff62ff7151bbc84a7706f40988258fabbcc324f5


Running a single test with:

.. code-block:: bash

    ant junit-single-test -Djunit.testcase=org.apache.tools.ant.ProjectTest

... produces 77 lines of output:

.. code-block:: text

    Buildfile: /Users/lemon/code/ant/build.xml

    check-optional-packages:

    prepare:

    compile:

    compile-jdk9+:

    build:
    [delete] Deleting directory /Users/lemon/code/ant/build/classes/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined
            ... more lines

    ... more targets, until we get to the one that we care about

    junit-single-test-only:
        [junit] WARNING: multiple versions of ant detected in path for junit
        [junit]          file:/Users/lemon/code/ant/build/classes/org/apache/tools/ant/Project.class
        [junit]      and jar:file:/usr/local/Cellar/ant/1.10.12/libexec/lib/ant.jar!/org/apache/tools/ant/Project.class
        [junit] Testsuite: org.apache.tools.ant.ProjectTest
        [junit] Tests run: 12, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 5.635 sec
            ... more lines

    junit-single-test:

    BUILD SUCCESSFUL
    Total time: 12 seconds

If this doesn't look all that bad,
try imagining what it looks like
for a Serious Enterprise Project™.


Lots of output is indeed very helpful
– if you're waiting minutes for the entire test suite to run,
you want all the details in there,
so you can debug failures without having to run it again.

However, it's not very helpful during development,
when you only care about the thing you're working on *right now*.
And it's doubly not helpful if you want to re-run the tests
on each file update with something like `entr`_.

.. _entr: http://eradman.com/entrproject/


This is where a `linesieve` wrapper script can help:

.. code-block:: bash

    #!/bin/sh
    linesieve \
        --section '^(\S+):$' \
        --success 'BUILD SUCCESSFUL' \
        --failure 'BUILD FAILED' \
    show junit-batch \
    show junit-single-test-only \
    sub-cwd \
    sub-paths --include 'src/main/**/*.java' --modules-skip 2 \
    sub-paths --include 'src/tests/junit/**/*.java' --modules-skip 3 \
    sub -s compile '^\s+\[javac?] ' '' \
    push compile \
        match -v '^Compiling \d source file' \
        match -v '^Ignoring source, target' \
    pop \
    push junit \
        sub '^\s+\[junit] ?' '' \
        span -v \
            --start '^WARNING: multiple versions of ant' \
            --end '^Testsuite:' \
        match -v '^\s+at java\.\S+\.reflect\.' \
        match -v '^\s+at org.junit.Assert' \
        span -v \
            --start '^\s+at org.junit.(runners|rules|internal)' \
            --end '^(?!\s+at )' \
    pop \
    sub -X '^( \s+ at \s+ (?! .+ \.\. ) .*? ) \( .*' '\1' \
    sub -X '
        (?P<pre> \s+ at \s .*)
        (?P<cls> \w+ )
        (?P<mid> .* \( )
        (?P=cls) \.java
        (?P<suf> : .* )
        ' \
        '\g<pre>\g<cls>\g<mid>\g<suf>' \
    sub --color -X '^( \w+ (\.\w+)+ (?= :\s ))' '\1' \
    sub --color -X '(FAILED)' '\1' \
    read-cmd ant "$@"

You can then call this instead of `ant`: `ant-wrapper.sh junit-single-test ...`.


Successful output looks like this (28 lines):

.. code-block:: text

    ............
    junit-single-test-only
    Testsuite: ..ProjectTest
    Tests run: 12, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 5.635 sec
    ------------- Standard Output ---------------
    bar
    ------------- ---------------- ---------------
    ------------- Standard Error -----------------
    bar
    ------------- ---------------- ---------------

    Testcase: testResolveFileWithDriveLetter took 0.034 sec
        SKIPPED: Not DOS or Netware
    Testcase: testResolveFileWithDriveLetter took 0.036 sec
    Testcase: testInputHandler took 0.007 sec
    Testcase: testAddTaskDefinition took 0.179 sec
    Testcase: testTaskDefinitionContainsKey took 0.002 sec
    Testcase: testDuplicateTargets took 0.05 sec
    Testcase: testResolveRelativeFile took 0.002 sec
    Testcase: testOutputDuringMessageLoggedIsSwallowed took 0.002 sec
    Testcase: testDataTypes took 0.154 sec
    Testcase: testDuplicateTargetsImport took 0.086 sec
    Testcase: testNullThrowableMessageLog took 0.002 sec
    Testcase: testTaskDefinitionContainsValue took 0.002 sec
    Testcase: testResolveFile took 0.001 sec

    .
    BUILD SUCCESSFUL

... "failure" output looks like this (34 lines):

.. code-block:: text

    ............
    junit-single-test-only
    Testsuite: ..ProjectTest
    Tests run: 12, Failures: 1, Errors: 0, Skipped: 1, Time elapsed: 5.638 sec
    ------------- Standard Output ---------------
    bar
    ------------- ---------------- ---------------
    ------------- Standard Error -----------------
    bar
    ------------- ---------------- ---------------

    Testcase: testResolveFileWithDriveLetter took 0.033 sec
        SKIPPED: Not DOS or Netware
    Testcase: testResolveFileWithDriveLetter took 0.035 sec
    Testcase: testInputHandler took 0.005 sec
        FAILED
    expected null, but was:<..DefaultInputHandler@61dc03ce>
    junit.framework.AssertionFailedError: expected null, but was:<..DefaultInputHandler@61dc03ce>
        at ..ProjectTest.testInputHandler(:254)

    Testcase: testAddTaskDefinition took 0.182 sec
    Testcase: testTaskDefinitionContainsKey took 0.003 sec
    Testcase: testDuplicateTargets took 0.043 sec
    Testcase: testResolveRelativeFile took 0.001 sec
    Testcase: testOutputDuringMessageLoggedIsSwallowed took 0.003 sec
    Testcase: testDataTypes took 0.161 sec
    Testcase: testDuplicateTargetsImport took 0.088 sec
    Testcase: testNullThrowableMessageLog took 0.001 sec
    Testcase: testTaskDefinitionContainsValue took 0.001 sec
    Testcase: testResolveFile took 0.001 sec
    Test ..ProjectTest FAILED

    .
    BUILD SUCCESSFUL

... and true failure due to a compile error looks like this (12 lines):

.. code-block:: text

    ...
    compile
    .../Project.java:65: error: cannot find symbol
    public class Project implements xResourceFactory {
                                    ^
    symbol: class xResourceFactory
    .../Project.java:2483: error: method does not override or implement a method from a supertype
        @Override
        ^
    2 errors

    BUILD FAILED


Breaking down the `linesieve` command
(skipping the parts from the traceback example):

* `--section '^(\S+):$'` tells `linesieve`
  sections start with a word followed by a colon.
* The `show`\s hide all sections except specific ones.
* `--success` and `--failure` tell `linesieve`
  to exit when encountering one of these patterns.
  Note that the failing section is shown
  regardless of `show`.
* `sub-cwd` makes absolute paths in the working directory relative.
* The `-s compile` option passed to `sub` applies it
  only to sections matching `compile`.
* `push compile` applies all the following filters, until `pop`,
  only to sections matching `compile`.
* The last two `sub --color ... '\1'` color
  dotted words followed by a colon at the beginning of the line
  (e.g. `junit.framework.AssertionFailedError:`),
  and `FAILED` anywhere in the input.
* Finally, `read-cmd` executes a command and uses its output as input.

.. end-examples

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/lemon24/linesieve",
    "name": "linesieve",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "grep,sed,awk,cli,command-line,terminal,text,text processing,search,replace,regex",
    "author": "lemon24",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/5a/fd/55143a9d49987b9bc78f50aeb310965ee7f9b2280807dd7551a08328f6b7/linesieve-1.0.tar.gz",
    "platform": null,
    "description": "\n.. default-role:: literal\n\n\n.. begin-intro\n\n*This is my text munging tool. There are many like it, but this one is mine.*\n\n**linesieve** is an unholy blend of grep, sed, awk, and Python,\nborn out of spite.\n\n.. end-intro\n\n\n|build-status-github| |code-coverage| |documentation-status| |pypi-status| |code-style|\n\n.. |build-status-github| image:: https://github.com/lemon24/linesieve/workflows/build/badge.svg\n  :target: https://github.com/lemon24/linesieve/actions?query=workflow%3Abuild\n  :alt: build status (GitHub Actions)\n\n.. |code-coverage| image:: https://codecov.io/gh/lemon24/linesieve/branch/main/graph/badge.svg?token=MrpEP5cg24\n  :target: https://codecov.io/gh/lemon24/linesieve\n  :alt: code coverage\n\n.. |documentation-status| image:: https://readthedocs.org/projects/linesieve/badge/?version=latest&style=flat\n  :target: https://linesieve.readthedocs.io/en/latest/?badge=latest\n  :alt: documentation status\n\n.. |pypi-status| image:: https://img.shields.io/pypi/v/linesieve.svg\n  :target: https://pypi.python.org/pypi/linesieve\n  :alt: PyPI status\n\n.. |type-checking| image:: http://www.mypy-lang.org/static/mypy_badge.svg\n  :target: http://mypy-lang.org/\n  :alt: checked with mypy\n\n.. |code-style| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n  :target: https://github.com/psf/black\n  :alt: code style: black\n\n\n\n.. begin-main\n\n\nFeatures\n--------\n\n`linesieve` allows you to:\n\n* split text input into sections\n* apply filters to specific sections\n* search and highlight success/failure markers\n* match/sub/split with the full power of Python's `re`_\n* shorten paths, links and module names\n* chain filters into pipelines\n* color output!\n\n.. _re: https://docs.python.org/3/library/re.html\n\n\nInstalling\n----------\n\nInstall and update using `pip`_:\n\n.. code-block:: console\n\n    $ pip install --upgrade linesieve\n\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n\n\nA simple example\n----------------\n\n.. code-block:: console\n\n    $ ls -1 /* | linesieve -s '.*:' show bin match ^d head -n2\n    .....\n    /bin:\n    dash\n    date\n    ......\n    /sbin:\n    disklabel\n    dmesg\n    ...\n\nThis prints the first two files starting with `d`\nfrom each directory whose name contains `bin`\n(skipped directories are marked with a dot on stderr).\n\n\nLinks\n-----\n\n* PyPI Releases: https://pypi.org/project/linesieve/\n* Documentation: https://linesieve.readthedocs.io/\n* Issue Tracker: https://github.com/lemon24/linesieve/issues\n* Source Code: https://github.com/lemon24/linesieve\n\n\n.. end-main\n\n\n\nExamples\n--------\n\n.. begin-examples\n\n\nJava tracebacks\n~~~~~~~~~~~~~~~\n\nAssume you're writing some Java tests with JUnit,\non a project that looks like this:\n\n.. code-block:: text\n\n    .\n    \u251c\u2500\u2500 src\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 com\n    \u2502\u00a0\u00a0     \u2514\u2500\u2500 example\n    \u2502\u00a0\u00a0         \u2514\u2500\u2500 someproject\n    \u2502\u00a0\u00a0             \u2514\u2500\u2500 somepackage\n    \u2502\u00a0\u00a0                 \u2514\u2500\u2500 ThingDoer.java\n    \u2514\u2500\u2500 tst\n        \u2514\u2500\u2500 com\n            \u2514\u2500\u2500 example\n                \u2514\u2500\u2500 someproject\n                    \u2514\u2500\u2500 somepackage\n                        \u2514\u2500\u2500 ThingDoerTest.java\n\nThis command:\n\n.. code-block:: bash\n\n    linesieve \\\n    span -v -X \\\n        --start '^ (\\s+) at \\s ( org\\.junit\\. | \\S+ \\. reflect\\.\\S+\\.invoke )' \\\n        --end '^ (?! \\s+ at \\s )' \\\n        --repl '\\1...' \\\n    match -v '^\\s+at \\S+\\.(rethrowAs|translateTo)IOException' \\\n    sub-paths --include '{src,tst}/**/*.java' --modules-skip 1 \\\n    sub -X '^( \\s+ at \\s+ (?! .+ \\.\\. | com\\.example\\. ) .*? ) \\( .*' '\\1' \\\n    sub -X '^( \\s+ at \\s+ com\\.example\\. .*? ) \\ ~\\[ .*' '\\1' \\\n    sub -X '\n        (?P<pre> \\s+ at \\s .*)\n        (?P<cls> \\w+ )\n        (?P<mid> .* \\( )\n        (?P=cls) \\.java\n        (?P<suf> : .* )\n        ' \\\n        '\\g<pre>\\g<cls>\\g<mid>\\g<suf>'\n\n... shortens this 76 line traceback:\n\n.. code-block:: text\n\n    12:34:56.789 [main] ERROR com.example.someproject.somepackage.ThingDoer - exception while notifying done listener\n    java.lang.RuntimeException: listener failed\n    \tat com.example.someproject.somepackage.ThingDoerTest$DummyListener.onThingDone(ThingDoerTest.java:420) ~[tests/:?]\n    \tat com.example.someproject.somepackage.ThingDoer.doThing(ThingDoer.java:69) ~[library/:?]\n    \tat com.example.otherproject.Framework.doAllTheThings(Framework.java:1066) ~[example-otherproject-2.0.jar:2.0]\n    \tat com.example.someproject.somepackage.ThingDoerTest.listenerException(ThingDoerTest.java:666) ~[tests/:?]\n    \tat jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]\n    \tat jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]\n    \t...\n    \t... 60+ more lines of JUnit stuff we don't really care about ...\n    \t...\n    12:34:56.999 [main] INFO done\n\n... to just:\n\n.. code-block:: text\n\n    12:34:56.789 [main] ERROR ..ThingDoer - exception while notifying done listener\n    java.lang.RuntimeException: listener failed\n    \tat ..ThingDoerTest$DummyListener.onThingDone(:420) ~[tests/:?]\n    \tat ..ThingDoer.doThing(:69) ~[library/:?]\n    \tat com.example.otherproject.Framework.doAllTheThings(:1066)\n    \tat ..ThingDoerTest.listenerException(:666) ~[tests/:?]\n    \t...\n    12:34:56.999 [main] INFO done\n\nLet's break that `linesieve` command down a bit:\n\n* The `span` gets rid of all the traceback lines coming from JUnit.\n* The `match -v` skips some usually useless lines from stack traces.\n* The `sub-paths` shortens and highlights the names of classes in the current project;\n  `com.example.someproject.somepackage.ThingDoer` becomes `..ThingDoer`\n  (presumably that's enough info to open the file).\n* The first `sub` gets rid of line numbers and JAR names for everything\n  that is not either in the current project or in another `com.example.` package.\n* The second `sub` gets rid of JAR names for things in other `com.example.` packages.\n* The third `sub` gets rid of the source file name;\n  `..ThingDoer.doThing(ThingDoer.java:69)` becomes `..ThingDoer.doThing(:69)`\n  (the file name matches the class name).\n\n\nApache Ant output\n~~~~~~~~~~~~~~~~~\n\nLet's look at why `linesieve` was born in the first place\n\u2013 cleaning up Apache Ant output.\n\nWe'll use Ant's own test output as an example,\nsince it `builds itself`_.\n\n.. _builds itself: https://github.com/apache/ant/tree/ff62ff7151bbc84a7706f40988258fabbcc324f5\n\n\nRunning a single test with:\n\n.. code-block:: bash\n\n    ant junit-single-test -Djunit.testcase=org.apache.tools.ant.ProjectTest\n\n... produces 77 lines of output:\n\n.. code-block:: text\n\n    Buildfile: /Users/lemon/code/ant/build.xml\n\n    check-optional-packages:\n\n    prepare:\n\n    compile:\n\n    compile-jdk9+:\n\n    build:\n    [delete] Deleting directory /Users/lemon/code/ant/build/classes/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined\n            ... more lines\n\n    ... more targets, until we get to the one that we care about\n\n    junit-single-test-only:\n        [junit] WARNING: multiple versions of ant detected in path for junit\n        [junit]          file:/Users/lemon/code/ant/build/classes/org/apache/tools/ant/Project.class\n        [junit]      and jar:file:/usr/local/Cellar/ant/1.10.12/libexec/lib/ant.jar!/org/apache/tools/ant/Project.class\n        [junit] Testsuite: org.apache.tools.ant.ProjectTest\n        [junit] Tests run: 12, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 5.635 sec\n            ... more lines\n\n    junit-single-test:\n\n    BUILD SUCCESSFUL\n    Total time: 12 seconds\n\nIf this doesn't look all that bad,\ntry imagining what it looks like\nfor a Serious Enterprise Project\u2122.\n\n\nLots of output is indeed very helpful\n\u2013 if you're waiting minutes for the entire test suite to run,\nyou want all the details in there,\nso you can debug failures without having to run it again.\n\nHowever, it's not very helpful during development,\nwhen you only care about the thing you're working on *right now*.\nAnd it's doubly not helpful if you want to re-run the tests\non each file update with something like `entr`_.\n\n.. _entr: http://eradman.com/entrproject/\n\n\nThis is where a `linesieve` wrapper script can help:\n\n.. code-block:: bash\n\n    #!/bin/sh\n    linesieve \\\n        --section '^(\\S+):$' \\\n        --success 'BUILD SUCCESSFUL' \\\n        --failure 'BUILD FAILED' \\\n    show junit-batch \\\n    show junit-single-test-only \\\n    sub-cwd \\\n    sub-paths --include 'src/main/**/*.java' --modules-skip 2 \\\n    sub-paths --include 'src/tests/junit/**/*.java' --modules-skip 3 \\\n    sub -s compile '^\\s+\\[javac?] ' '' \\\n    push compile \\\n        match -v '^Compiling \\d source file' \\\n        match -v '^Ignoring source, target' \\\n    pop \\\n    push junit \\\n        sub '^\\s+\\[junit] ?' '' \\\n        span -v \\\n            --start '^WARNING: multiple versions of ant' \\\n            --end '^Testsuite:' \\\n        match -v '^\\s+at java\\.\\S+\\.reflect\\.' \\\n        match -v '^\\s+at org.junit.Assert' \\\n        span -v \\\n            --start '^\\s+at org.junit.(runners|rules|internal)' \\\n            --end '^(?!\\s+at )' \\\n    pop \\\n    sub -X '^( \\s+ at \\s+ (?! .+ \\.\\. ) .*? ) \\( .*' '\\1' \\\n    sub -X '\n        (?P<pre> \\s+ at \\s .*)\n        (?P<cls> \\w+ )\n        (?P<mid> .* \\( )\n        (?P=cls) \\.java\n        (?P<suf> : .* )\n        ' \\\n        '\\g<pre>\\g<cls>\\g<mid>\\g<suf>' \\\n    sub --color -X '^( \\w+ (\\.\\w+)+ (?= :\\s ))' '\\1' \\\n    sub --color -X '(FAILED)' '\\1' \\\n    read-cmd ant \"$@\"\n\nYou can then call this instead of `ant`: `ant-wrapper.sh junit-single-test ...`.\n\n\nSuccessful output looks like this (28 lines):\n\n.. code-block:: text\n\n    ............\n    junit-single-test-only\n    Testsuite: ..ProjectTest\n    Tests run: 12, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 5.635 sec\n    ------------- Standard Output ---------------\n    bar\n    ------------- ---------------- ---------------\n    ------------- Standard Error -----------------\n    bar\n    ------------- ---------------- ---------------\n\n    Testcase: testResolveFileWithDriveLetter took 0.034 sec\n        SKIPPED: Not DOS or Netware\n    Testcase: testResolveFileWithDriveLetter took 0.036 sec\n    Testcase: testInputHandler took 0.007 sec\n    Testcase: testAddTaskDefinition took 0.179 sec\n    Testcase: testTaskDefinitionContainsKey took 0.002 sec\n    Testcase: testDuplicateTargets took 0.05 sec\n    Testcase: testResolveRelativeFile took 0.002 sec\n    Testcase: testOutputDuringMessageLoggedIsSwallowed took 0.002 sec\n    Testcase: testDataTypes took 0.154 sec\n    Testcase: testDuplicateTargetsImport took 0.086 sec\n    Testcase: testNullThrowableMessageLog took 0.002 sec\n    Testcase: testTaskDefinitionContainsValue took 0.002 sec\n    Testcase: testResolveFile took 0.001 sec\n\n    .\n    BUILD SUCCESSFUL\n\n... \"failure\" output looks like this (34 lines):\n\n.. code-block:: text\n\n    ............\n    junit-single-test-only\n    Testsuite: ..ProjectTest\n    Tests run: 12, Failures: 1, Errors: 0, Skipped: 1, Time elapsed: 5.638 sec\n    ------------- Standard Output ---------------\n    bar\n    ------------- ---------------- ---------------\n    ------------- Standard Error -----------------\n    bar\n    ------------- ---------------- ---------------\n\n    Testcase: testResolveFileWithDriveLetter took 0.033 sec\n        SKIPPED: Not DOS or Netware\n    Testcase: testResolveFileWithDriveLetter took 0.035 sec\n    Testcase: testInputHandler took 0.005 sec\n        FAILED\n    expected null, but was:<..DefaultInputHandler@61dc03ce>\n    junit.framework.AssertionFailedError: expected null, but was:<..DefaultInputHandler@61dc03ce>\n        at ..ProjectTest.testInputHandler(:254)\n\n    Testcase: testAddTaskDefinition took 0.182 sec\n    Testcase: testTaskDefinitionContainsKey took 0.003 sec\n    Testcase: testDuplicateTargets took 0.043 sec\n    Testcase: testResolveRelativeFile took 0.001 sec\n    Testcase: testOutputDuringMessageLoggedIsSwallowed took 0.003 sec\n    Testcase: testDataTypes took 0.161 sec\n    Testcase: testDuplicateTargetsImport took 0.088 sec\n    Testcase: testNullThrowableMessageLog took 0.001 sec\n    Testcase: testTaskDefinitionContainsValue took 0.001 sec\n    Testcase: testResolveFile took 0.001 sec\n    Test ..ProjectTest FAILED\n\n    .\n    BUILD SUCCESSFUL\n\n... and true failure due to a compile error looks like this (12 lines):\n\n.. code-block:: text\n\n    ...\n    compile\n    .../Project.java:65: error: cannot find symbol\n    public class Project implements xResourceFactory {\n                                    ^\n    symbol: class xResourceFactory\n    .../Project.java:2483: error: method does not override or implement a method from a supertype\n        @Override\n        ^\n    2 errors\n\n    BUILD FAILED\n\n\nBreaking down the `linesieve` command\n(skipping the parts from the traceback example):\n\n* `--section '^(\\S+):$'` tells `linesieve`\n  sections start with a word followed by a colon.\n* The `show`\\s hide all sections except specific ones.\n* `--success` and `--failure` tell `linesieve`\n  to exit when encountering one of these patterns.\n  Note that the failing section is shown\n  regardless of `show`.\n* `sub-cwd` makes absolute paths in the working directory relative.\n* The `-s compile` option passed to `sub` applies it\n  only to sections matching `compile`.\n* `push compile` applies all the following filters, until `pop`,\n  only to sections matching `compile`.\n* The last two `sub --color ... '\\1'` color\n  dotted words followed by a colon at the beginning of the line\n  (e.g. `junit.framework.AssertionFailedError:`),\n  and `FAILED` anywhere in the input.\n* Finally, `read-cmd` executes a command and uses its output as input.\n\n.. end-examples\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "An unholy blend of grep, sed, awk, and Python.",
    "version": "1.0",
    "split_keywords": [
        "grep",
        "sed",
        "awk",
        "cli",
        "command-line",
        "terminal",
        "text",
        "text processing",
        "search",
        "replace",
        "regex"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "90d75dc2fdb938ad00012a077a14b01122a768a8718288674426eef3e98d3e8f",
                "md5": "b4858696a0b2262f68ede40444807d4d",
                "sha256": "ebd161affcd4581e742fcba7816716e250de7319234e2e1a001dbd9a040818cc"
            },
            "downloads": -1,
            "filename": "linesieve-1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b4858696a0b2262f68ede40444807d4d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 20822,
            "upload_time": "2023-04-17T20:15:58",
            "upload_time_iso_8601": "2023-04-17T20:15:58.259612Z",
            "url": "https://files.pythonhosted.org/packages/90/d7/5dc2fdb938ad00012a077a14b01122a768a8718288674426eef3e98d3e8f/linesieve-1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5afd55143a9d49987b9bc78f50aeb310965ee7f9b2280807dd7551a08328f6b7",
                "md5": "16915810813fd31e65565407d49d1f60",
                "sha256": "3ccfc82254f3f729898dbf3f59356a79dac763a7abd6b547951061407052c359"
            },
            "downloads": -1,
            "filename": "linesieve-1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "16915810813fd31e65565407d49d1f60",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 38441,
            "upload_time": "2023-04-17T20:16:01",
            "upload_time_iso_8601": "2023-04-17T20:16:01.055633Z",
            "url": "https://files.pythonhosted.org/packages/5a/fd/55143a9d49987b9bc78f50aeb310965ee7f9b2280807dd7551a08328f6b7/linesieve-1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-17 20:16:01",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "lemon24",
    "github_project": "linesieve",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "linesieve"
}
        
Elapsed time: 0.05558s