Compare commits
11 Commits
0b5b73edc3
...
507eb8d711
Author | SHA1 | Date |
---|---|---|
Ferdinand Thiessen | 507eb8d711 | |
Ferdinand Thiessen | 693978a5f9 | |
Ferdinand Thiessen | 015ef353d9 | |
Ferdinand Thiessen | 0bfc551450 | |
Ferdinand Thiessen | 4248405462 | |
Ferdinand Thiessen | f5c7e59162 | |
Ferdinand Thiessen | 5cf54c1a08 | |
Ferdinand Thiessen | f2ea2a8fa5 | |
Ferdinand Thiessen | 4d972defdc | |
Ferdinand Thiessen | 6f35e17fba | |
Ferdinand Thiessen | 2f4472e708 |
|
@ -67,7 +67,8 @@ instance/
|
|||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
docs/
|
||||
# pdoc
|
||||
docs/html
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# Plugin Development
|
||||
|
||||
## File Structure
|
||||
|
||||
- your_plugin/
|
||||
- __init__.py
|
||||
- ...
|
||||
- migrations/ (optional)
|
||||
- ...
|
||||
- setup.cfg
|
||||
|
||||
The basic layout of a plugin is quite simple, you will only need the `setup.cfg` or `setup.py` and
|
||||
the package containing your plugin code, at lease a `__init__.py` file with your `Plugin` class.
|
||||
|
||||
If you use custom database tables you need to provide a `migrations` directory within your package,
|
||||
see next section.
|
||||
|
||||
## Database Tables / Migrations
|
||||
To allow upgrades of installed plugins, the database is versioned and handled
|
||||
through [Alembic](https://alembic.sqlalchemy.org/en/latest/index.html) migrations.
|
||||
Each plugin, which uses custom database tables, is represented as an other base.
|
||||
So you could simply follow the Alembic tutorial on [how to work with multiple bases](https://alembic.sqlalchemy.org/en/latest/branches.html#creating-a-labeled-base-revision).
|
||||
|
||||
A quick overview on how to work with migrations for your plugin:
|
||||
|
||||
$ flaschengeist db revision -m "Create my super plugin" \
|
||||
--head=base --branch-label=myplugin_name --version-path=your/plugin/migrations
|
||||
|
||||
This would add a new base named `myplugin_name`, which should be the same as the pypi name of you plugin.
|
||||
If your tables depend on an other plugin or a specific base version you could of cause add
|
||||
|
||||
--depends-on=VERSION
|
||||
|
||||
or
|
||||
|
||||
--depends-on=other_plugin
|
||||
|
||||
|
||||
### Plugin Removal and Database Tables
|
||||
As generic downgrades are most often hard to write, your plugin is not required to provide such functionallity.
|
||||
For Flaschengeist only instable versions provide meaningful downgrade migrations down to the latest stable version.
|
||||
|
||||
So this means if you do not provide downgrades you must at lease provide a series of migrations toward removal of
|
||||
the database tables in case the users wants to delete the plugin.
|
||||
|
||||
(base) ----> 1.0 <----> 1.1 <----> 1.2
|
||||
|
|
||||
--> removal
|
||||
|
||||
After the removal step the database is stamped to to "remove" your
|
||||
|
||||
## Useful Hooks
|
||||
There are some predefined hooks, which might get handy for you.
|
||||
|
||||
For more information, please refer to
|
||||
- `flaschengeist.utils.hook.HookBefore` and
|
||||
- `flaschengeist.utils.hook.HookAfter`
|
|
@ -8,7 +8,7 @@ import subprocess
|
|||
"--output",
|
||||
"-o",
|
||||
help="Documentation output path",
|
||||
default="./docs",
|
||||
default="./docs/html",
|
||||
type=click.Path(file_okay=False, path_type=pathlib.Path),
|
||||
)
|
||||
@click.pass_context
|
||||
|
|
|
@ -1,27 +1,7 @@
|
|||
"""Flaschengeist Plugins
|
||||
|
||||
## Custom database tables
|
||||
.. include:: docs/plugin_development.md
|
||||
|
||||
You can add tables by declaring them using the SQLAlchemy syntax,
|
||||
then use Alembic to generate migrations for your tables.
|
||||
This allows Flaschengeist to proper up- or downgrade the
|
||||
database tables if an user updates your plugin.
|
||||
|
||||
migrations have to be provided in a directory called `migrations`
|
||||
next to your plugin. E.G.
|
||||
|
||||
myplugin
|
||||
- __init__.py
|
||||
- other/
|
||||
- ...
|
||||
- migrations/
|
||||
|
||||
## Useful Hooks
|
||||
There are some predefined hooks, which might get handy for you.
|
||||
|
||||
For more information, please refer to
|
||||
- `flaschengeist.utils.hook.HookBefore` and
|
||||
- `flaschengeist.utils.hook.HookAfter`
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
|
|
Loading…
Reference in New Issue