nomnom-py 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nomnom_py-1.0.0/.github/workflows/ci.yml +32 -0
- nomnom_py-1.0.0/.github/workflows/publish.yml +54 -0
- nomnom_py-1.0.0/.gitignore +59 -0
- nomnom_py-1.0.0/.python-version +1 -0
- nomnom_py-1.0.0/AGENTS.md +57 -0
- nomnom_py-1.0.0/CONTRIBUTING.md +40 -0
- nomnom_py-1.0.0/LICENSE.md +21 -0
- nomnom_py-1.0.0/PKG-INFO +137 -0
- nomnom_py-1.0.0/README.md +113 -0
- nomnom_py-1.0.0/RELEASING.md +48 -0
- nomnom_py-1.0.0/SECURITY.md +18 -0
- nomnom_py-1.0.0/config.example.toml +11 -0
- nomnom_py-1.0.0/nomnom/__init__.py +28 -0
- nomnom_py-1.0.0/nomnom/cli.py +224 -0
- nomnom_py-1.0.0/nomnom/commands/__init__.py +0 -0
- nomnom_py-1.0.0/nomnom/commands/plugin.py +314 -0
- nomnom_py-1.0.0/nomnom/commands/setup.py +157 -0
- nomnom_py-1.0.0/nomnom/commands/watch.py +130 -0
- nomnom_py-1.0.0/nomnom/config.py +105 -0
- nomnom_py-1.0.0/nomnom/create_plugin.py +106 -0
- nomnom_py-1.0.0/nomnom/discovery.py +181 -0
- nomnom_py-1.0.0/nomnom/dispatcher.py +87 -0
- nomnom_py-1.0.0/nomnom/effects.py +47 -0
- nomnom_py-1.0.0/nomnom/events.py +18 -0
- nomnom_py-1.0.0/nomnom/executor.py +95 -0
- nomnom_py-1.0.0/nomnom/plugin.py +29 -0
- nomnom_py-1.0.0/nomnom/stats.py +44 -0
- nomnom_py-1.0.0/nomnom/validation.py +69 -0
- nomnom_py-1.0.0/nomnom/watcher.py +245 -0
- nomnom_py-1.0.0/plugins/nomnom-plugin-rules/README.md +54 -0
- nomnom_py-1.0.0/plugins/nomnom-plugin-rules/nomnom_plugin_rules/__init__.py +175 -0
- nomnom_py-1.0.0/plugins/nomnom-plugin-rules/pyproject.toml +13 -0
- nomnom_py-1.0.0/plugins/nomnom-plugin-rules/rules.example.toml +7 -0
- nomnom_py-1.0.0/pyproject.toml +74 -0
- nomnom_py-1.0.0/tests/__init__.py +0 -0
- nomnom_py-1.0.0/tests/conftest.py +44 -0
- nomnom_py-1.0.0/tests/test_cli.py +504 -0
- nomnom_py-1.0.0/tests/test_cli_commands.py +25 -0
- nomnom_py-1.0.0/tests/test_config.py +340 -0
- nomnom_py-1.0.0/tests/test_create_plugin.py +72 -0
- nomnom_py-1.0.0/tests/test_discovery.py +341 -0
- nomnom_py-1.0.0/tests/test_dispatcher.py +294 -0
- nomnom_py-1.0.0/tests/test_executor.py +262 -0
- nomnom_py-1.0.0/tests/test_plugin_setup.py +52 -0
- nomnom_py-1.0.0/tests/test_rules_plugin.py +323 -0
- nomnom_py-1.0.0/tests/test_stats.py +31 -0
- nomnom_py-1.0.0/tests/test_validation.py +94 -0
- nomnom_py-1.0.0/tests/test_watcher.py +474 -0
- nomnom_py-1.0.0/uv.lock +611 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Check out repository
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.11"
|
|
21
|
+
|
|
22
|
+
- name: Set up uv
|
|
23
|
+
uses: astral-sh/setup-uv@v5
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: uv sync --dev
|
|
27
|
+
|
|
28
|
+
- name: Lint
|
|
29
|
+
run: uv run ruff check
|
|
30
|
+
|
|
31
|
+
- name: Test
|
|
32
|
+
run: uv run pytest
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- name: Check out repository
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.11"
|
|
22
|
+
|
|
23
|
+
- name: Set up uv
|
|
24
|
+
uses: astral-sh/setup-uv@v5
|
|
25
|
+
|
|
26
|
+
- name: Build distributions
|
|
27
|
+
run: uv build
|
|
28
|
+
|
|
29
|
+
- name: Upload distributions
|
|
30
|
+
uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: python-package-distributions
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
name: Publish to PyPI
|
|
37
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
38
|
+
needs: build
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
environment:
|
|
41
|
+
name: pypi
|
|
42
|
+
url: https://pypi.org/p/nomnom-py
|
|
43
|
+
permissions:
|
|
44
|
+
id-token: write
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- name: Download distributions
|
|
48
|
+
uses: actions/download-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: python-package-distributions
|
|
51
|
+
path: dist/
|
|
52
|
+
|
|
53
|
+
- name: Publish distributions
|
|
54
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
pip-wheel-metadata/
|
|
20
|
+
share/python-wheels/
|
|
21
|
+
*.egg-info/
|
|
22
|
+
.installed.cfg
|
|
23
|
+
*.egg
|
|
24
|
+
MANIFEST
|
|
25
|
+
|
|
26
|
+
# Virtual environments
|
|
27
|
+
.venv
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
env/
|
|
31
|
+
|
|
32
|
+
# IDE
|
|
33
|
+
.vscode/
|
|
34
|
+
.idea/
|
|
35
|
+
*.swp
|
|
36
|
+
*.swo
|
|
37
|
+
*~
|
|
38
|
+
.DS_Store
|
|
39
|
+
|
|
40
|
+
# Testing
|
|
41
|
+
.pytest_cache/
|
|
42
|
+
.coverage
|
|
43
|
+
htmlcov/
|
|
44
|
+
|
|
45
|
+
# Project-specific
|
|
46
|
+
*.toml.local
|
|
47
|
+
|
|
48
|
+
# plugins
|
|
49
|
+
plugins/*
|
|
50
|
+
!plugins/nomnom-plugin-rules/
|
|
51
|
+
rules.toml
|
|
52
|
+
|
|
53
|
+
# config
|
|
54
|
+
config.toml
|
|
55
|
+
|
|
56
|
+
# ai tools
|
|
57
|
+
.jules/
|
|
58
|
+
.codex/
|
|
59
|
+
.conductor/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
**nomnom** is a plugin-based file watcher CLI. It watches directories for file changes and dispatches events to plugins that perform filesystem operations.
|
|
6
|
+
|
|
7
|
+
- **Entry point:** `nomnom/cli.py` (Typer app)
|
|
8
|
+
- **Package:** `nomnom/`
|
|
9
|
+
- **Tests:** `tests/`
|
|
10
|
+
- **Built-in plugin:** `plugins/nomnom-plugin-rules/`
|
|
11
|
+
|
|
12
|
+
## Tech Stack
|
|
13
|
+
|
|
14
|
+
- Python 3.11+ (use modern syntax: `match/case`, `X | Y` unions, dataclasses)
|
|
15
|
+
- CLI: `typer`
|
|
16
|
+
- File watching: `watchfiles`
|
|
17
|
+
- Build: `hatchling`
|
|
18
|
+
- Deps: `uv`
|
|
19
|
+
|
|
20
|
+
## Code Style
|
|
21
|
+
|
|
22
|
+
- **Linter:** ruff — rules: E, F, W, I, UP, B, SIM. Line length: 100.
|
|
23
|
+
- **Type checker:** mypy — strict mode enabled, target Python 3.11.
|
|
24
|
+
- Prefer `Protocol` over ABC for plugin interfaces.
|
|
25
|
+
- Use `dataclass` for data types (effects, events).
|
|
26
|
+
- Use `TYPE_CHECKING` guards to avoid circular imports.
|
|
27
|
+
|
|
28
|
+
## Testing
|
|
29
|
+
|
|
30
|
+
- Framework: `pytest`
|
|
31
|
+
- Run: `uv run pytest`
|
|
32
|
+
- Test files: `tests/test_<module>.py`
|
|
33
|
+
- Fixtures in `tests/conftest.py` (e.g. `make_event`, `StubPlugin`)
|
|
34
|
+
|
|
35
|
+
## Commits
|
|
36
|
+
|
|
37
|
+
- Keep commits minimal; describe the overview of changes.
|
|
38
|
+
- Prefix with one of: `feat:`, `fix:`, `test:`, `refactor:`
|
|
39
|
+
|
|
40
|
+
## Architecture
|
|
41
|
+
|
|
42
|
+
- **Event-driven:** `watchfiles` detects changes → `FileEvent` objects are created.
|
|
43
|
+
- **Plugin protocol:** plugins implement `matches(event)` and `handle(event)`.
|
|
44
|
+
- **Effect system:** plugins return `Effect` objects (`MoveFile`, `DeleteFile`, `CreateFile`, `EditFile`, `EmitEvent`).
|
|
45
|
+
- **Dispatcher:** routes events to matching plugins with depth-limited recursion for `EmitEvent`.
|
|
46
|
+
- **Executor:** performs atomic file operations (tempfile + rename).
|
|
47
|
+
- **Discovery:** plugins are loaded via Python entry points.
|
|
48
|
+
- **Config:** TOML-based (`config.toml`) with watch groups and plugin settings.
|
|
49
|
+
|
|
50
|
+
## Key Commands
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
uv run pytest # run tests
|
|
54
|
+
uv run ruff check . # lint
|
|
55
|
+
uv run mypy nomnom # typecheck
|
|
56
|
+
uv run nomnom --help # CLI help
|
|
57
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Development Setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
uv sync --dev
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
This installs the project and the development toolchain into the local virtual environment managed by `uv`.
|
|
10
|
+
|
|
11
|
+
## Common Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv run pytest
|
|
15
|
+
uv run ruff check
|
|
16
|
+
uv run mypy
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Run the full test suite before opening a pull request. If you change CLI behavior, also verify:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv run nomnom --help
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Working on Plugins
|
|
26
|
+
|
|
27
|
+
Use the built-in scaffold to create a local plugin package:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv run nomnom plugin create my-plugin
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Local plugins live under `plugins/`. The repository currently includes `nomnom-plugin-rules` as a reference implementation.
|
|
34
|
+
|
|
35
|
+
## Pull Requests
|
|
36
|
+
|
|
37
|
+
- Keep changes focused and minimal.
|
|
38
|
+
- Add or update tests for behavior changes.
|
|
39
|
+
- Update docs or examples when public-facing behavior changes.
|
|
40
|
+
- Prefer small commits with clear messages.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2026] [Mohamad Kenaan]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
nomnom_py-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nomnom-py
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Plugin-based CLI file watcher
|
|
5
|
+
Project-URL: Homepage, https://github.com/MohammadKanaan/nomnom-py
|
|
6
|
+
Project-URL: Repository, https://github.com/MohammadKanaan/nomnom-py
|
|
7
|
+
Project-URL: Issues, https://github.com/MohammadKanaan/nomnom-py/issues
|
|
8
|
+
Author-email: Mohammad Kanaan <mohammadkanaan.me@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE.md
|
|
11
|
+
Keywords: cli,file-watcher,plugins
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: rich>=13.0
|
|
20
|
+
Requires-Dist: tomli-w>=1.0
|
|
21
|
+
Requires-Dist: typer>=0.9
|
|
22
|
+
Requires-Dist: watchfiles>=0.21
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# nomnom
|
|
26
|
+
|
|
27
|
+
`nomnom` is an extensible file watcher for local automation. The core detects file changes and fires events. Plugins do the actual work: moving files, enriching them, or kicking off downstream workflows.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install nomnom-py
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
### Initialize
|
|
38
|
+
|
|
39
|
+
Generates a default `config.toml` in your project root.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
nomnom setup
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Watch
|
|
46
|
+
|
|
47
|
+
Starts watching your directories based on the configuration.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
nomnom watch
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use `nomnom watch --once <group>` to process a single watch group one time, or `nomnom watch --dry` to inspect behavior without applying file effects.
|
|
54
|
+
|
|
55
|
+
## Example Configuration
|
|
56
|
+
|
|
57
|
+
`nomnom` reads `config.toml` from the current project by default, or a custom path passed with `--config`.
|
|
58
|
+
|
|
59
|
+
```toml
|
|
60
|
+
[[watch]]
|
|
61
|
+
name = "inbox"
|
|
62
|
+
paths = ["./fixtures/inbox"]
|
|
63
|
+
extensions = [".pdf", ".txt"]
|
|
64
|
+
|
|
65
|
+
[[watch]]
|
|
66
|
+
name = "archive"
|
|
67
|
+
paths = ["./fixtures/archive"]
|
|
68
|
+
|
|
69
|
+
[[plugins]]
|
|
70
|
+
name = "nomnom-plugin-rules"
|
|
71
|
+
priority = 10
|
|
72
|
+
enabled = true
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For a fuller starter file, see [`config.example.toml`](config.example.toml).
|
|
76
|
+
|
|
77
|
+
## Plugins
|
|
78
|
+
|
|
79
|
+
### The Built-in Rules Plugin
|
|
80
|
+
|
|
81
|
+
A rules plugin for declarative file automation driven by `rules.toml`.
|
|
82
|
+
See [`plugins/nomnom-plugin-rules/README.md`](plugins/nomnom-plugin-rules/README.md) for the rule format and supported actions.
|
|
83
|
+
|
|
84
|
+
### Installing Community Plugins
|
|
85
|
+
|
|
86
|
+
Plugins can be installed from PyPI or directly from a Git repository:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
nomnom plugin add <package-name-or-git-url>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Example:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
nomnom plugin add git+https://github.com/<owner>/nomnom-plugin-example
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Creating a Plugin
|
|
99
|
+
|
|
100
|
+
Scaffold a local plugin package inside `plugins/`:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
nomnom plugin create <name>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The generated package includes a `pyproject.toml` entry point and a stub plugin module. Local plugins are automatically discoverable, no need to configure them.
|
|
107
|
+
|
|
108
|
+
If you'd like to publish your plugin, move it to its own repo and publish it to GitHub or PyPI. There is no system for discovering plugins yet but shoot me an email if interested.
|
|
109
|
+
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
uv sync --dev
|
|
114
|
+
uv run pytest
|
|
115
|
+
uv run ruff check
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Contributor guidance lives in [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## CLI Reference
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
Core Commands:
|
|
125
|
+
nomnom watch [GROUP] [OPTS] Start watching (Opts: -c/--config, -v/--verbose, --dry-run, --once)
|
|
126
|
+
nomnom setup [OPTS] Create or update the config file
|
|
127
|
+
nomnom --version / -v Print installed version
|
|
128
|
+
|
|
129
|
+
Plugin Management:
|
|
130
|
+
nomnom plugin add PACKAGE Install and register a plugin
|
|
131
|
+
nomnom plugin remove PACKAGE Remove a plugin
|
|
132
|
+
nomnom plugin enable NAME Enable a plugin in config
|
|
133
|
+
nomnom plugin disable NAME Disable a plugin in config
|
|
134
|
+
nomnom plugin list List active plugins
|
|
135
|
+
nomnom plugin setup Run setup for specific/all plugins
|
|
136
|
+
nomnom plugin create NAME Scaffold a new local plugin
|
|
137
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# nomnom
|
|
2
|
+
|
|
3
|
+
`nomnom` is an extensible file watcher for local automation. The core detects file changes and fires events. Plugins do the actual work: moving files, enriching them, or kicking off downstream workflows.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install nomnom-py
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Initialize
|
|
14
|
+
|
|
15
|
+
Generates a default `config.toml` in your project root.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
nomnom setup
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Watch
|
|
22
|
+
|
|
23
|
+
Starts watching your directories based on the configuration.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
nomnom watch
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use `nomnom watch --once <group>` to process a single watch group one time, or `nomnom watch --dry` to inspect behavior without applying file effects.
|
|
30
|
+
|
|
31
|
+
## Example Configuration
|
|
32
|
+
|
|
33
|
+
`nomnom` reads `config.toml` from the current project by default, or a custom path passed with `--config`.
|
|
34
|
+
|
|
35
|
+
```toml
|
|
36
|
+
[[watch]]
|
|
37
|
+
name = "inbox"
|
|
38
|
+
paths = ["./fixtures/inbox"]
|
|
39
|
+
extensions = [".pdf", ".txt"]
|
|
40
|
+
|
|
41
|
+
[[watch]]
|
|
42
|
+
name = "archive"
|
|
43
|
+
paths = ["./fixtures/archive"]
|
|
44
|
+
|
|
45
|
+
[[plugins]]
|
|
46
|
+
name = "nomnom-plugin-rules"
|
|
47
|
+
priority = 10
|
|
48
|
+
enabled = true
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For a fuller starter file, see [`config.example.toml`](config.example.toml).
|
|
52
|
+
|
|
53
|
+
## Plugins
|
|
54
|
+
|
|
55
|
+
### The Built-in Rules Plugin
|
|
56
|
+
|
|
57
|
+
A rules plugin for declarative file automation driven by `rules.toml`.
|
|
58
|
+
See [`plugins/nomnom-plugin-rules/README.md`](plugins/nomnom-plugin-rules/README.md) for the rule format and supported actions.
|
|
59
|
+
|
|
60
|
+
### Installing Community Plugins
|
|
61
|
+
|
|
62
|
+
Plugins can be installed from PyPI or directly from a Git repository:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
nomnom plugin add <package-name-or-git-url>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
nomnom plugin add git+https://github.com/<owner>/nomnom-plugin-example
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Creating a Plugin
|
|
75
|
+
|
|
76
|
+
Scaffold a local plugin package inside `plugins/`:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
nomnom plugin create <name>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The generated package includes a `pyproject.toml` entry point and a stub plugin module. Local plugins are automatically discoverable, no need to configure them.
|
|
83
|
+
|
|
84
|
+
If you'd like to publish your plugin, move it to its own repo and publish it to GitHub or PyPI. There is no system for discovering plugins yet but shoot me an email if interested.
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv sync --dev
|
|
90
|
+
uv run pytest
|
|
91
|
+
uv run ruff check
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Contributor guidance lives in [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
## CLI Reference
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
Core Commands:
|
|
101
|
+
nomnom watch [GROUP] [OPTS] Start watching (Opts: -c/--config, -v/--verbose, --dry-run, --once)
|
|
102
|
+
nomnom setup [OPTS] Create or update the config file
|
|
103
|
+
nomnom --version / -v Print installed version
|
|
104
|
+
|
|
105
|
+
Plugin Management:
|
|
106
|
+
nomnom plugin add PACKAGE Install and register a plugin
|
|
107
|
+
nomnom plugin remove PACKAGE Remove a plugin
|
|
108
|
+
nomnom plugin enable NAME Enable a plugin in config
|
|
109
|
+
nomnom plugin disable NAME Disable a plugin in config
|
|
110
|
+
nomnom plugin list List active plugins
|
|
111
|
+
nomnom plugin setup Run setup for specific/all plugins
|
|
112
|
+
nomnom plugin create NAME Scaffold a new local plugin
|
|
113
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Releasing nomnom
|
|
2
|
+
|
|
3
|
+
This project is set up to publish to PyPI from GitHub Actions using PyPI Trusted
|
|
4
|
+
Publishing.
|
|
5
|
+
|
|
6
|
+
## One-Time Setup
|
|
7
|
+
|
|
8
|
+
1. Create a PyPI account for the maintainer if you do not already have one.
|
|
9
|
+
2. In PyPI, go to `Account settings` -> `Publishing`.
|
|
10
|
+
3. Add a pending trusted publisher with:
|
|
11
|
+
- PyPI project name: `nomnom-py`
|
|
12
|
+
- Owner: `MohammadKanaan`
|
|
13
|
+
- Repository: `nomnom-py`
|
|
14
|
+
- Workflow file: `publish.yml`
|
|
15
|
+
- Environment: `pypi`
|
|
16
|
+
4. In GitHub, create an environment named `pypi`.
|
|
17
|
+
5. Require manual approval for that environment before the publish job runs.
|
|
18
|
+
|
|
19
|
+
## Release Checklist
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv sync --dev
|
|
23
|
+
uv run pytest
|
|
24
|
+
uv run ruff check .
|
|
25
|
+
uv run mypy nomnom
|
|
26
|
+
uv build
|
|
27
|
+
uvx twine check dist/*
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Publish a Release
|
|
31
|
+
|
|
32
|
+
1. Update `[project].version` in `pyproject.toml`.
|
|
33
|
+
2. Commit the release changes.
|
|
34
|
+
3. Create and push a tag that matches the version:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git tag v1.0.0
|
|
38
|
+
git push origin v1.0.0
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
4. Approve the `pypi` environment in GitHub when the `Publish` workflow starts.
|
|
42
|
+
5. Confirm the release at `https://pypi.org/project/nomnom-py/`.
|
|
43
|
+
|
|
44
|
+
## Notes
|
|
45
|
+
|
|
46
|
+
- `dist/` should be treated as build output; rebuild it for every release.
|
|
47
|
+
- If you want to dry-run the pipeline before the first public release, publish to
|
|
48
|
+
TestPyPI manually instead of tagging production.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
Please do not open public GitHub issues for security problems.
|
|
6
|
+
|
|
7
|
+
Use GitHub's private vulnerability reporting flow if it is enabled for the repository. If that is not available, contact the maintainer privately through GitHub and include:
|
|
8
|
+
|
|
9
|
+
- a description of the issue
|
|
10
|
+
- affected versions or commit hashes
|
|
11
|
+
- reproduction steps or a proof of concept
|
|
12
|
+
- any suggested mitigation
|
|
13
|
+
|
|
14
|
+
I will acknowledge valid reports as quickly as possible and coordinate a fix before public disclosure.
|
|
15
|
+
|
|
16
|
+
## Supported Versions
|
|
17
|
+
|
|
18
|
+
Security fixes are best-effort and prioritized for the latest release on the `main` branch.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
2
|
+
|
|
3
|
+
from nomnom.effects import CreateFile, DeleteFile, EditAction, EditFile, Effect, EmitEvent, MoveFile
|
|
4
|
+
from nomnom.events import EventType, FileEvent
|
|
5
|
+
from nomnom.plugin import Plugin, SetupPlugin
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_version() -> str:
|
|
9
|
+
try:
|
|
10
|
+
return version("nomnom-py")
|
|
11
|
+
except PackageNotFoundError:
|
|
12
|
+
return "dev"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"Plugin",
|
|
17
|
+
"SetupPlugin",
|
|
18
|
+
"FileEvent",
|
|
19
|
+
"EventType",
|
|
20
|
+
"Effect",
|
|
21
|
+
"MoveFile",
|
|
22
|
+
"DeleteFile",
|
|
23
|
+
"CreateFile",
|
|
24
|
+
"EditFile",
|
|
25
|
+
"EmitEvent",
|
|
26
|
+
"EditAction",
|
|
27
|
+
"get_version",
|
|
28
|
+
]
|