Metadata-Version: 2.4
Name: ppqs
Version: 2.0.1
Summary: Python project quick scripts
Author-email: Karl Wette <karl.wette@anu.edu.au>
License-Expression: MIT
Project-URL: Homepage, https://github.com/kwwette/ppqs
Project-URL: Issues, https://github.com/kwwette/ppqs/issues
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
Dynamic: license-file

# Python project quick scripts

**Define simple project management scripts in `pyproject.toml`**

Developing a Python project usually involves many tasks: setting up, installing
prerequisites, building, testing, cleaning up build products, etc. It can be
difficult to remember which program to run to perform a given task for a given
project, particularly when many different tools are being used.

**ppqs** defines simple (*"quick"*) scripts in `pyproject.toml`, and provides a
command-line utility -- `ppqs` -- to run them. In this way **ppqs** hides the
details of whatever dependency/virtual environment manager, build front-end,
test harness, etc. the project uses behind a simple interface.

Here is an example of **ppqs** being used for its own project:

```
$ ppqs --help
Quick scripts for Python project: ppqs

Usage: ppqs {init,lint,build,test,clean}

Scripts:
  init   Initialise project
  lint   Perform linting checks
  build  Build project
  test   Run tests
  clean  Clean up build files
```

Scripts are always run from the project root directory, i.e. the directory
containing `pyproject.toml`. `ppqs` traverses back through parent directories
until it finds the root directory. It is therefore safe to run `ppqs` from any
sub-directory within the project directory tree.

## Script definition in `pyproject.toml`

**ppqs** scripts are simple lists of commands which are run in sequence. If a
command errors, the remainder of the script is aborted.

Scripts are defined in `pyproject.toml` under the `[tool.ppqs.scripts]`
section. Script names may contain only lowercase letters (`[a-z]`) and dashes
(`-`). Scripts may be single or multi-line strings: commands are separated by
newlines, and command arguments are separated by spaces.

```toml
[tool.ppqs.scripts]
init = "command"
lint = """
command
"""
build = """
command1 -v
command2 -q
"""
```

Scripts may also be defined as lists of lists, i.e. a list of commands, each of
which is a list of arguments:

```toml
[tool.ppqs.scripts]
test = [
    ["command1"],
    ["command2", "-vv"],
]
clean = [
    ["command"],
]
```

If a script contains an ellipsis (`...`) it is replaced with any additional
arguments passed to `ppqs`. For example, the following script:

```toml
[tool.ppqs.scripts]
print-something = "echo ..."
```

may be run as

```
$ ppqs print-something Hi
Hi
```

The following only applies to scripts defined as lists of lists: if a command
argument is itself a list, it is concatenated into a path appropriate for the
current operating system. For example,

```toml
[tool.ppqs.scripts]
do-something = [["do-something-to", ["subdir", "afile"]]]
```

would run the command `do-something-to subdir/afile` on a Unix-based operating
system.

Scripts may also be defined in their own section, which permit a few options:

```toml
[tool.ppqs.scripts.init]
description = "Initialise project"
print-header = true
script = """
command
"""

[tool.ppqs.scripts.build]
script = [
    ["command1", "-v"],
    ["command2", "-q"],
]
```

where:

* `description` *(optional)*: description of the script which appears in `ppqs
  --help`. Default is `Run {name} script` where `name` is the script name.

* `print-header` *(optional)*: If true, print a header before running each
  command in the script. The header consists of the command to be run, centred
  on the console and padded with `*`s. Default is false.

The default value of some options may be overridden in the
`[tool.ppqs.defaults]` section, e.g.

```
[tool.ppqs.defaults]
print-header = true
```

Note that commands are *not* passed to the shell, so shell features
(e.g. wildcards, conditional statements) are not available. The recommended
solution is to write a helper script, e.g. `scripts/lots-to-do.py`, which may
then be called by `ppqs` as:

```toml
[tool.ppqs.scripts]
lots-to-do = [["python", "scripts/lots-to-do.py"]]
```

## Bash completion

`ppqs` support Bash command-line completion. Simply add the following command to
your `~/.bashrc` file:

```bash
complete -C "ppqs --bash-completion" ppqs
```

Typing `ppqs ` and hitting `TAB` will then show scripts available for the
current project. Typing part of a script name and hitting `TAB` will show
matching script name(s), or else complete the full name if unambiguous.
