# qgis-plugin-dev-tools
QGIS plugin development and packaging tools, which make managing runtime dependencies easy.
## Prerequisites
Your plugin package must be available to import from the python environment this tool is run in. For example, running `python -c "import your_plugin_package_name"` should not fail. Additionally, any dependency libraries must also be available in the python environment, so a dependency to `some_pypi_package` needs something like `pip install some_pypi_package` for this tool to work.
## Limitations
Bundling works by copying the code as-is and replacing the imports in all bundled files, so native library dependencies and other special cases might not work. To be safe, only depend on pure python libraries. Also verify the result zip works, since some import statements or `sys.modules` usage might not be supported.
## Setup
Install this library with `pip install qgis-plugin-dev-tools`.
Create a `pyproject.toml` tool section:
```toml
[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
```
If the plugin runtime depends on external libraries, add the distribution names to `runtime_requires` list as abstract dependencies.
```toml
[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
runtime_requires = [
"some_pypi_package"
]
```
If the plugin runtime dependencies have many dependencies themselves, it is possible to include those recursively with `auto_add_recursive_runtime_dependencies`. Alternatively, all the requirements can be listed in `runtime_requires`.
```toml
[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
runtime_requires = [
"some_pypi_package"
]
auto_add_recursive_runtime_dependencies = true
```
If the plugin runtime dependencies do not work with the aforementioned configuration, the dependencies can be added to the Python Path with `use_dangerous_vendor_sys_path_append` flag. This method might be **unsafe** if there are conflicts between dependency versions of different plugins.
```toml
[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
runtime_requires = [
"some_pypi_package_with_binary_files"
]
use_dangerous_vendor_sys_path_append = true
```
By default build version number is read from changelog top-most second level heading having format `## version anything`. This behaviour is configurable with `version_number_source` to use plugin package distribution metadata. Optionally, the version number can also be provided as an argument for the build script using `qpdt b --version 0.1.0-rc2`.
```toml
[tool.qgis_plugin_dev_tools]
plugin_package_name = "your_plugin_package_name"
version_number_source = "distribution" # or "changelog" (default if missing)
```
## Plugin packaging
Run `qgis-plugin-dev-tools build` (short `qpdt b`) to package the plugin and any runtime dependencies to a standard QGIS plugin zip file, that can be installed and published.
By default config is read from `pyproject.toml`, changelog notes from `CHANGELOG.md`, version from changelog, and package is created in a `dist` directory in the current working directory. Changelog contents and version number are inserted to the `metadata.txt` file, so the version and changelog sections do not need manual updates.
## Plugin publishing
Run `qgis-plugin-dev-tools publish <file>` (short `qpdt publish <file>`) to publish a previously built plugin zip file to QGIS plugin repository.
By default username and password are read from `QPDT_PUBLISH_USERNAME` and `QPDT_PUBLISH_PASSWORD` environment variables.
## Plugin development mode
Run `qgis-plugin-dev-tools start` (short `qpdt s`) to launch QGIS with the plugin installed and ready for development.
By default config is read from `pyproject.toml` and runtime config from `.env` in the current working directory. Extra environment files can be passed using `-e` flag. `.env` must configure the executable path, and may configure debugger, profile name and any extra runtime variables necessary for the plugin.
```sh
QGIS_EXECUTABLE_PATH= # path to qgis-bin/qgis-bin-ltr or .exe equivalents, necessary
# DEBUGGER_LIBRARY= # debugpy/pydevd to start a debugger on init, library must be installed to the environment
# DEVELOPMENT_PROFILE_NAME= # name of the profile that qgis is launched with, otherwise uses default
# QGIS_LOCALE= # locale code of QGIS, otherwise uses default
# QGIS_GUI_INI= # path to ini file containing QGIS UI customizations
# any other variables are added to the runtime QGIS environment
# SOMETHING=something
```
Development mode bootstraps the launched QGIS to have access to any packages available to the launching python environment, setups enviroment variables, configures a debugger, and installs and enables the developed plugin package.
Additionally editable installs for the plugin dependencies are supported. For example with a dependency to `some_pypi_package`, use `pip install -e /path/to/some_pypi_package` to provide `some_pypi_package` in editable mode from a local directory, and use [Plugin Reloader] to refresh new code when its changed on disk. This will also reload the declared dependencies.
### Developing multiple plugins
Development mode also enables using and developing multiple plugins easily if certain requirements are satisfied for all extra plugins:
* Extra plugin must be installable python packages
* See e.g. [Quickstart for setuptools]
* Extra plugin must have entry point in group "qgis_plugin_dev_tools"
* See for example: [Entry point usage with setuptools]
* Use plugin package name for entry point name
* Extra plugin needs to be installed in the same python environment where this tool is run in
Extra plugins are loaded on launch and reloaded together with the main plugin if [Plugin Reloader] is used.
You can disable plugin auto-load by using `pyproject.toml` configuration (for example when using a dependency, that also provides a plugin entrypoint):
```toml
[tool.qgis_plugin_dev_tools]
disabled_extra_plugins = [
"unwanted_plugin_package_name",
]
```
## Development of qgis-plugin-dev-tools
See [development readme](./DEVELOPMENT.md).
## License & copyright
Licensed under GNU GPL v3.0.
Copyright (C) 2022 [National Land Survey of Finland].
[Plugin Reloader]: https://plugins.qgis.org/plugins/plugin_reloader
[National Land Survey of Finland]: https://www.maanmittauslaitos.fi/en
[Quickstart for setuptools]: https://setuptools.pypa.io/en/latest/userguide/quickstart.html
[Entry point usage with setuptools]: https://setuptools.pypa.io/en/latest/userguide/entry_point.html#advertising-behavior
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.8.0] - 2024-08-23
- Feat: Add locale and ui ini options to be able to further customize development environment
## [0.7.0] - 2024-05-21
- Fix: Bundle contents by parsing pep-compliant distribution file catalog instead of possibly missing tool-specific top-level.txt
- Feat: Allow disabling auto-loaded entrypoint plugins
## [0.6.2] - 2023-09-27
- Fix: Fix issues with bundling requirements of the requirements recursively
## [0.6.1] - 2023-09-06
- update author email
## [0.6.0] - 2023-02-17
- Feat: Support dependencies having package references in .ui files
## [0.5.0] - 2022-11-09
- Feat: Add publish command to cli
- Fix: Support build without actually importing the code
- Fix: Preserve case for key names in metadata file
## [0.4.0] - 2022-11-01
- Feat: Add an option to get version from distribution metadata
- Fix: Rewrite imports correctly when dependency name is a prefix of the plugin package name
## [0.3.0] - 2022-09-02
- Feat: Add an option to append vendor package to the Python Path
- Feat: Add an option to bundle requirements of the requirements recursively
- Feat: Add module packages and .pyd files to the bundle if found
- Feat: Add version as an optional build argument
- Chore: Drop support from Python < 3.9
## [0.2.1] - 2022-07-07
- Fix: Correct some plain import rewrites
## [0.2.0] - 2022-06-13
- Feat: enable extra plugins in development mode
## [0.1.2] - 2022-05-30
- Fix: use UTF-8 encoding for file reads/writes
## [0.1.1] - 2022-05-16
- Fix: rewrite runtime requirement imports correctly
## [0.1.0] - 2022-05-12
- Initial release: `start` and `build` commands with minimal configuration options.
[0.1.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.1.0
[0.1.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.1.1
[0.1.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.1.2
[0.2.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.2.0
[0.2.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.2.1
[0.3.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.3.0
[0.4.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.4.0
[0.5.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.5.0
[0.6.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.0
[0.6.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.1
[0.6.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.2
[0.7.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.7.0
[0.8.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.8.0
Raw data
{
"_id": null,
"home_page": "https://github.com/nlsfi/qgis-plugin-dev-tools",
"name": "qgis-plugin-dev-tools",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "qgis",
"author": "National Land Survey of Finland",
"author_email": "os@nls.fi",
"download_url": "https://files.pythonhosted.org/packages/a8/b9/48cb8e6891023c52322a4ae1276ca1d1607e3a2aeadf9ac7eeb51a50108f/qgis_plugin_dev_tools-0.8.0.tar.gz",
"platform": null,
"description": "# qgis-plugin-dev-tools\n\nQGIS plugin development and packaging tools, which make managing runtime dependencies easy.\n\n## Prerequisites\n\nYour plugin package must be available to import from the python environment this tool is run in. For example, running `python -c \"import your_plugin_package_name\"` should not fail. Additionally, any dependency libraries must also be available in the python environment, so a dependency to `some_pypi_package` needs something like `pip install some_pypi_package` for this tool to work.\n\n## Limitations\n\nBundling works by copying the code as-is and replacing the imports in all bundled files, so native library dependencies and other special cases might not work. To be safe, only depend on pure python libraries. Also verify the result zip works, since some import statements or `sys.modules` usage might not be supported.\n\n## Setup\n\nInstall this library with `pip install qgis-plugin-dev-tools`.\n\nCreate a `pyproject.toml` tool section:\n\n```toml\n[tool.qgis_plugin_dev_tools]\nplugin_package_name = \"your_plugin_package_name\"\n```\n\nIf the plugin runtime depends on external libraries, add the distribution names to `runtime_requires` list as abstract dependencies.\n\n```toml\n[tool.qgis_plugin_dev_tools]\nplugin_package_name = \"your_plugin_package_name\"\nruntime_requires = [\n \"some_pypi_package\"\n]\n```\n\nIf the plugin runtime dependencies have many dependencies themselves, it is possible to include those recursively with `auto_add_recursive_runtime_dependencies`. Alternatively, all the requirements can be listed in `runtime_requires`.\n\n```toml\n[tool.qgis_plugin_dev_tools]\nplugin_package_name = \"your_plugin_package_name\"\nruntime_requires = [\n \"some_pypi_package\"\n]\nauto_add_recursive_runtime_dependencies = true\n```\n\nIf the plugin runtime dependencies do not work with the aforementioned configuration, the dependencies can be added to the Python Path with `use_dangerous_vendor_sys_path_append` flag. This method might be **unsafe** if there are conflicts between dependency versions of different plugins.\n\n```toml\n[tool.qgis_plugin_dev_tools]\nplugin_package_name = \"your_plugin_package_name\"\nruntime_requires = [\n \"some_pypi_package_with_binary_files\"\n]\nuse_dangerous_vendor_sys_path_append = true\n```\n\nBy default build version number is read from changelog top-most second level heading having format `## version anything`. This behaviour is configurable with `version_number_source` to use plugin package distribution metadata. Optionally, the version number can also be provided as an argument for the build script using `qpdt b --version 0.1.0-rc2`.\n\n```toml\n[tool.qgis_plugin_dev_tools]\nplugin_package_name = \"your_plugin_package_name\"\nversion_number_source = \"distribution\" # or \"changelog\" (default if missing)\n```\n\n## Plugin packaging\n\nRun `qgis-plugin-dev-tools build` (short `qpdt b`) to package the plugin and any runtime dependencies to a standard QGIS plugin zip file, that can be installed and published.\n\nBy default config is read from `pyproject.toml`, changelog notes from `CHANGELOG.md`, version from changelog, and package is created in a `dist` directory in the current working directory. Changelog contents and version number are inserted to the `metadata.txt` file, so the version and changelog sections do not need manual updates.\n\n## Plugin publishing\n\nRun `qgis-plugin-dev-tools publish <file>` (short `qpdt publish <file>`) to publish a previously built plugin zip file to QGIS plugin repository.\n\nBy default username and password are read from `QPDT_PUBLISH_USERNAME` and `QPDT_PUBLISH_PASSWORD` environment variables.\n\n## Plugin development mode\n\nRun `qgis-plugin-dev-tools start` (short `qpdt s`) to launch QGIS with the plugin installed and ready for development.\n\nBy default config is read from `pyproject.toml` and runtime config from `.env` in the current working directory. Extra environment files can be passed using `-e` flag. `.env` must configure the executable path, and may configure debugger, profile name and any extra runtime variables necessary for the plugin.\n\n```sh\nQGIS_EXECUTABLE_PATH= # path to qgis-bin/qgis-bin-ltr or .exe equivalents, necessary\n# DEBUGGER_LIBRARY= # debugpy/pydevd to start a debugger on init, library must be installed to the environment\n# DEVELOPMENT_PROFILE_NAME= # name of the profile that qgis is launched with, otherwise uses default\n# QGIS_LOCALE= # locale code of QGIS, otherwise uses default\n# QGIS_GUI_INI= # path to ini file containing QGIS UI customizations\n\n# any other variables are added to the runtime QGIS environment\n# SOMETHING=something\n```\n\nDevelopment mode bootstraps the launched QGIS to have access to any packages available to the launching python environment, setups enviroment variables, configures a debugger, and installs and enables the developed plugin package.\n\nAdditionally editable installs for the plugin dependencies are supported. For example with a dependency to `some_pypi_package`, use `pip install -e /path/to/some_pypi_package` to provide `some_pypi_package` in editable mode from a local directory, and use [Plugin Reloader] to refresh new code when its changed on disk. This will also reload the declared dependencies.\n\n### Developing multiple plugins\n\nDevelopment mode also enables using and developing multiple plugins easily if certain requirements are satisfied for all extra plugins:\n\n* Extra plugin must be installable python packages\n * See e.g. [Quickstart for setuptools]\n* Extra plugin must have entry point in group \"qgis_plugin_dev_tools\"\n * See for example: [Entry point usage with setuptools]\n * Use plugin package name for entry point name\n* Extra plugin needs to be installed in the same python environment where this tool is run in\n\nExtra plugins are loaded on launch and reloaded together with the main plugin if [Plugin Reloader] is used.\n\nYou can disable plugin auto-load by using `pyproject.toml` configuration (for example when using a dependency, that also provides a plugin entrypoint):\n\n```toml\n[tool.qgis_plugin_dev_tools]\ndisabled_extra_plugins = [\n \"unwanted_plugin_package_name\",\n]\n```\n\n## Development of qgis-plugin-dev-tools\n\nSee [development readme](./DEVELOPMENT.md).\n\n## License & copyright\n\nLicensed under GNU GPL v3.0.\n\nCopyright (C) 2022 [National Land Survey of Finland].\n\n[Plugin Reloader]: https://plugins.qgis.org/plugins/plugin_reloader\n[National Land Survey of Finland]: https://www.maanmittauslaitos.fi/en\n[Quickstart for setuptools]: https://setuptools.pypa.io/en/latest/userguide/quickstart.html\n[Entry point usage with setuptools]: https://setuptools.pypa.io/en/latest/userguide/entry_point.html#advertising-behavior\n\n# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.8.0] - 2024-08-23\n\n- Feat: Add locale and ui ini options to be able to further customize development environment\n\n## [0.7.0] - 2024-05-21\n\n- Fix: Bundle contents by parsing pep-compliant distribution file catalog instead of possibly missing tool-specific top-level.txt\n- Feat: Allow disabling auto-loaded entrypoint plugins\n\n## [0.6.2] - 2023-09-27\n\n- Fix: Fix issues with bundling requirements of the requirements recursively\n\n## [0.6.1] - 2023-09-06\n\n- update author email\n\n## [0.6.0] - 2023-02-17\n\n- Feat: Support dependencies having package references in .ui files\n\n## [0.5.0] - 2022-11-09\n\n- Feat: Add publish command to cli\n- Fix: Support build without actually importing the code\n- Fix: Preserve case for key names in metadata file\n\n## [0.4.0] - 2022-11-01\n\n- Feat: Add an option to get version from distribution metadata\n- Fix: Rewrite imports correctly when dependency name is a prefix of the plugin package name\n\n## [0.3.0] - 2022-09-02\n\n- Feat: Add an option to append vendor package to the Python Path\n- Feat: Add an option to bundle requirements of the requirements recursively\n- Feat: Add module packages and .pyd files to the bundle if found\n- Feat: Add version as an optional build argument\n- Chore: Drop support from Python < 3.9\n\n## [0.2.1] - 2022-07-07\n\n- Fix: Correct some plain import rewrites\n\n## [0.2.0] - 2022-06-13\n\n- Feat: enable extra plugins in development mode\n\n## [0.1.2] - 2022-05-30\n\n- Fix: use UTF-8 encoding for file reads/writes\n\n## [0.1.1] - 2022-05-16\n\n- Fix: rewrite runtime requirement imports correctly\n\n## [0.1.0] - 2022-05-12\n\n- Initial release: `start` and `build` commands with minimal configuration options.\n\n[0.1.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.1.0\n[0.1.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.1.1\n[0.1.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.1.2\n[0.2.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.2.0\n[0.2.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.2.1\n[0.3.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.3.0\n[0.4.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.4.0\n[0.5.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.5.0\n[0.6.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.0\n[0.6.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.1\n[0.6.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.2\n[0.7.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.7.0\n[0.8.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.8.0\n",
"bugtrack_url": null,
"license": "GNU GPL v3.0",
"summary": "QGIS plugin development and packaging tools, which make managing runtime dependencies easy.",
"version": "0.8.0",
"project_urls": {
"Changelog": "https://github.com/nlsfi/qgis-plugin-dev-tools/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/nlsfi/qgis-plugin-dev-tools"
},
"split_keywords": [
"qgis"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "8e6f0f798a9a82b0934249ae4268548159bd6beaa1c2910327ccb731086eef07",
"md5": "49570298297324bc689964cb6e5c4e92",
"sha256": "a43068867ae4c3dbf766a975492449ef5627157614b6aeb5f1739f31189da84b"
},
"downloads": -1,
"filename": "qgis_plugin_dev_tools-0.8.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "49570298297324bc689964cb6e5c4e92",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 45581,
"upload_time": "2024-08-23T08:14:31",
"upload_time_iso_8601": "2024-08-23T08:14:31.404603Z",
"url": "https://files.pythonhosted.org/packages/8e/6f/0f798a9a82b0934249ae4268548159bd6beaa1c2910327ccb731086eef07/qgis_plugin_dev_tools-0.8.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a8b948cb8e6891023c52322a4ae1276ca1d1607e3a2aeadf9ac7eeb51a50108f",
"md5": "a50bec37db4db1d29c3148761c9e7812",
"sha256": "1ed92918e23017ef122ac111ed8abbca338cf1318f2a55b7fd5d1eee2459b0a0"
},
"downloads": -1,
"filename": "qgis_plugin_dev_tools-0.8.0.tar.gz",
"has_sig": false,
"md5_digest": "a50bec37db4db1d29c3148761c9e7812",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 39881,
"upload_time": "2024-08-23T08:14:33",
"upload_time_iso_8601": "2024-08-23T08:14:33.141792Z",
"url": "https://files.pythonhosted.org/packages/a8/b9/48cb8e6891023c52322a4ae1276ca1d1607e3a2aeadf9ac7eeb51a50108f/qgis_plugin_dev_tools-0.8.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-23 08:14:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "nlsfi",
"github_project": "qgis-plugin-dev-tools",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "qgis-plugin-dev-tools"
}