Metadata-Version: 2.1
Name: foremon
Version: 1.3.0
Summary: Automatically restart applications when file changes are detected.
Home-page: http://github.com/matutter/foremon
Author: Mathew Utter
Author-email: mcutter.svc@gmail.com
License: MIT
Keywords: python filesystem monitoring scripting task automation
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX :: BSD
Classifier: Operating System :: Microsoft :: Windows :: Windows Vista
Classifier: Operating System :: Microsoft :: Windows :: Windows 7
Classifier: Operating System :: Microsoft :: Windows :: Windows 8
Classifier: Operating System :: Microsoft :: Windows :: Windows 8.1
Classifier: Operating System :: Microsoft :: Windows :: Windows 10
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Filesystems
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: Utilities
Requires: ansicolors
Requires: click
Requires: watchdog
Requires: toml
Requires: pydantic
Requires-Python: >=3.6.1
Description-Content-Type: text/markdown
Requires-Dist: ansicolors (>=1.1.8)
Requires-Dist: click (>=7.1.2)
Requires-Dist: watchdog (>=1.0.2)
Requires-Dist: toml (>=0.10.2)
Requires-Dist: pydantic (>=1.7.3)

# foremon

[![ci](https://github.com/matutter/foremon/workflows/CI/badge.svg?event=push)](https://github.com/matutter/foremon/actions?query=event%3Apush+branch%3Amaster+workflow%3ACI)
[![coverage](https://codecov.io/gh/matutter/foremon/branch/master/graph/badge.svg)](https://codecov.io/gh/matutter/foremon)
[![pypi](https://img.shields.io/pypi/v/foremon.svg)](https://pypi.python.org/pypi/foremon)
[![downloads](https://img.shields.io/pypi/dm/foremon.svg)](https://pypistats.org/packages/foremon)
[![versions](https://img.shields.io/pypi/pyversions/foremon.svg)](https://github.com/matutter/foremon)
[![license](https://img.shields.io/github/license/matutter/foremon.svg)](https://github.com/matutter/foremon/blob/master/LICENSE)

foremon is a tool to help develop python projects by executing build tasks when
file changes are detected.

foremon intends to have feature parity to [nodemon][nodemon], a similar tool for
the NodeJS ecosystem, but provide those features within a python toolchain. To
use `foremon` run your script or module as `foremon [script or module]` or run
`foremon --help` for advanced usage.

File monitoring is provided by [watchdog][watchdog] which provides its own
shell-utility, [watchmedo][watchmedo].

foremon is currently in beta.

[nodemon]: https://www.npmjs.com/package/nodemon
[watchdog]: https://github.com/gorakhargosh/watchdog
[watchmedo]: https://github.com/gorakhargosh/watchdog#shell-utilities

# Installation

Clone `foremon` with git or install it using [pip][pip] (recommended):

```bash
pip install foremon
```

[pip]: https://packaging.python.org/tutorials/installing-packages/#use-pip-for-installing

# Usage

foremon will bootstrap your module or script with the arguments you normally
pass to it:

```bash
foremon [script or module or library:func] [args]
```

If your application uses options which conflict with foremon's options use the
`--` argument separator.

```bash
foremon -- mymodules --version
```

For CLI options `--help`:

```bash
foremon --help
```

Using foremon is simple. It will guess if you are running a module or python
script and adjust command-line arguments and the `PYTHONPATH` accordingly. To
disable this feature, add the `-n` (`--no-guess`) option.

```bash
# Executes `script.py`
foremon -n -- script.py

# Executes `python3 script.py`
foremon -- script.py

# Executes `python -m module` if module/__main__.py is present
foremon module

# Executes `python -c 'from lib import main; main()'` if only lib/__init__.py is present
foremon lib:main

# Execute `python -m module` and inserts `path/to` into PYTHONPATH
foremon path/to/module
```

foremon runs python scripts with the python interpreter of the environment it is
installed in (`sys.executable`).

All foremon output is prefixed with `[foremon]` and written to `stderr`. Output
from your script, errors included, will be echoed out as expected.

If no script is given, foremon will test for a `pyproject.toml` file and if
found, will run scripts specified in the `[tool.foremon]` section
[(ref.)](#pyproject.toml).

# Automatic re-running

When file changes are detected foremon will restart the script. If a script is
running when the change is detected foremon will terminate the script before
running it again.

foremon will wait a short period after changes are detected before restarting
scripts. If a high volume of events are preventing a script from being restarted
foremon will display a warning.

To control how long foremon waits use the `-d/--dwell` option. _Dwell_ is a
fractional number of seconds to wait and is set to `0.1` (_100 milliseconds_) by
default.

# Manual restart

Scripts may be manually restarted by typing `rs` and `enter` in the terminal
where foremon is running. If a script is still running when `rs` is entered then
foremon will terminate the script with a signal. By default `SIGTERM` is sent
but the signal may be changed by setting `term_signal` in the config file.

foremon can also be shutdown gracefully by typing `exit` followed by `enter`.
Just using `ctrl+c` has the same effect.

# pyproject.toml

foremon supports _pyproject.toml_ configuration files. If the project contains a
_pyproject.toml_ file foremon will automatically load defaults from the
`[tool.foremon]` section. An alternative config file may be specified with the
`-f` (`--config-file`) option.

All configuration settings are optional but foremon wont begin monitoring for
changes if there are no `scripts` to run.

foremon will automatically reload the config file if it changes while foremon is
running. Using the `--no-reload` option will disable this feature.

```ini
[tool.foremon]
# Only watch files ending in .py
patterns = ["*.py"]
# Run these scripts in-order on-change
scripts = ["pytest --cov=myproj"]
# Only run if explicitly run with `-a [alias]
skip = true
# Run script like they're in this directory
cwd = "./"
# Exit code to expect for a successful exit
returncode = 0
# Amount of time after an event is received and a script is restarted
dwell = 1.0
# Signal to send if the process should be terminated
term_signal = "SIGTERM"
# Set to false to turn on case-sensitive pattern matching
ignore_case = true
# List of default ignored paths like .git, or .tox
ignore_defaults = []
# Ignore changes to directories
ignore_dirs = true
# A list of patterns to ignore
ignore = ["*/build/*"]
# Paths to watch for changes
paths = ["src/"]
# Watch paths recursively
recursive = true
# List of events - created, deleted, moved, modified
events = ["created", "modified"]
# Environment overrides
[tool.foremon.environment]
TERM = "MONO"
```

All subsections contain the same options.

foremon supports multiple monitor and script definitions. Sections in the config
file matching `[tool.foremon.*]`, where `*` is the alias for the section, may be
defined in addition to the default section.

To run these other sections specify the `-a [alias]` option. The `-a` option may
be used multiple times or the `--all` option can be used to turn on all tasks.


```ini
[tool.foremon]
patterns = ["*.c", "*.h"]
scripts = ["./configure"]

  # Run me with 'foremon -a make'
  [tool.foremon.make]
  patterns = ["make*"]
  paths = ["src/*"]
  scripts = ["make -C src"]
  events = ["created"]

  [tool.foremon.other]
  scripts = ["echo skipped"]
  skip = true
```

Any command-line arguments passed to foremon only supersede definitions in
default section.

Refer to the [configuration samples][config] for more examples of configuring
foremon.

[config]: /config

