Metadata-Version: 2.0
Name: exesexe
Version: 1.0.1
Summary: Manipulate return codes from executables
Home-page: https://github.com/mtkennerly/exesexe
Author: Matthew T. Kennerly (mtkennerly)
Author-email: mtkennerly@gmail.com
License: MIT
Keywords: return code
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Utilities
Provides-Extra: dev
Requires-Dist: invoke; extra == 'dev'
Requires-Dist: pyinstaller; extra == 'dev'
Requires-Dist: tox; extra == 'dev'

Inspired by programs that return 1 on success, exesexe lets you wrap a call
to an executable and selectively override its return codes. This allows you,
for example, to use an aberrant installer with configuration management
software that expects programs to return 0 when successful.

exesexe will use the first argument it receives as its own directive, but all
other arguments will be executed without modification. The directive is a
comma-separated list, where each segment may have one of these forms:

```
1      whitelist 1 (convert to 0)
-1=2   substitute -1 with 2
5:8=9  substitute 5, 6, 7, and 8 with 9
!1     blacklist 1 (don't convert 1 at all; convert everything else to 0)
*=3    substitute all others with 3
```

Examples:
  * `1,-1,2=3`
    * Convert 1 and -1 to 0.
    * Convert 2 to 3.

  * `!2`
    * Don't convert 2.
    * Convert everything else to 0.

  * `!-4=2`
    * Don't convert -4.
    * Convert everything else to 2.

  * `*=10`
    * Return 10 no matter what.

The precedence order is whitelists, specific substitutions, blacklists,
then *-substitutions, so `*=4,1=2,!3` would convert 1 to 2 rather than 4 or 0.
The lexical order only matters for overlapping segments, like `1=0,1=2`,
where the rightmost segment overrides the left segments.

Suppose you want to run the executable `foo`. You could issue any of these:

```
exesexe 1 foo         # return 0 if foo returns 1
exesexe 3=4 foo       # return 4 if foo returns 3
exesexe *=0 foo       # always return 0
exesexe !2 foo        # return 0 if foo does not return 2
exesexe !2,3=4 foo    # if foo returns 3, return 4;
                      # else, if foo does not return 2, return 0;
                      # else, pass back foo's real return code
```

You can also use exesexe as a library:

```python
import exesexe
whitelist, blacklist, substitutions = exesexe.parse_directive("1,!2,3=4")
exesexe.interpret(
    "foo --bar",
    whitelist=[1],
    blacklist=[2],
    substitutions={3: 4, "*": 1}
)
```


