nmk-python 1.6.0__py3-none-any.whl → 1.8.0__py3-none-any.whl
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.
- nmk_python/backends/__init__.py +0 -0
- nmk_python/backends/build_backend.py +56 -0
- nmk_python/backends/factory.py +32 -0
- nmk_python/backends/pip_build_backend.py +53 -0
- nmk_python/backends/uv_build_backend.py +56 -0
- nmk_python/build.py +154 -49
- nmk_python/build.yml +189 -152
- nmk_python/files.py +7 -4
- nmk_python/files.yml +23 -20
- nmk_python/project.yml +28 -26
- nmk_python/templates/build.toml.jinja +15 -5
- nmk_python/version.yml +0 -1
- {nmk_python-1.6.0.dist-info → nmk_python-1.8.0.dist-info}/METADATA +1 -1
- nmk_python-1.8.0.dist-info/RECORD +31 -0
- nmk_python-1.6.0.dist-info/RECORD +0 -26
- {nmk_python-1.6.0.dist-info → nmk_python-1.8.0.dist-info}/WHEEL +0 -0
- {nmk_python-1.6.0.dist-info → nmk_python-1.8.0.dist-info}/licenses/LICENSE +0 -0
- {nmk_python-1.6.0.dist-info → nmk_python-1.8.0.dist-info}/top_level.txt +0 -0
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Python build backend definition module
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import cast
|
|
8
|
+
|
|
9
|
+
from nmk._internal.envbackend_legacy import EnvBackend # For type hinting
|
|
10
|
+
from nmk.model.model import NmkModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PythonBuildBackend(ABC):
|
|
14
|
+
"""
|
|
15
|
+
Python build backend interface
|
|
16
|
+
|
|
17
|
+
:param model: NmkModel instance
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, model: NmkModel):
|
|
21
|
+
self._model = model
|
|
22
|
+
self._env_backend = cast(EnvBackend, model.env_backend) # type: ignore
|
|
23
|
+
|
|
24
|
+
@abstractmethod
|
|
25
|
+
def install_editable(self): # pragma: no cover
|
|
26
|
+
"""
|
|
27
|
+
Install current project as editable package
|
|
28
|
+
"""
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def install_wheel(self, wheel_path: Path): # pragma: no cover
|
|
33
|
+
"""
|
|
34
|
+
Install current project built wheel
|
|
35
|
+
"""
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def build_wheel(self, build_dir: Path, built_wheel_name: str, wheel_version: str) -> Path: # pragma: no cover
|
|
40
|
+
"""
|
|
41
|
+
Build current project wheel
|
|
42
|
+
|
|
43
|
+
:param build_dir: temporary build folder
|
|
44
|
+
:param built_wheel_name: name of the built wheel file
|
|
45
|
+
:return: path to built wheel
|
|
46
|
+
"""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
@abstractmethod
|
|
50
|
+
def uninstall_wheels(self, wheel_names: list[str]): # pragma: no cover
|
|
51
|
+
"""
|
|
52
|
+
Uninstall specified wheels
|
|
53
|
+
|
|
54
|
+
:param wheel_names: names of the wheels to uninstall
|
|
55
|
+
"""
|
|
56
|
+
pass
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Build backend factory definition module
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from nmk.model.model import NmkModel
|
|
6
|
+
|
|
7
|
+
from .build_backend import PythonBuildBackend
|
|
8
|
+
from .pip_build_backend import PipBuildBackend
|
|
9
|
+
from .uv_build_backend import UvBuildBackend
|
|
10
|
+
|
|
11
|
+
# Supported backends mapping
|
|
12
|
+
_SUPPORTED_BACKENDS = {"pip": PipBuildBackend, "legacy": PipBuildBackend, "uv": UvBuildBackend}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BuildBackendFactory:
|
|
16
|
+
"""
|
|
17
|
+
Python build backend factory
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def create(model: NmkModel) -> PythonBuildBackend:
|
|
22
|
+
"""
|
|
23
|
+
Create a python build backend, from provided environment backend
|
|
24
|
+
|
|
25
|
+
:param model: NmkModel instance
|
|
26
|
+
:return: Python build backend instance
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Check for supported backend
|
|
30
|
+
env_backend_name = model.env_backend.name
|
|
31
|
+
assert env_backend_name in _SUPPORTED_BACKENDS, f"Unsupported backend for python build: {env_backend_name}"
|
|
32
|
+
return _SUPPORTED_BACKENDS[env_backend_name](model)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pip build backend module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import cast
|
|
8
|
+
|
|
9
|
+
from nmk.utils import run_with_logs
|
|
10
|
+
|
|
11
|
+
from .build_backend import PythonBuildBackend
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PipBuildBackend(PythonBuildBackend):
|
|
15
|
+
"""
|
|
16
|
+
Pip build backend implementation
|
|
17
|
+
|
|
18
|
+
:param model: NmkModel instance
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def install_editable(self):
|
|
22
|
+
# Prepare install args
|
|
23
|
+
install_args = ["install", "-e", "."]
|
|
24
|
+
|
|
25
|
+
# Add extra args from model config
|
|
26
|
+
install_args += cast(list[str], self._model.config["pythonEditablePipInstallArgs"].value)
|
|
27
|
+
|
|
28
|
+
# Delegate to subprocess
|
|
29
|
+
self._env_backend.subprocess(install_args, cwd=self._env_backend.project_path)
|
|
30
|
+
|
|
31
|
+
def install_wheel(self, wheel_path: Path):
|
|
32
|
+
# Prepare install args
|
|
33
|
+
install_args = ["install", str(wheel_path)]
|
|
34
|
+
|
|
35
|
+
# Add extra args from model config
|
|
36
|
+
install_args += cast(list[str], self._model.config["pythonWheelPipInstallArgs"].value)
|
|
37
|
+
|
|
38
|
+
# Delegate to subprocess
|
|
39
|
+
self._env_backend.subprocess(install_args, cwd=self._env_backend.project_path)
|
|
40
|
+
|
|
41
|
+
def build_wheel(self, build_dir: Path, built_wheel_name: str, wheel_version: str) -> Path:
|
|
42
|
+
# Delegate to build module
|
|
43
|
+
run_with_logs([sys.executable, "-m", "build", "--wheel", "--skip-dependency-check", "--no-isolation"], cwd=build_dir)
|
|
44
|
+
|
|
45
|
+
# Return built wheel path
|
|
46
|
+
return build_dir / "dist" / built_wheel_name
|
|
47
|
+
|
|
48
|
+
def uninstall_wheels(self, wheel_names: list[str]):
|
|
49
|
+
# Prepare uninstall args
|
|
50
|
+
uninstall_args = ["uninstall", "--yes"] + wheel_names
|
|
51
|
+
|
|
52
|
+
# Delegate to subprocess
|
|
53
|
+
self._env_backend.subprocess(uninstall_args, cwd=self._env_backend.project_path)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Uv build backend module.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import cast
|
|
7
|
+
|
|
8
|
+
from .build_backend import PythonBuildBackend
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UvBuildBackend(PythonBuildBackend):
|
|
12
|
+
"""
|
|
13
|
+
Uv build backend implementation
|
|
14
|
+
|
|
15
|
+
:param model: NmkModel instance
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def install_editable(self):
|
|
19
|
+
# Prepare install args
|
|
20
|
+
install_args = ["sync"]
|
|
21
|
+
|
|
22
|
+
# Add extra args from model config
|
|
23
|
+
install_args += cast(list[str], self._model.config["pythonEditableUvInstallArgs"].value)
|
|
24
|
+
|
|
25
|
+
# Delegate to subprocess
|
|
26
|
+
self._env_backend.subprocess(install_args, cwd=self._env_backend.project_path)
|
|
27
|
+
|
|
28
|
+
def install_wheel(self, wheel_path: Path):
|
|
29
|
+
# Prepare install args
|
|
30
|
+
install_args = ["pip", "install", str(wheel_path)]
|
|
31
|
+
|
|
32
|
+
# Add extra args from model config
|
|
33
|
+
install_args += cast(list[str], self._model.config["pythonWheelUvInstallArgs"].value)
|
|
34
|
+
|
|
35
|
+
# Delegate to subprocess
|
|
36
|
+
self._env_backend.subprocess(install_args, cwd=self._env_backend.project_path)
|
|
37
|
+
|
|
38
|
+
def build_wheel(self, build_dir: Path, built_wheel_name: str, wheel_version: str) -> Path:
|
|
39
|
+
# Name for wheel sub-directory
|
|
40
|
+
wheel_sub_dir = "wheel_dist"
|
|
41
|
+
|
|
42
|
+
# Check for (experimental) uv-build backend
|
|
43
|
+
if self._model.config["pythonUseUvBuildBackend"].value:
|
|
44
|
+
# Prepare project version (without updating the venv)
|
|
45
|
+
self._env_backend.subprocess(["version", "--active", "--no-sync", wheel_version], cwd=build_dir)
|
|
46
|
+
|
|
47
|
+
# Delegate to uv
|
|
48
|
+
build_args = ["build", "--wheel", "--out-dir", wheel_sub_dir]
|
|
49
|
+
self._env_backend.subprocess(build_args, cwd=build_dir)
|
|
50
|
+
|
|
51
|
+
# Return built wheel path
|
|
52
|
+
return build_dir / wheel_sub_dir / built_wheel_name
|
|
53
|
+
|
|
54
|
+
def uninstall_wheels(self, wheel_names: list[str]):
|
|
55
|
+
# Same as setup
|
|
56
|
+
self._env_backend.upgrade(full=False, only_deps=True)
|
nmk_python/build.py
CHANGED
|
@@ -2,35 +2,47 @@
|
|
|
2
2
|
Python package build module
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import importlib.metadata
|
|
6
|
+
import json
|
|
5
7
|
import shutil
|
|
6
|
-
import
|
|
7
|
-
from
|
|
8
|
+
from fnmatch import fnmatch
|
|
9
|
+
from itertools import product
|
|
8
10
|
from pathlib import Path
|
|
11
|
+
from typing import cast
|
|
9
12
|
|
|
13
|
+
from nmk._internal.envbackend_legacy import EnvBackend # For type hinting
|
|
14
|
+
from nmk.logs import NmkLogWrapper
|
|
10
15
|
from nmk.model.builder import NmkTaskBuilder
|
|
11
|
-
from nmk.model.
|
|
12
|
-
from nmk.model.resolver import NmkListConfigResolver, NmkStrConfigResolver
|
|
13
|
-
from nmk.utils import is_windows
|
|
14
|
-
from
|
|
15
|
-
|
|
16
|
-
from
|
|
16
|
+
from nmk.model.model import NmkModel
|
|
17
|
+
from nmk.model.resolver import NmkDictConfigResolver, NmkListConfigResolver, NmkStrConfigResolver
|
|
18
|
+
from nmk.utils import is_windows
|
|
19
|
+
from packaging.requirements import Requirement
|
|
20
|
+
|
|
21
|
+
from nmk_python.backends.factory import BuildBackendFactory
|
|
17
22
|
|
|
18
23
|
|
|
19
24
|
# Install filter for Windows
|
|
20
|
-
def _can_install(name: str, logger:
|
|
25
|
+
def _can_install(name: str, logger: NmkLogWrapper) -> bool:
|
|
21
26
|
# On Windows, refuse to install nmk package while running nmk (wont' work)
|
|
22
|
-
if is_windows() and name
|
|
23
|
-
logger.warning("Can't install
|
|
27
|
+
if is_windows() and name in ["nmk", "buildenv"]:
|
|
28
|
+
logger.warning(f"Can't install {name} while running {name}!")
|
|
24
29
|
return False
|
|
25
30
|
return True
|
|
26
31
|
|
|
27
32
|
|
|
33
|
+
# Get python package from model
|
|
34
|
+
def _python_package(model: NmkModel) -> str:
|
|
35
|
+
cfg = model.config.get("pythonPackage")
|
|
36
|
+
assert cfg is not None and isinstance(cfg.value, str), "Can't read pythonPackage from model"
|
|
37
|
+
return cfg.value
|
|
38
|
+
|
|
39
|
+
|
|
28
40
|
class PackageBuilder(NmkTaskBuilder):
|
|
29
41
|
"""
|
|
30
42
|
Python package builder
|
|
31
43
|
"""
|
|
32
44
|
|
|
33
|
-
def build(self, project_file: str, version_file: str, source_dirs: list[str], artifacts_dir: str, build_dir: str, extra_resources: dict[str, str]):
|
|
45
|
+
def build(self, project_file: str, version_file: str, source_dirs: list[str], artifacts_dir: str, build_dir: str, extra_resources: dict[str, str]): # pyright: ignore[reportIncompatibleMethodOverride]
|
|
34
46
|
"""
|
|
35
47
|
Delegate to python build module, from a temporary build folder
|
|
36
48
|
|
|
@@ -49,21 +61,14 @@ class PackageBuilder(NmkTaskBuilder):
|
|
|
49
61
|
build_path.mkdir(exist_ok=True, parents=True)
|
|
50
62
|
|
|
51
63
|
# Copy source folders and various project files
|
|
52
|
-
|
|
64
|
+
project_path = Path(project_file)
|
|
65
|
+
project_root = project_path.parent
|
|
53
66
|
for source_dir in map(Path, source_dirs):
|
|
54
67
|
shutil.copytree(source_dir, build_path / source_dir.relative_to(project_root))
|
|
55
|
-
for candidate in filter(lambda p: p.is_file(), map(Path, [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
build_project = build_path / Path(project_file).name
|
|
60
|
-
build_version = build_path / Path(version_file).name
|
|
61
|
-
with build_project.open() as f:
|
|
62
|
-
project_doc = loads(f.read())
|
|
63
|
-
dyn_table = project_doc.get("tool").get("setuptools").get("dynamic")
|
|
64
|
-
dyn_table["version"] = {"file": build_version.name}
|
|
65
|
-
project_output = TOMLFile(build_project)
|
|
66
|
-
project_output.write(project_doc)
|
|
68
|
+
for candidate in filter(lambda p: p.is_file(), map(Path, [project_path, version_file, project_root / "README.md", project_root / "LICENSE"])):
|
|
69
|
+
dest = build_path / candidate.relative_to(project_root)
|
|
70
|
+
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
71
|
+
shutil.copyfile(candidate, dest)
|
|
67
72
|
|
|
68
73
|
# Handle extra resources
|
|
69
74
|
for src, dst in extra_resources.items():
|
|
@@ -90,18 +95,17 @@ class PackageBuilder(NmkTaskBuilder):
|
|
|
90
95
|
for wheel in artifacts_path.glob("*.whl"):
|
|
91
96
|
wheel.unlink()
|
|
92
97
|
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
# Read version from file
|
|
99
|
+
wheel_version = Path(version_file).read_text().splitlines()[0]
|
|
100
|
+
|
|
101
|
+
# Delegate to build backend
|
|
102
|
+
built_wheel = BuildBackendFactory.create(self.model).build_wheel(
|
|
103
|
+
build_dir=build_path, built_wheel_name=self.main_output.name, wheel_version=wheel_version
|
|
98
104
|
)
|
|
105
|
+
assert built_wheel.is_file(), f"Expected built wheel not found: {built_wheel}"
|
|
99
106
|
|
|
100
107
|
# Copy wheel to artifacts folder
|
|
101
|
-
|
|
102
|
-
built_wheel = build_path / "dist" / target_wheel.name
|
|
103
|
-
assert built_wheel.is_file(), f"Expected built wheel not found: {built_wheel}"
|
|
104
|
-
shutil.copyfile(built_wheel, target_wheel)
|
|
108
|
+
shutil.copyfile(built_wheel, self.main_output)
|
|
105
109
|
|
|
106
110
|
|
|
107
111
|
class PythonModuleResolver(NmkStrConfigResolver):
|
|
@@ -113,27 +117,31 @@ class PythonModuleResolver(NmkStrConfigResolver):
|
|
|
113
117
|
"""
|
|
114
118
|
Return module name from package (i.e. wheel) name
|
|
115
119
|
"""
|
|
116
|
-
return self.model.
|
|
120
|
+
return _python_package(self.model).replace("-", "_")
|
|
117
121
|
|
|
118
122
|
|
|
119
|
-
class Installer(
|
|
123
|
+
class Installer(NmkTaskBuilder):
|
|
120
124
|
"""
|
|
121
125
|
Install built wheel in venv
|
|
122
126
|
"""
|
|
123
127
|
|
|
124
|
-
def build(self, name: str, pip_args: list[str], to_remove: str):
|
|
128
|
+
def build(self, name: str, wheel: str, pip_args: list[str] | None = None, to_remove: str = ""): # pyright: ignore[reportIncompatibleMethodOverride]
|
|
125
129
|
"""
|
|
126
130
|
Install wheel in venv
|
|
127
131
|
|
|
128
132
|
:param name: wheel name to be installed
|
|
129
|
-
:param
|
|
133
|
+
:param wheel: wheel path to be installed
|
|
134
|
+
:param pip_args: pip command line arguments; deprecated, not used anymore
|
|
130
135
|
:param to_remove: stamp file to be removed
|
|
131
136
|
"""
|
|
132
137
|
|
|
133
138
|
# Check if wheel can be installed
|
|
134
139
|
if _can_install(name, self.logger):
|
|
135
|
-
#
|
|
136
|
-
|
|
140
|
+
# Delegate to build backend
|
|
141
|
+
eb = cast(EnvBackend, self.model.env_backend) # type: ignore
|
|
142
|
+
old_packages = eb.installed_packages
|
|
143
|
+
BuildBackendFactory.create(self.model).install_wheel(wheel_path=Path(wheel))
|
|
144
|
+
eb.print_updates(old_packages)
|
|
137
145
|
|
|
138
146
|
# Remove stamp file
|
|
139
147
|
Path(to_remove).unlink(missing_ok=True)
|
|
@@ -144,17 +152,28 @@ class Uninstaller(NmkTaskBuilder):
|
|
|
144
152
|
Uninstall current project wheel from venv
|
|
145
153
|
"""
|
|
146
154
|
|
|
147
|
-
def build(self, name: str):
|
|
155
|
+
def build(self, name: str, local_deps: list[str] | None = None): # pyright: ignore[reportIncompatibleMethodOverride]
|
|
148
156
|
"""
|
|
149
157
|
Uninstall wheel from venv
|
|
150
158
|
|
|
151
159
|
Note that task won't fail if the wheel is not installed
|
|
152
160
|
|
|
153
161
|
:param name: wheel name to be uninstalled
|
|
162
|
+
:param local_deps: list of workspace local dependencies patterns, used to find additional wheels to uninstall
|
|
154
163
|
"""
|
|
155
164
|
|
|
156
|
-
#
|
|
157
|
-
|
|
165
|
+
# Find local deps to uninstall, from provided packages
|
|
166
|
+
wheel_names = set([name])
|
|
167
|
+
eb = cast(EnvBackend, self.model.env_backend) # type: ignore
|
|
168
|
+
old_packages = eb.installed_packages
|
|
169
|
+
for pattern, dep_name in product(local_deps if local_deps else [], old_packages.keys()):
|
|
170
|
+
if fnmatch(dep_name, pattern):
|
|
171
|
+
self.logger.debug(f"wheel name '{dep_name}' matches local dependency pattern '{pattern}', will be uninstalled")
|
|
172
|
+
wheel_names.add(dep_name)
|
|
173
|
+
|
|
174
|
+
# Delegate to build backend
|
|
175
|
+
BuildBackendFactory.create(self.model).uninstall_wheels(wheel_names=sorted(list(wheel_names)))
|
|
176
|
+
eb.print_updates(old_packages)
|
|
158
177
|
|
|
159
178
|
|
|
160
179
|
class EditableBuilder(NmkTaskBuilder):
|
|
@@ -162,17 +181,20 @@ class EditableBuilder(NmkTaskBuilder):
|
|
|
162
181
|
Install python project in editable mode
|
|
163
182
|
"""
|
|
164
183
|
|
|
165
|
-
def build(self, pip_args: list[str]):
|
|
184
|
+
def build(self, pip_args: list[str] | None = None): # pyright: ignore[reportIncompatibleMethodOverride]
|
|
166
185
|
"""
|
|
167
186
|
Install project in venv as editable package
|
|
168
187
|
|
|
169
|
-
:param pip_args: pip command line arguments
|
|
188
|
+
:param pip_args: pip command line arguments; deprecated, not used anymore
|
|
170
189
|
"""
|
|
171
190
|
|
|
172
191
|
# Check if project can be installed in editable mode
|
|
173
|
-
if _can_install(self.model
|
|
174
|
-
# Delegate to
|
|
175
|
-
|
|
192
|
+
if _can_install(_python_package(self.model), self.logger):
|
|
193
|
+
# Delegate to build backend
|
|
194
|
+
eb = cast(EnvBackend, self.model.env_backend) # type: ignore
|
|
195
|
+
old_packages = eb.installed_packages
|
|
196
|
+
BuildBackendFactory.create(self.model).install_editable()
|
|
197
|
+
eb.print_updates(old_packages)
|
|
176
198
|
|
|
177
199
|
# Touch stamp file
|
|
178
200
|
self.main_output.touch()
|
|
@@ -183,8 +205,91 @@ class PythonOptionalDepsResolver(NmkListConfigResolver):
|
|
|
183
205
|
Python optional deps resolver
|
|
184
206
|
"""
|
|
185
207
|
|
|
186
|
-
def get_value(self, name: str, groups: dict[str, list[str]]) -> list[str]:
|
|
208
|
+
def get_value(self, name: str, groups: dict[str, list[str]]) -> list[str]: # pyright: ignore[reportIncompatibleMethodOverride]
|
|
187
209
|
"""
|
|
188
210
|
Turn dependency options deps dict into a merged list of dependencies
|
|
189
211
|
"""
|
|
190
212
|
return sorted(list(set(dependency for deps in groups.values() for dependency in deps)))
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class PythonDevDepsResolver(NmkListConfigResolver):
|
|
216
|
+
"""
|
|
217
|
+
Python development deps resolver
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
def get_value(self, name: str, package_deps: list[str], all_deps: list[str]) -> list[str]: # pyright: ignore[reportIncompatibleMethodOverride]
|
|
221
|
+
"""
|
|
222
|
+
Return development dependencies (all deps minus package deps)
|
|
223
|
+
"""
|
|
224
|
+
return sorted(list(set(all_deps) - set(package_deps)))
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class PythonArchiveDepsResolver(NmkDictConfigResolver):
|
|
228
|
+
"""
|
|
229
|
+
Python archive dependencies resolver
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
def get_value(self, name: str, archives: list[str]) -> dict[str, str]: # pyright: ignore[reportIncompatibleMethodOverride]
|
|
233
|
+
"""
|
|
234
|
+
Return archive dependencies mapping (python package name -> wheel path)
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
# Iterate on existing archives paths
|
|
238
|
+
out: dict[str, str] = {}
|
|
239
|
+
for dep in filter(lambda p: p.is_file() and "-" in p.name, map(Path, archives)):
|
|
240
|
+
# Extract package name from wheel file name
|
|
241
|
+
dep_name = dep.name.split("-")[0].replace("_", "-")
|
|
242
|
+
out[dep_name] = str(dep.resolve()).replace("\\", "\\\\") # Escape backslashes for Windows paths
|
|
243
|
+
return out
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
class DepsMetadataBuilder(NmkTaskBuilder):
|
|
247
|
+
"""
|
|
248
|
+
Generate python dependencies metadata file
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
def build(self, root_name: str, local_deps: list[str]): # pyright: ignore[reportIncompatibleMethodOverride]
|
|
252
|
+
"""
|
|
253
|
+
Generate python dependencies metadata file
|
|
254
|
+
|
|
255
|
+
:param root_name: name of the root package
|
|
256
|
+
:param local_deps: list of workspace local dependencies patterns
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
# Normalization implementation
|
|
260
|
+
def normalize(name: str) -> str:
|
|
261
|
+
return name.lower().replace("_", "-")
|
|
262
|
+
|
|
263
|
+
# Prepare distributions map
|
|
264
|
+
distributions = {normalize(d.name): d for d in importlib.metadata.distributions()}
|
|
265
|
+
assert root_name in distributions, f"Root package '{root_name}' not found in installed distributions"
|
|
266
|
+
output_data: dict[str, str] = {}
|
|
267
|
+
|
|
268
|
+
# Visitor implementation
|
|
269
|
+
def visit(name: str):
|
|
270
|
+
# Already visited or unknown?
|
|
271
|
+
if (name in output_data) or (name not in distributions):
|
|
272
|
+
return
|
|
273
|
+
|
|
274
|
+
# If this is a local project, don't add metadata
|
|
275
|
+
if (name != root_name) and not any(fnmatch(name, pattern) for pattern in local_deps):
|
|
276
|
+
# Keep versions
|
|
277
|
+
output_data[name] = distributions[name].version
|
|
278
|
+
|
|
279
|
+
# Visit dependencies
|
|
280
|
+
for dep in distributions[name].requires or []:
|
|
281
|
+
# Get requirement
|
|
282
|
+
req = Requirement(dep)
|
|
283
|
+
|
|
284
|
+
# Check marker, if any
|
|
285
|
+
if req.marker is not None and not req.marker.evaluate():
|
|
286
|
+
continue
|
|
287
|
+
|
|
288
|
+
# Visit dependency if installed
|
|
289
|
+
visit(normalize(req.name))
|
|
290
|
+
|
|
291
|
+
# Visit from root
|
|
292
|
+
visit(root_name)
|
|
293
|
+
|
|
294
|
+
# Write output metadata file
|
|
295
|
+
self.main_output.write_text(json.dumps({k: output_data[k] for k in sorted(output_data)}, indent=4))
|
nmk_python/build.yml
CHANGED
|
@@ -1,155 +1,192 @@
|
|
|
1
1
|
config:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
2
|
+
# Python package name (to be configured at project level)
|
|
3
|
+
pythonPackage: ${projectName}
|
|
4
|
+
pythonModule:
|
|
5
|
+
__resolver__: nmk_python.build.PythonModuleResolver
|
|
6
|
+
|
|
7
|
+
# Python artifacts directory
|
|
8
|
+
pythonArtifacts: ${outputDir}/artifacts
|
|
9
|
+
|
|
10
|
+
# Python build directory
|
|
11
|
+
pythonBuildDir: ${outputDir}/python
|
|
12
|
+
|
|
13
|
+
# Target platform for python project
|
|
14
|
+
pythonPackagePlatform: any
|
|
15
|
+
|
|
16
|
+
# Python source distribution + wheel artifacts
|
|
17
|
+
pythonWheel: ${pythonArtifacts}/${pythonModule}-${pythonVersion}-py3-none-${pythonPackagePlatform}.whl
|
|
18
|
+
|
|
19
|
+
# Add project file fragment for build config
|
|
20
|
+
pythonProjectFileFragments:
|
|
21
|
+
- ${BASEDIR}/templates/build.toml.jinja
|
|
22
|
+
|
|
23
|
+
# Python optional deps (named groups of python package optional dependencies)
|
|
24
|
+
pythonPackageOptionalRequirements: {}
|
|
25
|
+
|
|
26
|
+
# Derived list of python dependencies from the dependency groups
|
|
27
|
+
pythonPackageOptionalRequirementsList:
|
|
28
|
+
__resolver__: nmk_python.build.PythonOptionalDepsResolver
|
|
29
|
+
params:
|
|
30
|
+
groups: ${pythonPackageOptionalRequirements}
|
|
31
|
+
pythonProjectFileItems:
|
|
32
|
+
project:
|
|
33
|
+
optional-dependencies: ${pythonPackageOptionalRequirements}
|
|
34
|
+
|
|
35
|
+
# Python package dependencies
|
|
36
|
+
pythonPackageRequirements: []
|
|
37
|
+
|
|
38
|
+
# Python development dependencies
|
|
39
|
+
pythonDevRequirements:
|
|
40
|
+
__resolver__: nmk_python.build.PythonDevDepsResolver
|
|
41
|
+
params:
|
|
42
|
+
package_deps: ${pythonPackageRequirements}
|
|
43
|
+
all_deps: ${venvPkgDeps}
|
|
44
|
+
|
|
45
|
+
# Archive related requirements
|
|
46
|
+
pythonArchiveRequirements:
|
|
47
|
+
__resolver__: nmk_python.build.PythonArchiveDepsResolver
|
|
48
|
+
params:
|
|
49
|
+
archives: ${venvArchiveDeps}
|
|
50
|
+
|
|
51
|
+
# Also install in venv all dependencies
|
|
52
|
+
venvPkgDeps:
|
|
53
|
+
- ${pythonPackageRequirements}
|
|
54
|
+
- ${pythonPackageOptionalRequirementsList}
|
|
55
|
+
|
|
56
|
+
# Extra (external) resources to be bundled in built python wheel
|
|
57
|
+
pythonExtraResources: {}
|
|
58
|
+
|
|
59
|
+
# Python editable install stamp
|
|
60
|
+
pythonEditableStamp: ${outputDir}/.pyeditable
|
|
61
|
+
|
|
62
|
+
# Python files to be ignored
|
|
63
|
+
gitIgnoredFiles:
|
|
64
|
+
- .eggs/
|
|
65
|
+
- "*.egg-info/"
|
|
66
|
+
- "*.pyc"
|
|
67
|
+
- __pycache__
|
|
68
|
+
|
|
69
|
+
# Additional github publish step: publish on pypi.org
|
|
70
|
+
githubPublishSteps:
|
|
71
|
+
- name: Publish package on pypi.org
|
|
72
|
+
uses: pypa/gh-action-pypi-publish@v1.13.0
|
|
73
|
+
with:
|
|
74
|
+
user: __token__
|
|
75
|
+
password: ${{ secrets.pypi_password }}
|
|
76
|
+
packages_dir: ${r!pythonArtifacts}
|
|
77
|
+
|
|
78
|
+
# Wheel install arguments (for pip backend)
|
|
79
|
+
pythonWheelPipInstallArgs:
|
|
80
|
+
- --force-reinstall # force reinstall because otherwise install will be skipped if version didn't changed
|
|
81
|
+
- --no-deps # but skip dependencies to avoid reinstalling everything (deps are already installed by py.venv task)
|
|
82
|
+
|
|
83
|
+
# Editable install arguments (for pip backend)
|
|
84
|
+
pythonEditablePipInstallArgs:
|
|
85
|
+
- --no-deps # skip dependencies to avoid reinstalling everything
|
|
86
|
+
- --no-build-isolation # disable dependencies install when building for "editable" mode
|
|
87
|
+
|
|
88
|
+
# Wheel install arguments (for uv backend)
|
|
89
|
+
pythonWheelUvInstallArgs: []
|
|
90
|
+
|
|
91
|
+
# Editable install arguments (for uv backend)
|
|
92
|
+
pythonEditableUvInstallArgs: []
|
|
93
|
+
|
|
94
|
+
# Type checking mode for Pyright; may be off, basic, standard, strict
|
|
95
|
+
pythonTypeCheckingMode: strict
|
|
96
|
+
|
|
97
|
+
# Excluded modules for wheel build
|
|
98
|
+
pythonBuildExcludedModules: []
|
|
99
|
+
|
|
100
|
+
# Workspace local dependencies patterns
|
|
101
|
+
pythonLocalDepsPatterns: []
|
|
102
|
+
|
|
103
|
+
# Generated python dependencies metadata file
|
|
104
|
+
pythonDepsMetadata: ${outputDir}/python_deps.json
|
|
81
105
|
|
|
82
106
|
tasks:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
107
|
+
# Python editable install
|
|
108
|
+
py.editable:
|
|
109
|
+
description: Install python editable package
|
|
110
|
+
emoji: ":snake:.:house:"
|
|
111
|
+
deps:
|
|
112
|
+
- py.project
|
|
113
|
+
- py.format
|
|
114
|
+
- py.analyze
|
|
115
|
+
appendToDeps: build
|
|
116
|
+
if: ${pythonSrcFiles} # Only if python source files are found
|
|
117
|
+
output:
|
|
118
|
+
- ${pythonEditableStamp}
|
|
119
|
+
input:
|
|
120
|
+
- ${pythonProjectFile}
|
|
121
|
+
builder: nmk_python.build.EditableBuilder
|
|
122
|
+
|
|
123
|
+
# Python dependencies metadata
|
|
124
|
+
py.deps:
|
|
125
|
+
description: Gather python dependencies metadata
|
|
126
|
+
emoji: ":snake:.:link:"
|
|
127
|
+
deps:
|
|
128
|
+
- py.editable
|
|
129
|
+
appendToDeps: build
|
|
130
|
+
if: ${pythonSrcFiles} # Only if python source files are found
|
|
131
|
+
output:
|
|
132
|
+
- ${pythonDepsMetadata}
|
|
133
|
+
input:
|
|
134
|
+
- ${pythonProjectFile}
|
|
135
|
+
builder: nmk_python.build.DepsMetadataBuilder
|
|
136
|
+
params:
|
|
137
|
+
root_name: ${pythonPackage}
|
|
138
|
+
local_deps: ${pythonLocalDepsPatterns}
|
|
139
|
+
|
|
140
|
+
# Python wheel build
|
|
141
|
+
py.build:
|
|
142
|
+
description: Build python wheel
|
|
143
|
+
emoji: ":snake:.:hammer:"
|
|
144
|
+
deps:
|
|
145
|
+
- py.project
|
|
146
|
+
- py.format
|
|
147
|
+
- py.analyze
|
|
148
|
+
appendToDeps: package
|
|
149
|
+
if: ${pythonSrcFiles} # Only if python source files are found
|
|
150
|
+
output:
|
|
151
|
+
- ${pythonWheel}
|
|
152
|
+
input:
|
|
153
|
+
- ${pythonSrcFiles}
|
|
154
|
+
- ${pythonProjectFile}
|
|
155
|
+
builder: nmk_python.build.PackageBuilder
|
|
156
|
+
params:
|
|
157
|
+
project_file: ${pythonProjectFile}
|
|
158
|
+
version_file: ${pythonVersionStamp}
|
|
159
|
+
source_dirs: ${pythonSrcFolders}
|
|
160
|
+
artifacts_dir: ${pythonArtifacts}
|
|
161
|
+
build_dir: ${pythonBuildDir}
|
|
162
|
+
extra_resources: ${pythonExtraResources}
|
|
163
|
+
|
|
164
|
+
# Python wheel install
|
|
165
|
+
py.install:
|
|
166
|
+
description: Install python wheel
|
|
167
|
+
emoji: ":snake:.:inbox_tray:"
|
|
168
|
+
deps:
|
|
169
|
+
- py.build
|
|
170
|
+
appendToDeps: install
|
|
171
|
+
if: ${pythonSrcFiles} # Only if python source files are found
|
|
172
|
+
input: ${pythonWheel}
|
|
173
|
+
output:
|
|
174
|
+
- ${ROOTDIR}/${venvName}
|
|
175
|
+
- ${venvState}
|
|
176
|
+
builder: nmk_python.build.Installer
|
|
177
|
+
params:
|
|
178
|
+
name: ${pythonPackage}
|
|
179
|
+
wheel: ${pythonWheel}
|
|
180
|
+
to_remove: ${pythonEditableStamp}
|
|
181
|
+
|
|
182
|
+
# Python module clean
|
|
183
|
+
py.uninstall:
|
|
184
|
+
description: Uninstall python package and local dependencies
|
|
185
|
+
emoji: ":broom:.:snake:"
|
|
186
|
+
appendToDeps:
|
|
187
|
+
- clean
|
|
188
|
+
builder: nmk_python.build.Uninstaller
|
|
189
|
+
params:
|
|
190
|
+
name: ${pythonPackage}
|
|
191
|
+
local_deps: ${pythonLocalDepsPatterns}
|
|
192
|
+
if: ${pythonSrcFiles} # Only if python source files are found
|
nmk_python/files.py
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Python files resolvers
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from abc import abstractmethod
|
|
5
6
|
from pathlib import Path
|
|
7
|
+
from typing import cast
|
|
6
8
|
|
|
7
9
|
from nmk.model.resolver import NmkListConfigResolver
|
|
8
10
|
|
|
@@ -12,6 +14,7 @@ class FilesFinder(NmkListConfigResolver):
|
|
|
12
14
|
Shared logic for files resolution
|
|
13
15
|
"""
|
|
14
16
|
|
|
17
|
+
@abstractmethod
|
|
15
18
|
def find_in_folders(self) -> list[str]: # pragma: no cover
|
|
16
19
|
"""
|
|
17
20
|
Folders to be browsed (to be overridden)
|
|
@@ -38,7 +41,7 @@ class PythonFilesFinder(FilesFinder):
|
|
|
38
41
|
"""
|
|
39
42
|
Python source folders
|
|
40
43
|
"""
|
|
41
|
-
return self.model.config["pythonSrcFolders"].value
|
|
44
|
+
return cast(list[str], self.model.config["pythonSrcFolders"].value)
|
|
42
45
|
|
|
43
46
|
def get_value(self, name: str) -> list[Path]:
|
|
44
47
|
"""
|
|
@@ -50,8 +53,8 @@ class PythonFilesFinder(FilesFinder):
|
|
|
50
53
|
all_files = set(super().get_value(name))
|
|
51
54
|
|
|
52
55
|
# Remove generated and test ones
|
|
53
|
-
all_files -= {Path(p) for p in self.model.config["pythonTestSrcFiles"].value}
|
|
54
|
-
all_files -= {Path(p) for p in self.model.config["pythonGeneratedSrcFiles"].value}
|
|
56
|
+
all_files -= {Path(p) for p in cast(list[str], self.model.config["pythonTestSrcFiles"].value)}
|
|
57
|
+
all_files -= {Path(p) for p in cast(list[str], self.model.config["pythonGeneratedSrcFiles"].value)}
|
|
55
58
|
|
|
56
59
|
return list(all_files)
|
|
57
60
|
|
|
@@ -63,4 +66,4 @@ class PythonTestFilesFinder(FilesFinder):
|
|
|
63
66
|
"""
|
|
64
67
|
Python tests source folders
|
|
65
68
|
"""
|
|
66
|
-
return [self.model.config["pythonTestSources"].value]
|
|
69
|
+
return [cast(str, self.model.config["pythonTestSources"].value)]
|
nmk_python/files.yml
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
config:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
# Folder(s) for Python sources
|
|
3
|
+
pythonSrcFolders:
|
|
4
|
+
- ${sourceDir}
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
# Package holding test code
|
|
7
|
+
pythonTestPackage: tests
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
# Root folder for test sources
|
|
10
|
+
pythonTestSources: ${sourceDir}/${pythonTestPackage}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# Found Python test source files
|
|
13
|
+
pythonTestSrcFiles:
|
|
14
|
+
__resolver__: nmk_python.files.PythonTestFilesFinder
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
# Generated Python source files (to let other plugins contribute)
|
|
17
|
+
pythonGeneratedSrcFiles: []
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
# Found Python source files (that are neither generated not test ones)
|
|
20
|
+
pythonFoundSrcFiles:
|
|
21
|
+
__resolver__: nmk_python.files.PythonFilesFinder
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
# All Python source files
|
|
24
|
+
pythonSrcFiles:
|
|
25
|
+
- ${pythonFoundSrcFiles}
|
|
26
|
+
- ${pythonTestSrcFiles}
|
|
27
|
+
- ${pythonGeneratedSrcFiles}
|
|
28
|
+
|
|
29
|
+
# State if using uv build backend (experimental)
|
|
30
|
+
pythonUseUvBuildBackend: false
|
nmk_python/project.yml
CHANGED
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
config:
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
# Generated project file
|
|
3
|
+
pythonProjectFile: ${PROJECTDIR}/pyproject.toml
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
# Paths to pyproject.toml fragments to be merged
|
|
6
|
+
pythonProjectFileFragments: []
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
# Contributed project items from yml files
|
|
9
|
+
pythonProjectFileItems: {}
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
# Require VSCode specific extension for toml support
|
|
12
|
+
vscodeExtensionsNames:
|
|
13
|
+
- tamasfe.even-better-toml
|
|
14
|
+
|
|
15
|
+
# Input file for venv refresh is project file (overrides nmk-base default)
|
|
16
|
+
venvUpdateInput: ${pythonProjectFile}
|
|
14
17
|
|
|
15
18
|
tasks:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
plugin_name: nmk-python
|
|
19
|
+
py.project:
|
|
20
|
+
description: Generate python project file
|
|
21
|
+
emoji: ":snake:.:toolbox:"
|
|
22
|
+
input:
|
|
23
|
+
- ${pythonProjectFileFragments}
|
|
24
|
+
- ${pythonVersionStamp}
|
|
25
|
+
output:
|
|
26
|
+
- ${pythonProjectFile}
|
|
27
|
+
deps:
|
|
28
|
+
- py.version
|
|
29
|
+
appendToDeps: py.venv # Project file must be generated before venv is refreshed
|
|
30
|
+
builder: nmk_base.common.TomlFileBuilder
|
|
31
|
+
params:
|
|
32
|
+
fragment_files: ${pythonProjectFileFragments}
|
|
33
|
+
items: ${pythonProjectFileItems}
|
|
34
|
+
plugin_name: nmk-python
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
2
|
+
requires = ["{% if pythonUseUvBuildBackend %}uv_build>=0.9.18,<0.10.0{% else %}setuptools{% endif %}"]
|
|
3
|
+
build-backend = "{% if pythonUseUvBuildBackend %}uv_build{% else %}setuptools.build_meta{% endif %}"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "{{ pythonPackage }}"
|
|
7
|
-
dynamic = ["version"]
|
|
7
|
+
{% if pythonUseUvBuildBackend %}version = "0.0.0"{% else %}dynamic = ["version"]{% endif %}
|
|
8
8
|
authors = [
|
|
9
9
|
{name="{{ projectAuthor }}"},
|
|
10
10
|
]
|
|
@@ -20,7 +20,17 @@ dependencies = [{% for req in pythonPackageRequirements %}
|
|
|
20
20
|
"{{ req }}",{% endfor %}
|
|
21
21
|
]
|
|
22
22
|
|
|
23
|
-
[
|
|
23
|
+
[dependency-groups]
|
|
24
|
+
dev = [{% for req in pythonDevRequirements %}
|
|
25
|
+
"{{ req }}",{% endfor %}{% for req in pythonArchiveRequirements %}
|
|
26
|
+
"{{ req }}@{{ pythonArchiveRequirements[req] }}",{% endfor %}
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
{% if pythonUseUvBuildBackend %}[tool.uv.build-backend]
|
|
30
|
+
module-root = "{{pythonSrcFolders[0]}}"
|
|
31
|
+
wheel-exclude = [{% for module in pythonBuildExcludedModules %}{% if loop.index > 1 %},{% endif %}"{{module}}"{% endfor %}]
|
|
32
|
+
|
|
33
|
+
{% else %}[tool.setuptools.packages.find]
|
|
24
34
|
where = [{% for path in pythonSrcFolders %}"{{path}}",{% endfor %}]
|
|
25
35
|
exclude = [{% for module in pythonBuildExcludedModules %}{% if loop.index > 1 %},{% endif %}"{{module}}"{% endfor %}]
|
|
26
36
|
namespaces = false
|
|
@@ -31,7 +41,7 @@ namespaces = false
|
|
|
31
41
|
[tool.setuptools.dynamic.version]
|
|
32
42
|
file = "{{ pythonVersionStamp }}"
|
|
33
43
|
|
|
34
|
-
[tool.distutils.bdist_wheel]
|
|
44
|
+
{% endif %}[tool.distutils.bdist_wheel]
|
|
35
45
|
plat-name = "{{ pythonPackagePlatform }}"
|
|
36
46
|
|
|
37
47
|
[tool.pyright]
|
nmk_python/version.yml
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
nmk_python/__init__.py,sha256=EouCWXbAeObby1vOCx0Vx_WaGC2fEEFDMCen3JZt4TU,446
|
|
2
|
+
nmk_python/badges.yml,sha256=LzElZecCXKxdF-oPkvIwfnbQlOcAM_zUj6MelClmAug,749
|
|
3
|
+
nmk_python/build.py,sha256=bzpS1lUotsgdwBJH6Jgl2guAva1M0XDlKzwfj_lfZ1Y,11368
|
|
4
|
+
nmk_python/build.yml,sha256=8CWVacVv3r3pbvuRkaLQbH1aTO-oK4U0hAO9SgDTfFA,5726
|
|
5
|
+
nmk_python/doc.yml,sha256=12amAlYylH7JAHaqBIOoEZ_LrXY_bPNKuHrrwUkIj8w,932
|
|
6
|
+
nmk_python/files.py,sha256=K6Y-XKXuf8jh4x333Qgj6G1MyB-BgZ5Kd2-XCZhsfR4,2000
|
|
7
|
+
nmk_python/files.yml,sha256=jlp87gW9rTASUnsy7id7VWanaMUMN_py82bMa2adniM,813
|
|
8
|
+
nmk_python/plugin.yml,sha256=hi7osXyIwpHgJAsww5mhOA6emxhzgitDF8cOsvyY29Y,1068
|
|
9
|
+
nmk_python/project.yml,sha256=wBnB6KOglRvIpw1UHuXTYmuE_2BYGBzGWwIEbA5NDv8,985
|
|
10
|
+
nmk_python/ruff.py,sha256=TBmn5nFflcFRvjj36JtJGJ-GYHOK6XfhK9Jp-2dO5_E,1557
|
|
11
|
+
nmk_python/ruff.yml,sha256=FNmYjbv2l5vlqFXinY87LfgzpZ3PSiduB_xUiYw8aMw,3019
|
|
12
|
+
nmk_python/tests.py,sha256=8kRKP3dT2Thi5W5sCQSQOPXkV1D9C7tde3QYySo6G2c,1212
|
|
13
|
+
nmk_python/tests.yml,sha256=Sg6ZezkBVuvOzh-4QbJmZQymCOzXfenc0EpMdMZsEBc,1687
|
|
14
|
+
nmk_python/version.py,sha256=fLpOWdujYwlJB7XhWaOGCTeg3gQaClk2YHoRkkW64dE,3109
|
|
15
|
+
nmk_python/version.yml,sha256=WpZyQ2mChmvA_6eVb_Yp6ZaFIkX6oINxWBhKgb8h4GE,833
|
|
16
|
+
nmk_python/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
nmk_python/backends/build_backend.py,sha256=NOAXMa6jmAIfUvA690ht-x_DwsGtvBvttPZLfFcX_b0,1437
|
|
18
|
+
nmk_python/backends/factory.py,sha256=NMYByORffwSSIjeNMLkOnwh6x1xhJQVhoV-0rSooq6Q,953
|
|
19
|
+
nmk_python/backends/pip_build_backend.py,sha256=4MGYghBeMjZhUlKTwE0svSHArYwOAaK1I6_gmeNnwaI,1698
|
|
20
|
+
nmk_python/backends/uv_build_backend.py,sha256=QpN5nMm_QhnKzoHQcX4769OOQG6NqOD2ctYXyH2MI7A,1880
|
|
21
|
+
nmk_python/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
nmk_python/templates/build.toml.jinja,sha256=6F1Kdb32JVBWEitxLC7AsUdhx2VTyQEyWhhSb7n3oBs,1770
|
|
23
|
+
nmk_python/templates/pytest.toml.jinja,sha256=zQ3SRWnF23Omxm7zInE54j0l3OyjXSOn5pQ5Pak8Boo,641
|
|
24
|
+
nmk_python/templates/python-settings.json.jinja,sha256=jYXSy96cX9X9GIHoF7XiZDzd4P2GOlMisAVWW626WF4,749
|
|
25
|
+
nmk_python/templates/python-test-debug-launch.json.jinja,sha256=J_xju2EpHNXvgvqBxlf99p7g-ZMh3xE-_2r7o_57gpU,364
|
|
26
|
+
nmk_python/templates/ruff.toml.jinja,sha256=DTHe1ixK1SBY8d2xBCfkGz89HzjAoMO7Ogs12AY1i4Y,346
|
|
27
|
+
nmk_python-1.8.0.dist-info/licenses/LICENSE,sha256=PROo9EW7wP6jmSr_90OluItAsIB411b_CAqEBioMKpI,1074
|
|
28
|
+
nmk_python-1.8.0.dist-info/METADATA,sha256=wW1y07Ek_meONzj-P7sZd9h_8d1tEsKMKN7xm-DD2pQ,3148
|
|
29
|
+
nmk_python-1.8.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
nmk_python-1.8.0.dist-info/top_level.txt,sha256=MCb5w_hoOZ0kk3Dajxrd9Pz6lZ3pyuS6TQCRA3vddTo,11
|
|
31
|
+
nmk_python-1.8.0.dist-info/RECORD,,
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
nmk_python/__init__.py,sha256=EouCWXbAeObby1vOCx0Vx_WaGC2fEEFDMCen3JZt4TU,446
|
|
2
|
-
nmk_python/badges.yml,sha256=LzElZecCXKxdF-oPkvIwfnbQlOcAM_zUj6MelClmAug,749
|
|
3
|
-
nmk_python/build.py,sha256=K8BowkROfrGwOPk7wKwOo9fsWJrrk8bDqJqliC876WI,6716
|
|
4
|
-
nmk_python/build.yml,sha256=tbKjPRef7ZydEogsX3tAuQMR1B-vaMX5_q8q8tqzOnM,5046
|
|
5
|
-
nmk_python/doc.yml,sha256=12amAlYylH7JAHaqBIOoEZ_LrXY_bPNKuHrrwUkIj8w,932
|
|
6
|
-
nmk_python/files.py,sha256=gtPf6ldR5F4oGsAdzFnEIbI9MqqvF3z5JQnyONZmLmk,1863
|
|
7
|
-
nmk_python/files.yml,sha256=-vGjogdulwsfdKVEUa5RARYDKxF3m9RmHKFnIhaT3_k,780
|
|
8
|
-
nmk_python/plugin.yml,sha256=hi7osXyIwpHgJAsww5mhOA6emxhzgitDF8cOsvyY29Y,1068
|
|
9
|
-
nmk_python/project.yml,sha256=sRIMvKkasrYlIvOo3DsVyNM_sgID_sHVgZg_bSIqtfw,975
|
|
10
|
-
nmk_python/ruff.py,sha256=TBmn5nFflcFRvjj36JtJGJ-GYHOK6XfhK9Jp-2dO5_E,1557
|
|
11
|
-
nmk_python/ruff.yml,sha256=FNmYjbv2l5vlqFXinY87LfgzpZ3PSiduB_xUiYw8aMw,3019
|
|
12
|
-
nmk_python/tests.py,sha256=8kRKP3dT2Thi5W5sCQSQOPXkV1D9C7tde3QYySo6G2c,1212
|
|
13
|
-
nmk_python/tests.yml,sha256=Sg6ZezkBVuvOzh-4QbJmZQymCOzXfenc0EpMdMZsEBc,1687
|
|
14
|
-
nmk_python/version.py,sha256=fLpOWdujYwlJB7XhWaOGCTeg3gQaClk2YHoRkkW64dE,3109
|
|
15
|
-
nmk_python/version.yml,sha256=amHNaA7WVnD6S1kL0IFD1KLKef9-2aEM3xU2ZkiZanc,905
|
|
16
|
-
nmk_python/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
nmk_python/templates/build.toml.jinja,sha256=RJ-hCDc2SJG3K5rxK8tIIFcW-R7nt7Bu-x0wP9uPGGQ,1114
|
|
18
|
-
nmk_python/templates/pytest.toml.jinja,sha256=zQ3SRWnF23Omxm7zInE54j0l3OyjXSOn5pQ5Pak8Boo,641
|
|
19
|
-
nmk_python/templates/python-settings.json.jinja,sha256=jYXSy96cX9X9GIHoF7XiZDzd4P2GOlMisAVWW626WF4,749
|
|
20
|
-
nmk_python/templates/python-test-debug-launch.json.jinja,sha256=J_xju2EpHNXvgvqBxlf99p7g-ZMh3xE-_2r7o_57gpU,364
|
|
21
|
-
nmk_python/templates/ruff.toml.jinja,sha256=DTHe1ixK1SBY8d2xBCfkGz89HzjAoMO7Ogs12AY1i4Y,346
|
|
22
|
-
nmk_python-1.6.0.dist-info/licenses/LICENSE,sha256=PROo9EW7wP6jmSr_90OluItAsIB411b_CAqEBioMKpI,1074
|
|
23
|
-
nmk_python-1.6.0.dist-info/METADATA,sha256=0tKglaK0AkZMKrLPmsIuBmjKcN5sAeW-7r1zrKJuqHA,3148
|
|
24
|
-
nmk_python-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
25
|
-
nmk_python-1.6.0.dist-info/top_level.txt,sha256=MCb5w_hoOZ0kk3Dajxrd9Pz6lZ3pyuS6TQCRA3vddTo,11
|
|
26
|
-
nmk_python-1.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|