Metadata-Version: 2.1
Name: pysh-lib
Version: 0.0.1
Summary: Pythonically simple alternative to shell scripts and subprocess
Home-page: https://github.com/gnprice/pysh
Author: Greg Price
Author-email: gnprice@gmail.com
License: MIT
Project-URL: Documentation, https://github.com/gnprice/pysh/blob/master/pysh/README.md
Project-URL: Examples, https://github.com/gnprice/pysh/tree/master/example
Keywords: scripting shell subprocess cli
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Operating System :: Unix
Classifier: Operating System :: POSIX
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Environment :: Console
Classifier: Environment :: No Input/Output (Daemon)
Classifier: Environment :: Web Environment
Classifier: Environment :: Other Environment
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Requires-Dist: click (>=7.0)

Pysh is a library for running external commands from a Python program,
with the usual concision and clarity that Python achieves in other domains.

## Usage

Simple commands are simple:

    from pysh import check_cmd, try_cmd

    check_cmd('gpg --decrypt --output {} {}', cleartext_path, cryptotext_path)

    if not try_cmd('git diff-index --quiet HEAD'):
        raise RuntimeError("worktree not clean")

    repo_root = slurp_cmd('git rev-parse --show-toplevel')
    # "slurp" strips trailing newlines, just like shell `$(...)`

### Writing command lines

Command lines offer a `format`-like minilanguage, powered by
`pysh.shwords`.  The format string is automatically split to form the
command's list of arguments, providing shell-script-like
convenience...  but the interpolated data never affects the split,
avoiding classic shell-script bugs.

    from pysh import shwords, check_cmd

    shwords('rm -rf {tmpdir}/{userdoc}', tmpdir='/tmp', userdoc='1 .. 2')
    # -> ['rm', '-rf', '/tmp/1 .. 2']

    check_cmd('rm -rf {tmpdir}/{userdoc}', tmpdir='/tmp', userdoc='1 .. 2')
    # removes `/tmp/1 .. 2` -- not `/tmp/1`, `..`, and `2`

A format-minilanguage extension `{...!@}` substitutes in a whole list:

    check_cmd('grep -C2 TODO -- {!@}', files)

Each function taking a command line also has a twin, named with `_f`,
that opts into f-string-like behavior:

    from pysh import check_cmd, check_cmd_f

    check_cmd_f('{compiler} {cflags!@} -c {source_file} -o {object_file}')

    # equivalent to:
    check_cmd('{} {!@} -c {} -o {}',
              compiler, cflags, source_file, object_file)

### Pipelines

Pipelines are composed with the `|` operator.  Each stage (or
"filter") in the pipeline can be an external command, or Python code.

Most often pipelines are built from the filters offered in the
`pysh.cmd` module.  You can consume the output with `pysh.slurp`:

    import pysh
    from pysh import cmd

    hello = pysh.slurp(cmd.echo(b'hello world')
                       | cmd.run('tr h H'))
    # -> b'Hello world'

Or iterate through it:

    for commit_id in (cmd.run('git rev-list -n10 -- {!@}', files)
                      | cmd.splitlines()):
        # ... gets last 10 commits touching `files`

You can also write filters directly, using the `@pysh.filter`
decorator.  See examples in the `example/` tree.  This is also the same
API that all the filters in `pysh.cmd` are built on, so there are many
examples there.



