qgis-plugin-dev-tools 0.7.0__tar.gz → 0.9.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.
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/CHANGELOG.md +10 -0
- {qgis_plugin_dev_tools-0.7.0/src/qgis_plugin_dev_tools.egg-info → qgis_plugin_dev_tools-0.9.0}/PKG-INFO +21 -1
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/README.md +10 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/__init__.py +1 -1
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/build/__init__.py +2 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/build/packaging.py +53 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/cli/__init__.py +2 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/config/__init__.py +12 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/config/dotenv.py +7 -1
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/config/pyproject.py +2 -1
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/start/__init__.py +2 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/start/config.py +2 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/start/launch.py +12 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0/src/qgis_plugin_dev_tools.egg-info}/PKG-INFO +21 -1
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/test/test_build.py +105 -16
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/test/test_read_distributions.py +0 -2
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/test/test_read_dotenv.py +2 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/LICENSE +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/MANIFEST.in +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/pyproject.toml +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/setup.cfg +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/setup.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/__main__.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/build/changelog_parser.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/build/distribution.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/build/metadata.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/build/rewrite_imports.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/publish/__init__.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/py.typed +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/start/bootstrap/__init__.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/start/bootstrap/template.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/start/daemon_server.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/utils/__init__.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/utils/distributions.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools.egg-info/SOURCES.txt +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools.egg-info/dependency_links.txt +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools.egg-info/entry_points.txt +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools.egg-info/requires.txt +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools.egg-info/top_level.txt +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/test/test_read_pyproject.py +0 -0
- {qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/test/test_rewrite_imports.py +0 -0
|
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
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).
|
|
6
6
|
|
|
7
|
+
## [0.9.0] - 2025-01-08
|
|
8
|
+
|
|
9
|
+
- Feat: Copy license into the plugin zip while deploying
|
|
10
|
+
|
|
11
|
+
## [0.8.0] - 2024-08-23
|
|
12
|
+
|
|
13
|
+
- Feat: Add locale and ui ini options to be able to further customize development environment
|
|
14
|
+
|
|
7
15
|
## [0.7.0] - 2024-05-21
|
|
8
16
|
|
|
9
17
|
- Fix: Bundle contents by parsing pep-compliant distribution file catalog instead of possibly missing tool-specific top-level.txt
|
|
@@ -72,3 +80,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
72
80
|
[0.6.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.1
|
|
73
81
|
[0.6.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.2
|
|
74
82
|
[0.7.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.7.0
|
|
83
|
+
[0.8.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.8.0
|
|
84
|
+
[0.9.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.9.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qgis-plugin-dev-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: QGIS plugin development and packaging tools, which make managing runtime dependencies easy.
|
|
5
5
|
Home-page: https://github.com/nlsfi/qgis-plugin-dev-tools
|
|
6
6
|
Author: National Land Survey of Finland
|
|
@@ -91,6 +91,14 @@ plugin_package_name = "your_plugin_package_name"
|
|
|
91
91
|
version_number_source = "distribution" # or "changelog" (default if missing)
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
QGIS plugins are required to have a LICENSE file included in the plugin package. However, usually it is more convenient to keep the license file in the root of the repository. LICENSE can be copied automatically to the plugin zip while packaging if such file is found. A relative path to the license file can also be configured with `license_file_path` option.
|
|
95
|
+
|
|
96
|
+
```toml
|
|
97
|
+
[tool.qgis_plugin_dev_tools]
|
|
98
|
+
plugin_package_name = "your_plugin_package_name"
|
|
99
|
+
license_file_path = "docs/my-license.md"
|
|
100
|
+
```
|
|
101
|
+
|
|
94
102
|
## Plugin packaging
|
|
95
103
|
|
|
96
104
|
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.
|
|
@@ -113,6 +121,8 @@ By default config is read from `pyproject.toml` and runtime config from `.env` i
|
|
|
113
121
|
QGIS_EXECUTABLE_PATH= # path to qgis-bin/qgis-bin-ltr or .exe equivalents, necessary
|
|
114
122
|
# DEBUGGER_LIBRARY= # debugpy/pydevd to start a debugger on init, library must be installed to the environment
|
|
115
123
|
# DEVELOPMENT_PROFILE_NAME= # name of the profile that qgis is launched with, otherwise uses default
|
|
124
|
+
# QGIS_LOCALE= # locale code of QGIS, otherwise uses default
|
|
125
|
+
# QGIS_GUI_INI= # path to ini file containing QGIS UI customizations
|
|
116
126
|
|
|
117
127
|
# any other variables are added to the runtime QGIS environment
|
|
118
128
|
# SOMETHING=something
|
|
@@ -165,6 +175,14 @@ All notable changes to this project will be documented in this file.
|
|
|
165
175
|
|
|
166
176
|
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).
|
|
167
177
|
|
|
178
|
+
## [0.9.0] - 2025-01-08
|
|
179
|
+
|
|
180
|
+
- Feat: Copy license into the plugin zip while deploying
|
|
181
|
+
|
|
182
|
+
## [0.8.0] - 2024-08-23
|
|
183
|
+
|
|
184
|
+
- Feat: Add locale and ui ini options to be able to further customize development environment
|
|
185
|
+
|
|
168
186
|
## [0.7.0] - 2024-05-21
|
|
169
187
|
|
|
170
188
|
- Fix: Bundle contents by parsing pep-compliant distribution file catalog instead of possibly missing tool-specific top-level.txt
|
|
@@ -233,3 +251,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
233
251
|
[0.6.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.1
|
|
234
252
|
[0.6.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.2
|
|
235
253
|
[0.7.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.7.0
|
|
254
|
+
[0.8.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.8.0
|
|
255
|
+
[0.9.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.9.0
|
|
@@ -61,6 +61,14 @@ plugin_package_name = "your_plugin_package_name"
|
|
|
61
61
|
version_number_source = "distribution" # or "changelog" (default if missing)
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
QGIS plugins are required to have a LICENSE file included in the plugin package. However, usually it is more convenient to keep the license file in the root of the repository. LICENSE can be copied automatically to the plugin zip while packaging if such file is found. A relative path to the license file can also be configured with `license_file_path` option.
|
|
65
|
+
|
|
66
|
+
```toml
|
|
67
|
+
[tool.qgis_plugin_dev_tools]
|
|
68
|
+
plugin_package_name = "your_plugin_package_name"
|
|
69
|
+
license_file_path = "docs/my-license.md"
|
|
70
|
+
```
|
|
71
|
+
|
|
64
72
|
## Plugin packaging
|
|
65
73
|
|
|
66
74
|
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.
|
|
@@ -83,6 +91,8 @@ By default config is read from `pyproject.toml` and runtime config from `.env` i
|
|
|
83
91
|
QGIS_EXECUTABLE_PATH= # path to qgis-bin/qgis-bin-ltr or .exe equivalents, necessary
|
|
84
92
|
# DEBUGGER_LIBRARY= # debugpy/pydevd to start a debugger on init, library must be installed to the environment
|
|
85
93
|
# DEVELOPMENT_PROFILE_NAME= # name of the profile that qgis is launched with, otherwise uses default
|
|
94
|
+
# QGIS_LOCALE= # locale code of QGIS, otherwise uses default
|
|
95
|
+
# QGIS_GUI_INI= # path to ini file containing QGIS UI customizations
|
|
86
96
|
|
|
87
97
|
# any other variables are added to the runtime QGIS environment
|
|
88
98
|
# SOMETHING=something
|
|
@@ -35,6 +35,7 @@ from qgis_plugin_dev_tools.build.metadata import update_metadata_file
|
|
|
35
35
|
from qgis_plugin_dev_tools.build.packaging import (
|
|
36
36
|
copy_plugin_code,
|
|
37
37
|
copy_runtime_requirements,
|
|
38
|
+
copy_license,
|
|
38
39
|
)
|
|
39
40
|
from qgis_plugin_dev_tools.config import DevToolsConfig, VersionNumberSource
|
|
40
41
|
|
|
@@ -84,6 +85,7 @@ def make_plugin_zip(
|
|
|
84
85
|
changelog_contents,
|
|
85
86
|
)
|
|
86
87
|
copy_runtime_requirements(dev_tools_config, build_directory_path)
|
|
88
|
+
copy_license(dev_tools_config, build_directory_path)
|
|
87
89
|
|
|
88
90
|
LOGGER.debug("creating built plugin zip file from build directory")
|
|
89
91
|
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
import logging
|
|
21
21
|
import shutil
|
|
22
22
|
import sys
|
|
23
|
+
from typing import Generator, Optional
|
|
24
|
+
|
|
23
25
|
from importlib_metadata import Distribution
|
|
24
26
|
from pathlib import Path
|
|
25
27
|
|
|
@@ -133,6 +135,45 @@ def copy_runtime_requirements(
|
|
|
133
135
|
)
|
|
134
136
|
|
|
135
137
|
|
|
138
|
+
def copy_license(dev_tools_config: DevToolsConfig, build_directory_path: Path) -> None:
|
|
139
|
+
plugin_build_path = build_directory_path / dev_tools_config.plugin_package_name
|
|
140
|
+
target_license_file = plugin_build_path / "LICENSE"
|
|
141
|
+
license_file = dev_tools_config.license_file_path
|
|
142
|
+
if license_file is not None:
|
|
143
|
+
if not license_file.exists():
|
|
144
|
+
LOGGER.error(
|
|
145
|
+
f"Configured license file "
|
|
146
|
+
f"{license_file} "
|
|
147
|
+
f"does not exist. Check the configuration."
|
|
148
|
+
)
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
if target_license_file.exists():
|
|
152
|
+
LOGGER.warning(
|
|
153
|
+
f"Overwriting existing license {target_license_file} "
|
|
154
|
+
f"with configured license {license_file}"
|
|
155
|
+
)
|
|
156
|
+
LOGGER.debug(f"Copying license file {license_file} to {build_directory_path}")
|
|
157
|
+
shutil.copy(license_file, target_license_file)
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
if target_license_file.exists():
|
|
161
|
+
LOGGER.debug(f"Existing license file {target_license_file} found.")
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
# Try finding the license
|
|
165
|
+
license_file = _find_existing_license_file(dev_tools_config.pyproject_path)
|
|
166
|
+
if not license_file:
|
|
167
|
+
LOGGER.warning(
|
|
168
|
+
"Cannot copy LICENSE file since it does not exist. "
|
|
169
|
+
"Configure valid LICENSE file with license_file_path in pyproject.toml"
|
|
170
|
+
)
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
LOGGER.debug(f"Copying license file {license_file} to {build_directory_path}")
|
|
174
|
+
shutil.copy(license_file, target_license_file)
|
|
175
|
+
|
|
176
|
+
|
|
136
177
|
def _copy_distribution_files(
|
|
137
178
|
distribution: Distribution,
|
|
138
179
|
top_level_names: set[str],
|
|
@@ -190,3 +231,15 @@ def _copy_distribution_files(
|
|
|
190
231
|
src=original_path,
|
|
191
232
|
dst=new_path,
|
|
192
233
|
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def _find_existing_license_file(search_path: Path) -> Optional[Path]:
|
|
237
|
+
def generate_license_candidates() -> Generator[Path, None, None]:
|
|
238
|
+
for base_name in ("LICENSE", "license"):
|
|
239
|
+
for extension in ("", ".md", ".MD"):
|
|
240
|
+
yield search_path / f"{base_name}{extension}"
|
|
241
|
+
|
|
242
|
+
for potential_path in generate_license_candidates():
|
|
243
|
+
if potential_path.exists():
|
|
244
|
+
return potential_path
|
|
245
|
+
return None
|
|
@@ -54,6 +54,8 @@ def start(dotenv_file_paths: list[Path]) -> None:
|
|
|
54
54
|
DevelopmentModeConfig(
|
|
55
55
|
qgis_executable_path=dotenv_config.QGIS_EXECUTABLE_PATH,
|
|
56
56
|
profile_name=dotenv_config.DEVELOPMENT_PROFILE_NAME,
|
|
57
|
+
locale=dotenv_config.QGIS_LOCALE,
|
|
58
|
+
ui_ini=dotenv_config.QGIS_GUI_INI,
|
|
57
59
|
runtime_environment=dotenv_config.runtime_environment,
|
|
58
60
|
runtime_library_paths=[Path(p) for p in sys.path],
|
|
59
61
|
plugin_package_path=dev_tools_config.plugin_package_path,
|
|
@@ -21,6 +21,7 @@ from collections import ChainMap
|
|
|
21
21
|
from enum import Enum, auto
|
|
22
22
|
from importlib.util import find_spec
|
|
23
23
|
from pathlib import Path
|
|
24
|
+
from typing import Optional
|
|
24
25
|
|
|
25
26
|
from importlib_metadata import Distribution, distribution
|
|
26
27
|
from packaging.requirements import Requirement
|
|
@@ -42,6 +43,7 @@ class VersionNumberSource(Enum):
|
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
class DevToolsConfig:
|
|
46
|
+
pyproject_path: Path
|
|
45
47
|
plugin_package_name: str
|
|
46
48
|
plugin_package_path: Path
|
|
47
49
|
runtime_distributions: list[Distribution]
|
|
@@ -49,9 +51,11 @@ class DevToolsConfig:
|
|
|
49
51
|
append_distributions_to_path: bool
|
|
50
52
|
version_number_source: VersionNumberSource
|
|
51
53
|
disabled_extra_plugins: list[str]
|
|
54
|
+
license_file_path: Optional[Path]
|
|
52
55
|
|
|
53
56
|
def __init__( # noqa: PLR0913
|
|
54
57
|
self,
|
|
58
|
+
pyproject_path: Path,
|
|
55
59
|
plugin_package_name: str,
|
|
56
60
|
runtime_requires: list[str],
|
|
57
61
|
changelog_file_path: Path,
|
|
@@ -59,6 +63,7 @@ class DevToolsConfig:
|
|
|
59
63
|
auto_add_recursive_runtime_dependencies: bool,
|
|
60
64
|
version_number_source: VersionNumberSource,
|
|
61
65
|
disabled_extra_plugins: list[str],
|
|
66
|
+
license_file_path: Optional[Path],
|
|
62
67
|
) -> None:
|
|
63
68
|
plugin_package_spec = find_spec(plugin_package_name)
|
|
64
69
|
if plugin_package_spec is None or plugin_package_spec.origin is None:
|
|
@@ -66,6 +71,7 @@ class DevToolsConfig:
|
|
|
66
71
|
f"could not find {plugin_package_name=} in the current environment"
|
|
67
72
|
)
|
|
68
73
|
|
|
74
|
+
self.pyproject_path = pyproject_path
|
|
69
75
|
self.plugin_package_path = Path(plugin_package_spec.origin).parent
|
|
70
76
|
self.plugin_package_name = plugin_package_name
|
|
71
77
|
# TODO: check versions are satisfied?
|
|
@@ -77,6 +83,7 @@ class DevToolsConfig:
|
|
|
77
83
|
self.version_number_source = version_number_source
|
|
78
84
|
self.extra_runtime_distributions = []
|
|
79
85
|
self.disabled_extra_plugins = disabled_extra_plugins
|
|
86
|
+
self.license_file_path = license_file_path
|
|
80
87
|
|
|
81
88
|
if auto_add_recursive_runtime_dependencies:
|
|
82
89
|
# Add the requirements of the distributions as well
|
|
@@ -98,6 +105,7 @@ class DevToolsConfig:
|
|
|
98
105
|
def from_pyproject_config(pyproject_file_path: Path) -> "DevToolsConfig":
|
|
99
106
|
pyproject_config = read_pyproject_config(pyproject_file_path)
|
|
100
107
|
return DevToolsConfig(
|
|
108
|
+
pyproject_path=pyproject_file_path,
|
|
101
109
|
plugin_package_name=pyproject_config.plugin_package_name,
|
|
102
110
|
runtime_requires=pyproject_config.runtime_requires,
|
|
103
111
|
# TODO: allow setting path in pyproject file?
|
|
@@ -112,4 +120,8 @@ class DevToolsConfig:
|
|
|
112
120
|
pyproject_config.version_number_source
|
|
113
121
|
),
|
|
114
122
|
disabled_extra_plugins=pyproject_config.disabled_extra_plugins,
|
|
123
|
+
license_file_path=pyproject_file_path.parent
|
|
124
|
+
/ pyproject_config.license_file_path
|
|
125
|
+
if pyproject_config.license_file_path
|
|
126
|
+
else None,
|
|
115
127
|
)
|
|
@@ -34,14 +34,18 @@ class DotenvConfig:
|
|
|
34
34
|
QGIS_EXECUTABLE_PATH: Path
|
|
35
35
|
DEBUGGER_LIBRARY: Optional[str]
|
|
36
36
|
DEVELOPMENT_PROFILE_NAME: Optional[str]
|
|
37
|
+
QGIS_LOCALE: Optional[str]
|
|
38
|
+
QGIS_GUI_INI: Optional[str]
|
|
37
39
|
runtime_environment: dict[str, str]
|
|
38
40
|
|
|
39
|
-
def __init__(
|
|
41
|
+
def __init__( # noqa: PLR0913
|
|
40
42
|
self,
|
|
41
43
|
*,
|
|
42
44
|
QGIS_EXECUTABLE_PATH: str, # noqa: N803
|
|
43
45
|
DEBUGGER_LIBRARY: Optional[str] = None, # noqa: N803
|
|
44
46
|
DEVELOPMENT_PROFILE_NAME: Optional[str] = None, # noqa: N803
|
|
47
|
+
QGIS_LOCALE: Optional[str] = None, # noqa: N803
|
|
48
|
+
QGIS_GUI_INI: Optional[str] = None, # noqa: N803
|
|
45
49
|
**other_vars: str,
|
|
46
50
|
) -> None:
|
|
47
51
|
self.QGIS_EXECUTABLE_PATH = Path(QGIS_EXECUTABLE_PATH)
|
|
@@ -51,6 +55,8 @@ class DotenvConfig:
|
|
|
51
55
|
)
|
|
52
56
|
self.DEBUGGER_LIBRARY = DEBUGGER_LIBRARY
|
|
53
57
|
self.DEVELOPMENT_PROFILE_NAME = DEVELOPMENT_PROFILE_NAME
|
|
58
|
+
self.QGIS_LOCALE = QGIS_LOCALE
|
|
59
|
+
self.QGIS_GUI_INI = QGIS_GUI_INI
|
|
54
60
|
self.runtime_environment = other_vars
|
|
55
61
|
|
|
56
62
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import logging
|
|
21
21
|
from dataclasses import dataclass, field
|
|
22
22
|
from pathlib import Path
|
|
23
|
-
from typing import Literal, Union
|
|
23
|
+
from typing import Literal, Optional, Union
|
|
24
24
|
|
|
25
25
|
import tomli
|
|
26
26
|
|
|
@@ -43,6 +43,7 @@ class PyprojectConfig:
|
|
|
43
43
|
Literal["changelog"], Literal["distribution"]
|
|
44
44
|
] = "changelog"
|
|
45
45
|
disabled_extra_plugins: list[str] = field(default_factory=list)
|
|
46
|
+
license_file_path: Optional[str] = None
|
|
46
47
|
|
|
47
48
|
def __post_init__(self) -> None:
|
|
48
49
|
if self.version_number_source not in ["changelog", "distribution"]:
|
|
@@ -42,6 +42,8 @@ def launch_development_qgis(
|
|
|
42
42
|
development_mode_config.qgis_executable_path,
|
|
43
43
|
bootstrap_file_path,
|
|
44
44
|
development_mode_config.profile_name,
|
|
45
|
+
development_mode_config.locale,
|
|
46
|
+
development_mode_config.ui_ini,
|
|
45
47
|
)
|
|
46
48
|
|
|
47
49
|
LOGGER.info("waiting for qgis to connect")
|
|
@@ -26,6 +26,8 @@ from typing import Optional
|
|
|
26
26
|
class DevelopmentModeConfig:
|
|
27
27
|
qgis_executable_path: Path
|
|
28
28
|
profile_name: Optional[str]
|
|
29
|
+
locale: Optional[str]
|
|
30
|
+
ui_ini: Optional[str]
|
|
29
31
|
runtime_environment: dict[str, str]
|
|
30
32
|
runtime_library_paths: list[Path]
|
|
31
33
|
plugin_package_path: Path
|
|
@@ -29,6 +29,8 @@ def launch_qgis_with_bootstrap_script(
|
|
|
29
29
|
qgis_executable_path: Path,
|
|
30
30
|
bootstrap_script_path: Path,
|
|
31
31
|
profile_name: Optional[str],
|
|
32
|
+
locale: Optional[str],
|
|
33
|
+
ui_ini: Optional[str],
|
|
32
34
|
) -> None:
|
|
33
35
|
args = [
|
|
34
36
|
str(qgis_executable_path),
|
|
@@ -42,6 +44,16 @@ def launch_qgis_with_bootstrap_script(
|
|
|
42
44
|
else:
|
|
43
45
|
LOGGER.info("using default profile name")
|
|
44
46
|
|
|
47
|
+
if locale:
|
|
48
|
+
LOGGER.info("using locale name %s", locale)
|
|
49
|
+
args.extend(["--lang", locale])
|
|
50
|
+
else:
|
|
51
|
+
LOGGER.info("using default locale")
|
|
52
|
+
|
|
53
|
+
if ui_ini:
|
|
54
|
+
LOGGER.info("using ui ini file from path %s", ui_ini)
|
|
55
|
+
args.extend(["--customizationfile", ui_ini])
|
|
56
|
+
|
|
45
57
|
LOGGER.debug("launch command args %s", args)
|
|
46
58
|
|
|
47
59
|
process = Popen(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qgis-plugin-dev-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: QGIS plugin development and packaging tools, which make managing runtime dependencies easy.
|
|
5
5
|
Home-page: https://github.com/nlsfi/qgis-plugin-dev-tools
|
|
6
6
|
Author: National Land Survey of Finland
|
|
@@ -91,6 +91,14 @@ plugin_package_name = "your_plugin_package_name"
|
|
|
91
91
|
version_number_source = "distribution" # or "changelog" (default if missing)
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
QGIS plugins are required to have a LICENSE file included in the plugin package. However, usually it is more convenient to keep the license file in the root of the repository. LICENSE can be copied automatically to the plugin zip while packaging if such file is found. A relative path to the license file can also be configured with `license_file_path` option.
|
|
95
|
+
|
|
96
|
+
```toml
|
|
97
|
+
[tool.qgis_plugin_dev_tools]
|
|
98
|
+
plugin_package_name = "your_plugin_package_name"
|
|
99
|
+
license_file_path = "docs/my-license.md"
|
|
100
|
+
```
|
|
101
|
+
|
|
94
102
|
## Plugin packaging
|
|
95
103
|
|
|
96
104
|
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.
|
|
@@ -113,6 +121,8 @@ By default config is read from `pyproject.toml` and runtime config from `.env` i
|
|
|
113
121
|
QGIS_EXECUTABLE_PATH= # path to qgis-bin/qgis-bin-ltr or .exe equivalents, necessary
|
|
114
122
|
# DEBUGGER_LIBRARY= # debugpy/pydevd to start a debugger on init, library must be installed to the environment
|
|
115
123
|
# DEVELOPMENT_PROFILE_NAME= # name of the profile that qgis is launched with, otherwise uses default
|
|
124
|
+
# QGIS_LOCALE= # locale code of QGIS, otherwise uses default
|
|
125
|
+
# QGIS_GUI_INI= # path to ini file containing QGIS UI customizations
|
|
116
126
|
|
|
117
127
|
# any other variables are added to the runtime QGIS environment
|
|
118
128
|
# SOMETHING=something
|
|
@@ -165,6 +175,14 @@ All notable changes to this project will be documented in this file.
|
|
|
165
175
|
|
|
166
176
|
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).
|
|
167
177
|
|
|
178
|
+
## [0.9.0] - 2025-01-08
|
|
179
|
+
|
|
180
|
+
- Feat: Copy license into the plugin zip while deploying
|
|
181
|
+
|
|
182
|
+
## [0.8.0] - 2024-08-23
|
|
183
|
+
|
|
184
|
+
- Feat: Add locale and ui ini options to be able to further customize development environment
|
|
185
|
+
|
|
168
186
|
## [0.7.0] - 2024-05-21
|
|
169
187
|
|
|
170
188
|
- Fix: Bundle contents by parsing pep-compliant distribution file catalog instead of possibly missing tool-specific top-level.txt
|
|
@@ -233,3 +251,5 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
233
251
|
[0.6.1]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.1
|
|
234
252
|
[0.6.2]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.6.2
|
|
235
253
|
[0.7.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.7.0
|
|
254
|
+
[0.8.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.8.0
|
|
255
|
+
[0.9.0]: https://github.com/nlsfi/qgis-plugin-dev-tools/releases/tag/v0.9.0
|
|
@@ -5,7 +5,7 @@ import zipfile
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
|
-
from qgis_plugin_dev_tools.build import make_plugin_zip
|
|
8
|
+
from qgis_plugin_dev_tools.build import copy_license, make_plugin_zip
|
|
9
9
|
from qgis_plugin_dev_tools.config import DevToolsConfig, VersionNumberSource
|
|
10
10
|
|
|
11
11
|
|
|
@@ -49,6 +49,9 @@ def plugin_dir(tmp_path: Path) -> Path:
|
|
|
49
49
|
main_file = plugin_dir / "__init__.py"
|
|
50
50
|
main_file.touch()
|
|
51
51
|
|
|
52
|
+
license_file = tmp_path / "LICENSE"
|
|
53
|
+
license_file.touch()
|
|
54
|
+
|
|
52
55
|
os.chdir(tmp_path.resolve())
|
|
53
56
|
sys.path.append(tmp_path.resolve().as_posix())
|
|
54
57
|
|
|
@@ -56,10 +59,11 @@ def plugin_dir(tmp_path: Path) -> Path:
|
|
|
56
59
|
|
|
57
60
|
|
|
58
61
|
@pytest.fixture()
|
|
59
|
-
def dev_tools_config(plugin_dir: Path) -> DevToolsConfig:
|
|
62
|
+
def dev_tools_config(tmp_path: Path, plugin_dir: Path) -> DevToolsConfig:
|
|
60
63
|
from qgis_plugin_dev_tools.config import DevToolsConfig
|
|
61
64
|
|
|
62
65
|
return DevToolsConfig(
|
|
66
|
+
pyproject_path=tmp_path,
|
|
63
67
|
plugin_package_name="Plugin",
|
|
64
68
|
runtime_requires=["pytest"],
|
|
65
69
|
changelog_file_path=plugin_dir / "CHANGELOG.md",
|
|
@@ -67,14 +71,18 @@ def dev_tools_config(plugin_dir: Path) -> DevToolsConfig:
|
|
|
67
71
|
auto_add_recursive_runtime_dependencies=True,
|
|
68
72
|
version_number_source=VersionNumberSource.CHANGELOG,
|
|
69
73
|
disabled_extra_plugins=[],
|
|
74
|
+
license_file_path=None,
|
|
70
75
|
)
|
|
71
76
|
|
|
72
77
|
|
|
73
78
|
@pytest.fixture()
|
|
74
|
-
def dev_tools_config_with_duplicate_dependencies(
|
|
79
|
+
def dev_tools_config_with_duplicate_dependencies(
|
|
80
|
+
tmp_path: Path, plugin_dir: Path
|
|
81
|
+
) -> DevToolsConfig:
|
|
75
82
|
from qgis_plugin_dev_tools.config import DevToolsConfig
|
|
76
83
|
|
|
77
84
|
return DevToolsConfig(
|
|
85
|
+
pyproject_path=tmp_path,
|
|
78
86
|
plugin_package_name="Plugin",
|
|
79
87
|
runtime_requires=["pytest-cov"],
|
|
80
88
|
changelog_file_path=plugin_dir / "CHANGELOG.md",
|
|
@@ -82,15 +90,17 @@ def dev_tools_config_with_duplicate_dependencies(plugin_dir: Path) -> DevToolsCo
|
|
|
82
90
|
auto_add_recursive_runtime_dependencies=True,
|
|
83
91
|
version_number_source=VersionNumberSource.CHANGELOG,
|
|
84
92
|
disabled_extra_plugins=[],
|
|
93
|
+
license_file_path=None,
|
|
85
94
|
)
|
|
86
95
|
|
|
87
96
|
|
|
88
97
|
@pytest.fixture()
|
|
89
|
-
def dev_tools_config_minimal(plugin_dir: Path) -> DevToolsConfig:
|
|
98
|
+
def dev_tools_config_minimal(tmp_path: Path, plugin_dir: Path) -> DevToolsConfig:
|
|
90
99
|
# No python path append and not recursive deps
|
|
91
100
|
from qgis_plugin_dev_tools.config import DevToolsConfig
|
|
92
101
|
|
|
93
102
|
return DevToolsConfig(
|
|
103
|
+
pyproject_path=tmp_path,
|
|
94
104
|
plugin_package_name="Plugin",
|
|
95
105
|
runtime_requires=["pytest"],
|
|
96
106
|
changelog_file_path=plugin_dir / "CHANGELOG.md",
|
|
@@ -98,6 +108,7 @@ def dev_tools_config_minimal(plugin_dir: Path) -> DevToolsConfig:
|
|
|
98
108
|
auto_add_recursive_runtime_dependencies=False,
|
|
99
109
|
version_number_source=VersionNumberSource.CHANGELOG,
|
|
100
110
|
disabled_extra_plugins=[],
|
|
111
|
+
license_file_path=None,
|
|
101
112
|
)
|
|
102
113
|
|
|
103
114
|
|
|
@@ -115,19 +126,17 @@ def test_make_zip(dev_tools_config: "DevToolsConfig", tmp_path: Path):
|
|
|
115
126
|
expected_zip, "Plugin/_vendor/__init__.py"
|
|
116
127
|
)
|
|
117
128
|
vendor_files = _get_file_names(expected_zip, "Plugin/_vendor/")
|
|
129
|
+
plugin_files = _get_file_names(expected_zip, "Plugin/")
|
|
130
|
+
assert "LICENSE" in plugin_files
|
|
118
131
|
|
|
119
132
|
assert "import Plugin._vendor" in plugin_init_file_contents
|
|
120
133
|
assert "sys.path.append" in vendor_init_file_contents
|
|
121
134
|
assert vendor_files == {
|
|
122
135
|
"__init__.py",
|
|
123
136
|
"_pytest",
|
|
124
|
-
"atomicwrites",
|
|
125
|
-
"atomicwrites-1.4.0.dist-info",
|
|
126
137
|
"attr",
|
|
127
138
|
"attrs",
|
|
128
139
|
"attrs-21.4.0.dist-info",
|
|
129
|
-
"colorama",
|
|
130
|
-
"colorama-0.4.4.dist-info",
|
|
131
140
|
"importlib_metadata",
|
|
132
141
|
"importlib_metadata-4.11.3.dist-info",
|
|
133
142
|
"iniconfig",
|
|
@@ -142,7 +151,7 @@ def test_make_zip(dev_tools_config: "DevToolsConfig", tmp_path: Path):
|
|
|
142
151
|
"pytest-6.2.5.dist-info",
|
|
143
152
|
"toml",
|
|
144
153
|
"toml-0.10.2.dist-info",
|
|
145
|
-
"typing_extensions-4.2.
|
|
154
|
+
"typing_extensions-4.12.2.dist-info",
|
|
146
155
|
"typing_extensions.py", # no top-level.txt in .dist-info, parsed from record
|
|
147
156
|
"zipp-3.8.0.dist-info",
|
|
148
157
|
"zipp.py", # top-level.txt in .dist-info, includes zipp
|
|
@@ -172,15 +181,11 @@ def test_make_zip_with_duplicate_dependencies(
|
|
|
172
181
|
assert vendor_files == {
|
|
173
182
|
"__init__.py",
|
|
174
183
|
"_pytest",
|
|
175
|
-
"atomicwrites",
|
|
176
|
-
"atomicwrites-1.4.0.dist-info",
|
|
177
184
|
"attr",
|
|
178
185
|
"attrs",
|
|
179
186
|
"attrs-21.4.0.dist-info",
|
|
180
|
-
"colorama",
|
|
181
|
-
"colorama-0.4.4.dist-info",
|
|
182
187
|
"coverage",
|
|
183
|
-
"coverage-6.
|
|
188
|
+
"coverage-7.6.1.dist-info",
|
|
184
189
|
"importlib_metadata",
|
|
185
190
|
"importlib_metadata-4.11.3.dist-info",
|
|
186
191
|
"iniconfig",
|
|
@@ -194,10 +199,10 @@ def test_make_zip_with_duplicate_dependencies(
|
|
|
194
199
|
"pytest",
|
|
195
200
|
"pytest-6.2.5.dist-info",
|
|
196
201
|
"pytest_cov",
|
|
197
|
-
"pytest_cov-
|
|
202
|
+
"pytest_cov-4.1.0.dist-info",
|
|
198
203
|
"toml",
|
|
199
204
|
"toml-0.10.2.dist-info",
|
|
200
|
-
"typing_extensions-4.2.
|
|
205
|
+
"typing_extensions-4.12.2.dist-info",
|
|
201
206
|
"typing_extensions.py", # no top-level.txt in .dist-info, parsed from record
|
|
202
207
|
"zipp-3.8.0.dist-info",
|
|
203
208
|
"zipp.py", # top-level.txt in .dist-info, includes zipp
|
|
@@ -233,6 +238,90 @@ def test_make_zip_with_minimal_config(
|
|
|
233
238
|
}
|
|
234
239
|
|
|
235
240
|
|
|
241
|
+
@pytest.mark.parametrize("licence_file_name", ["LICENSE", "license.md"])
|
|
242
|
+
def test_make_zip_copies_license_from_custom_path(
|
|
243
|
+
dev_tools_config_minimal: "DevToolsConfig", tmp_path: Path, licence_file_name: str
|
|
244
|
+
):
|
|
245
|
+
# Remove original
|
|
246
|
+
original_license = tmp_path / "LICENSE"
|
|
247
|
+
os.remove(original_license)
|
|
248
|
+
|
|
249
|
+
license_dir = tmp_path / "license"
|
|
250
|
+
license_dir.mkdir()
|
|
251
|
+
license_file = license_dir / licence_file_name
|
|
252
|
+
license_file.touch()
|
|
253
|
+
dev_tools_config_minimal.license_file_path = license_file
|
|
254
|
+
target_path = tmp_path / "dist"
|
|
255
|
+
expected_zip = target_path / "Plugin-test-version.zip"
|
|
256
|
+
|
|
257
|
+
make_plugin_zip(
|
|
258
|
+
dev_tools_config_minimal, target_path, override_plugin_version="test-version"
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
assert target_path.exists()
|
|
262
|
+
assert expected_zip.exists()
|
|
263
|
+
plugin_files = _get_file_names(expected_zip, "Plugin/")
|
|
264
|
+
assert "LICENSE" in plugin_files
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def test_make_zip_copies_license_with_different_name(
|
|
268
|
+
dev_tools_config_minimal: "DevToolsConfig",
|
|
269
|
+
tmp_path: Path,
|
|
270
|
+
plugin_dir: Path,
|
|
271
|
+
):
|
|
272
|
+
# Remove original
|
|
273
|
+
original_license = tmp_path / "LICENSE"
|
|
274
|
+
os.remove(original_license)
|
|
275
|
+
|
|
276
|
+
license_file = tmp_path / "license.md"
|
|
277
|
+
license_file.touch()
|
|
278
|
+
|
|
279
|
+
copy_license(dev_tools_config_minimal, plugin_dir.parent)
|
|
280
|
+
|
|
281
|
+
assert (plugin_dir / "LICENSE").exists()
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def test_make_zip_does_not_create_license_if_it_does_not_exist(
|
|
285
|
+
dev_tools_config_minimal: "DevToolsConfig", tmp_path: Path
|
|
286
|
+
):
|
|
287
|
+
# Remove original
|
|
288
|
+
original_license = tmp_path / "LICENSE"
|
|
289
|
+
os.remove(original_license)
|
|
290
|
+
|
|
291
|
+
target_path = tmp_path / "dist"
|
|
292
|
+
expected_zip = target_path / "Plugin-test-version.zip"
|
|
293
|
+
|
|
294
|
+
make_plugin_zip(
|
|
295
|
+
dev_tools_config_minimal, target_path, override_plugin_version="test-version"
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
assert target_path.exists()
|
|
299
|
+
assert expected_zip.exists()
|
|
300
|
+
plugin_files = _get_file_names(expected_zip, "Plugin/")
|
|
301
|
+
assert "LICENSE" not in plugin_files
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def test_make_zip_does_not_create_license_if_configured_one_does_not_exist(
|
|
305
|
+
dev_tools_config_minimal: "DevToolsConfig", tmp_path: Path
|
|
306
|
+
):
|
|
307
|
+
dev_tools_config_minimal.license_file_path = tmp_path / "non-existing-license"
|
|
308
|
+
|
|
309
|
+
original_license = tmp_path / "LICENSE"
|
|
310
|
+
os.remove(original_license)
|
|
311
|
+
|
|
312
|
+
target_path = tmp_path / "dist"
|
|
313
|
+
expected_zip = target_path / "Plugin-test-version.zip"
|
|
314
|
+
|
|
315
|
+
make_plugin_zip(
|
|
316
|
+
dev_tools_config_minimal, target_path, override_plugin_version="test-version"
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
assert target_path.exists()
|
|
320
|
+
assert expected_zip.exists()
|
|
321
|
+
plugin_files = _get_file_names(expected_zip, "Plugin/")
|
|
322
|
+
assert "LICENSE" not in plugin_files
|
|
323
|
+
|
|
324
|
+
|
|
236
325
|
def _get_file_names(zip_file: Path, prefix: str) -> set[str]:
|
|
237
326
|
with zipfile.ZipFile(zip_file) as z:
|
|
238
327
|
namelist = z.namelist()
|
|
@@ -14,9 +14,7 @@ def sample_dist() -> Any:
|
|
|
14
14
|
def test_get_distribution_requirements(sample_dist: Any):
|
|
15
15
|
requirements = get_distribution_requirements(sample_dist)
|
|
16
16
|
assert sorted(requirements.keys()) == [
|
|
17
|
-
"atomicwrites",
|
|
18
17
|
"attrs",
|
|
19
|
-
"colorama",
|
|
20
18
|
"importlib-metadata",
|
|
21
19
|
"iniconfig",
|
|
22
20
|
"packaging",
|
|
@@ -46,6 +46,8 @@ def test_optionals_can_be_missing(
|
|
|
46
46
|
result = read_dotenv_configs([test_file])
|
|
47
47
|
assert result.DEVELOPMENT_PROFILE_NAME is None
|
|
48
48
|
assert result.DEBUGGER_LIBRARY is None
|
|
49
|
+
assert result.QGIS_LOCALE is None
|
|
50
|
+
assert result.QGIS_GUI_INI is None
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
def test_other_vars_saved_as_runtime_env(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qgis_plugin_dev_tools-0.7.0 → qgis_plugin_dev_tools-0.9.0}/src/qgis_plugin_dev_tools/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|