wexample-wex-addon-dev-python 0.0.63__py3-none-any.whl → 0.1.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.
- wexample_wex_addon_dev_python/commands/code/check.py +3 -1
- wexample_wex_addon_dev_python/commands/code/format.py +2 -1
- wexample_wex_addon_dev_python/commands/examples/validate.py +2 -1
- wexample_wex_addon_dev_python/file/python_pyproject_toml_file.py +30 -11
- wexample_wex_addon_dev_python/resources/package_publish_gitlab.yml +8 -0
- wexample_wex_addon_dev_python/workdir/python_package_workdir.py +188 -17
- wexample_wex_addon_dev_python/workdir/python_workdir.py +9 -50
- {wexample_wex_addon_dev_python-0.0.63.dist-info → wexample_wex_addon_dev_python-0.1.0.dist-info}/METADATA +53 -126
- {wexample_wex_addon_dev_python-0.0.63.dist-info → wexample_wex_addon_dev_python-0.1.0.dist-info}/RECORD +11 -10
- {wexample_wex_addon_dev_python-0.0.63.dist-info → wexample_wex_addon_dev_python-0.1.0.dist-info}/WHEEL +1 -1
- {wexample_wex_addon_dev_python-0.0.63.dist-info → wexample_wex_addon_dev_python-0.1.0.dist-info}/entry_points.txt +0 -0
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
from wexample_wex_core.const.globals import COMMAND_TYPE_ADDON
|
|
5
6
|
from wexample_wex_core.const.middleware import (
|
|
6
7
|
MIDDLEWARE_OPTION_VALUE_ALLWAYS,
|
|
7
8
|
MIDDLEWARE_OPTION_VALUE_OPTIONAL,
|
|
@@ -32,8 +33,9 @@ if TYPE_CHECKING:
|
|
|
32
33
|
show_progress=MIDDLEWARE_OPTION_VALUE_ALLWAYS,
|
|
33
34
|
)
|
|
34
35
|
@command(
|
|
36
|
+
type=COMMAND_TYPE_ADDON,
|
|
35
37
|
description="Check python code on every file: "
|
|
36
|
-
"
|
|
38
|
+
"python::code/check --file ../../pip/wex-core/wexample_wex_core/ -sof",
|
|
37
39
|
)
|
|
38
40
|
def python__code__check(
|
|
39
41
|
context: ExecutionContext,
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
from wexample_wex_core.const.globals import COMMAND_TYPE_ADDON
|
|
5
6
|
from wexample_wex_core.decorator.command import command
|
|
6
7
|
from wexample_wex_core.decorator.middleware import middleware
|
|
7
8
|
from wexample_wex_core.decorator.option import option
|
|
@@ -26,7 +27,7 @@ if TYPE_CHECKING:
|
|
|
26
27
|
@middleware(
|
|
27
28
|
name="each_python_file", should_exist=True, expand_glob=True, recursive=True
|
|
28
29
|
)
|
|
29
|
-
@command()
|
|
30
|
+
@command(type=COMMAND_TYPE_ADDON)
|
|
30
31
|
def python__code__format(
|
|
31
32
|
kernel: Kernel,
|
|
32
33
|
file: str,
|
|
@@ -2,13 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
from wexample_wex_core.const.globals import COMMAND_TYPE_ADDON
|
|
5
6
|
from wexample_wex_core.decorator.command import command
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
8
9
|
from wexample_wex_core.context.execution_context import ExecutionContext
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
@command(description="Check python code on every file.")
|
|
12
|
+
@command(type=COMMAND_TYPE_ADDON, description="Check python code on every file.")
|
|
12
13
|
def python__examples__validate(
|
|
13
14
|
context: ExecutionContext,
|
|
14
15
|
) -> None:
|
|
@@ -5,18 +5,20 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
from wexample_filestate.item.file.toml_file import TomlFile
|
|
6
6
|
from wexample_helpers.decorator.base_class import base_class
|
|
7
7
|
from wexample_wex_addon_app.const.path import APP_PATH_README
|
|
8
|
+
from wexample_wex_addon_app.item.file.mixin.app_dependencies_config_file_mixin import (
|
|
9
|
+
AppDependenciesConfigFileMixin,
|
|
10
|
+
)
|
|
8
11
|
|
|
9
12
|
if TYPE_CHECKING:
|
|
13
|
+
from packaging.requirements import Requirement
|
|
10
14
|
from tomlkit import TOMLDocument
|
|
11
15
|
|
|
12
16
|
|
|
13
17
|
@base_class
|
|
14
|
-
class PythonPyprojectTomlFile(TomlFile):
|
|
15
|
-
def
|
|
18
|
+
class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
19
|
+
def add_dependency_from_spec(
|
|
16
20
|
self,
|
|
17
|
-
|
|
18
|
-
version: str,
|
|
19
|
-
operator: str = "==",
|
|
21
|
+
spec: Requirement,
|
|
20
22
|
optional: bool = False,
|
|
21
23
|
group: None | str = None,
|
|
22
24
|
) -> bool:
|
|
@@ -24,13 +26,11 @@ class PythonPyprojectTomlFile(TomlFile):
|
|
|
24
26
|
from packaging.utils import canonicalize_name
|
|
25
27
|
from wexample_filestate_python.helpers.toml import toml_sort_string_array
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
new_req = Requirement(spec)
|
|
29
|
-
new_name = canonicalize_name(new_req.name)
|
|
29
|
+
new_name = canonicalize_name(spec.name)
|
|
30
30
|
|
|
31
31
|
deps = self._get_deps_array(optional=optional, group=group)
|
|
32
32
|
|
|
33
|
-
# Look for existing dependency
|
|
33
|
+
# Look for existing dependency (string-based)
|
|
34
34
|
old_spec = next(
|
|
35
35
|
(d for d in deps if canonicalize_name(Requirement(d).name) == new_name),
|
|
36
36
|
None,
|
|
@@ -40,8 +40,11 @@ class PythonPyprojectTomlFile(TomlFile):
|
|
|
40
40
|
if old_spec:
|
|
41
41
|
deps.remove(old_spec)
|
|
42
42
|
|
|
43
|
+
# Convert Requirement → string
|
|
44
|
+
new_spec_str = str(spec)
|
|
45
|
+
|
|
43
46
|
# Add new version
|
|
44
|
-
deps.append(
|
|
47
|
+
deps.append(new_spec_str)
|
|
45
48
|
|
|
46
49
|
# Sort array
|
|
47
50
|
toml_sort_string_array(deps)
|
|
@@ -49,7 +52,23 @@ class PythonPyprojectTomlFile(TomlFile):
|
|
|
49
52
|
# Save file
|
|
50
53
|
self.write_parsed()
|
|
51
54
|
|
|
52
|
-
return old_spec !=
|
|
55
|
+
return old_spec != new_spec_str
|
|
56
|
+
|
|
57
|
+
def add_dependency_from_string(
|
|
58
|
+
self,
|
|
59
|
+
package_name: str,
|
|
60
|
+
version: str,
|
|
61
|
+
operator: str = "==",
|
|
62
|
+
optional: bool = False,
|
|
63
|
+
group: None | str = None,
|
|
64
|
+
) -> bool:
|
|
65
|
+
from packaging.requirements import Requirement
|
|
66
|
+
|
|
67
|
+
return self.add_dependency_from_spec(
|
|
68
|
+
spec=Requirement(f"{package_name}{operator}{version}"),
|
|
69
|
+
optional=optional,
|
|
70
|
+
group=group,
|
|
71
|
+
)
|
|
53
72
|
|
|
54
73
|
def dumps(self, content: TOMLDocument | dict | None = None) -> str:
|
|
55
74
|
"""Serialize a TOMLDocument (preferred) or a plain dict to TOML.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
publish:
|
|
2
|
+
stage: deploy
|
|
3
|
+
image: python:3.12-slim
|
|
4
|
+
script:
|
|
5
|
+
- pip install pdm --quiet
|
|
6
|
+
- pdm publish --repository "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi" --username gitlab-ci-token --password "${CI_JOB_TOKEN}"
|
|
7
|
+
rules:
|
|
8
|
+
- if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+$/'
|
|
@@ -27,10 +27,34 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
27
27
|
|
|
28
28
|
def prepare_value(self, raw_value: DictConfig | None = None) -> DictConfig:
|
|
29
29
|
from wexample_helpers.helpers.array import array_dict_get_by
|
|
30
|
+
from wexample_helpers.helpers.file import file_read
|
|
31
|
+
from wexample_helpers.helpers.module import module_get_path
|
|
32
|
+
|
|
33
|
+
import wexample_wex_addon_dev_python
|
|
30
34
|
|
|
31
35
|
raw_value = super().prepare_value(raw_value=raw_value)
|
|
32
36
|
children = raw_value.get("children")
|
|
33
37
|
|
|
38
|
+
# Add .gitlab-ci.yml for private GitLab registry packages.
|
|
39
|
+
# Both callbacks are evaluated after configure() completes, so base_name
|
|
40
|
+
# and runtime config are fully available at that point.
|
|
41
|
+
children.append(
|
|
42
|
+
{
|
|
43
|
+
"name": ".gitlab-ci.yml",
|
|
44
|
+
"type": DiskItemType.FILE,
|
|
45
|
+
"should_exist": lambda _target, _self=self: bool(
|
|
46
|
+
_self.search_app_or_suite_runtime_config(
|
|
47
|
+
"pdm.repository.url", default=None
|
|
48
|
+
).get_str_or_none()
|
|
49
|
+
),
|
|
50
|
+
"content": lambda _: file_read(
|
|
51
|
+
module_get_path(wexample_wex_addon_dev_python)
|
|
52
|
+
/ "resources"
|
|
53
|
+
/ "package_publish_gitlab.yml"
|
|
54
|
+
),
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
|
|
34
58
|
children.append(
|
|
35
59
|
{
|
|
36
60
|
"name": "examples",
|
|
@@ -139,6 +163,42 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
139
163
|
|
|
140
164
|
return found
|
|
141
165
|
|
|
166
|
+
def _classify_version_bump(self, last_tag: str) -> str:
|
|
167
|
+
from wexample_helpers.const.types import (
|
|
168
|
+
UPGRADE_TYPE_INTERMEDIATE,
|
|
169
|
+
UPGRADE_TYPE_MAJOR,
|
|
170
|
+
UPGRADE_TYPE_MINOR,
|
|
171
|
+
)
|
|
172
|
+
from wexample_helpers_git.helpers.git import git_has_changes_since_tag
|
|
173
|
+
|
|
174
|
+
if not git_has_changes_since_tag(last_tag, "src", cwd=self.get_path()):
|
|
175
|
+
return UPGRADE_TYPE_MINOR
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
import griffe
|
|
179
|
+
|
|
180
|
+
module_name = self.get_package_name().replace("-", "_")
|
|
181
|
+
repo_path = str(self.get_path())
|
|
182
|
+
|
|
183
|
+
previous = griffe.load_git(
|
|
184
|
+
module_name,
|
|
185
|
+
ref=last_tag,
|
|
186
|
+
repo=repo_path,
|
|
187
|
+
search_paths=["src"],
|
|
188
|
+
)
|
|
189
|
+
current = griffe.load(
|
|
190
|
+
module_name,
|
|
191
|
+
search_paths=[str(self.get_path() / "src")],
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
if list(griffe.find_breaking_changes(previous, current)):
|
|
195
|
+
return UPGRADE_TYPE_MAJOR
|
|
196
|
+
|
|
197
|
+
return UPGRADE_TYPE_INTERMEDIATE
|
|
198
|
+
|
|
199
|
+
except Exception:
|
|
200
|
+
return UPGRADE_TYPE_MAJOR
|
|
201
|
+
|
|
142
202
|
def _collect_suite_dependencies(
|
|
143
203
|
self,
|
|
144
204
|
direct_dependencies: list[str],
|
|
@@ -164,7 +224,7 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
164
224
|
pkg = suite_workdir.get_package(dep_name)
|
|
165
225
|
if pkg:
|
|
166
226
|
# Get dependencies of this suite package and recurse
|
|
167
|
-
pkg_dependencies = pkg.
|
|
227
|
+
pkg_dependencies = pkg.get_dependencies_versions().keys()
|
|
168
228
|
collect_recursive(pkg_dependencies)
|
|
169
229
|
|
|
170
230
|
# Start with direct dependencies from pyproject.toml
|
|
@@ -180,6 +240,9 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
180
240
|
|
|
181
241
|
return suite_deps_ordered
|
|
182
242
|
|
|
243
|
+
def _get_critical_directories(self) -> list[str]:
|
|
244
|
+
return ["src"]
|
|
245
|
+
|
|
183
246
|
def _get_readme_content(self) -> ReadmeContentConfigValue | None:
|
|
184
247
|
from wexample_wex_addon_dev_python.config_value.python_package_readme_config_value import (
|
|
185
248
|
PythonPackageReadmeContentConfigValue,
|
|
@@ -187,7 +250,7 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
187
250
|
|
|
188
251
|
return PythonPackageReadmeContentConfigValue(workdir=self)
|
|
189
252
|
|
|
190
|
-
def
|
|
253
|
+
def _get_suite_workdir_class(self) -> type[FrameworkPackageSuiteWorkdir]:
|
|
191
254
|
from wexample_wex_addon_dev_python.workdir.python_packages_suite_workdir import (
|
|
192
255
|
PythonPackagesSuiteWorkdir,
|
|
193
256
|
)
|
|
@@ -210,7 +273,9 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
210
273
|
# Package is part of a suite that may have a venv configured.
|
|
211
274
|
if suite_workdir:
|
|
212
275
|
# Get all dependencies from pyproject.toml
|
|
213
|
-
pyproject_toml_dependencies =
|
|
276
|
+
pyproject_toml_dependencies = (
|
|
277
|
+
toml_file.get_dependencies_versions().keys()
|
|
278
|
+
)
|
|
214
279
|
|
|
215
280
|
# Get all packages from the suite ordered by dependencies (leaf -> trunk)
|
|
216
281
|
suite_packages = suite_workdir.get_ordered_packages()
|
|
@@ -289,25 +354,131 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
289
354
|
def _publish(self, force: bool = False) -> None:
|
|
290
355
|
from wexample_filestate_python.common.pipy_gateway import PipyGateway
|
|
291
356
|
from wexample_helpers.helpers.shell import shell_run
|
|
357
|
+
from wexample_helpers_git.helpers.git import (
|
|
358
|
+
git_push_tag,
|
|
359
|
+
git_tag_annotated,
|
|
360
|
+
git_tag_exists,
|
|
361
|
+
)
|
|
292
362
|
|
|
293
|
-
|
|
363
|
+
repository_url = self.search_app_or_suite_runtime_config(
|
|
364
|
+
"pdm.repository.url", default=None
|
|
365
|
+
).get_str_or_none()
|
|
294
366
|
|
|
295
367
|
package_name = self.get_package_name()
|
|
296
368
|
version = self.get_project_version()
|
|
369
|
+
|
|
370
|
+
# Private GitLab registry: trigger CI by pushing a git tag
|
|
371
|
+
if repository_url:
|
|
372
|
+
remote = self._get_deployment_remote_name()
|
|
373
|
+
tag = f"v{version}"
|
|
374
|
+
cwd = self.get_path()
|
|
375
|
+
|
|
376
|
+
if git_tag_exists(tag, cwd=cwd, inherit_stdio=False):
|
|
377
|
+
self.log(f"Tag {tag} already exists, skipping creation.")
|
|
378
|
+
else:
|
|
379
|
+
git_tag_annotated(tag, f"Release {tag}", cwd=cwd, inherit_stdio=True)
|
|
380
|
+
|
|
381
|
+
git_push_tag(tag, cwd=cwd, remote=remote, inherit_stdio=True)
|
|
382
|
+
return
|
|
383
|
+
|
|
384
|
+
# TODO: align public PyPI packages with the private registry approach — publish
|
|
385
|
+
# via a GitLab CI pipeline triggered by a git tag rather than running
|
|
386
|
+
# `pdm publish` locally.
|
|
387
|
+
# PyPI public: publish locally
|
|
388
|
+
client = PipyGateway(parent_io_handler=self)
|
|
297
389
|
if client.package_release_exists(package_name=package_name, version=version):
|
|
298
390
|
self.warning(
|
|
299
391
|
f'Trying to publish an existing release for package "{package_name}" version {version}'
|
|
300
392
|
)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
393
|
+
if not force:
|
|
394
|
+
return
|
|
395
|
+
|
|
396
|
+
repository_token = self.search_app_or_suite_runtime_config(
|
|
397
|
+
"pdm.repository.token", default=None
|
|
398
|
+
).get_str_or_none()
|
|
399
|
+
|
|
400
|
+
repository_username = self.search_app_or_suite_runtime_config(
|
|
401
|
+
"pdm.repository.username", default="__token__"
|
|
402
|
+
).get_str_or_none()
|
|
403
|
+
|
|
404
|
+
self.subtitle("Publishing to PyPI")
|
|
405
|
+
publish_cmd = ["pdm", "publish"]
|
|
406
|
+
|
|
407
|
+
username = repository_username or "__token__"
|
|
408
|
+
password = repository_token or self.get_env_parameter_or_suite_fallback(
|
|
409
|
+
"PIPY_TOKEN"
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
if username:
|
|
413
|
+
publish_cmd += ["--username", username]
|
|
414
|
+
if password:
|
|
415
|
+
publish_cmd += ["--password", password]
|
|
416
|
+
|
|
417
|
+
shell_run(publish_cmd, inherit_stdio=True, cwd=self.get_path())
|
|
418
|
+
|
|
419
|
+
def _wait_for_registry(self) -> None:
|
|
420
|
+
import time
|
|
421
|
+
import urllib.error
|
|
422
|
+
import urllib.request
|
|
423
|
+
|
|
424
|
+
repository_url = self.search_app_or_suite_runtime_config(
|
|
425
|
+
"pdm.repository.url", default=None
|
|
426
|
+
).get_str_or_none()
|
|
427
|
+
|
|
428
|
+
if not repository_url:
|
|
429
|
+
return # PyPI public — published locally, no polling needed
|
|
430
|
+
|
|
431
|
+
token = self.search_app_or_suite_runtime_config(
|
|
432
|
+
"pdm.repository.token", default=None
|
|
433
|
+
).get_str_or_none()
|
|
434
|
+
|
|
435
|
+
username = (
|
|
436
|
+
self.search_app_or_suite_runtime_config(
|
|
437
|
+
"pdm.repository.username", default="__token__"
|
|
438
|
+
).get_str_or_none()
|
|
439
|
+
or "__token__"
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
package = self.get_package_name()
|
|
443
|
+
version = self.get_project_version()
|
|
444
|
+
|
|
445
|
+
base = repository_url.rstrip("/")
|
|
446
|
+
url = f"{base}/simple/{package}/"
|
|
447
|
+
|
|
448
|
+
max_attempts = 40
|
|
449
|
+
delay = 30.0
|
|
450
|
+
|
|
451
|
+
self.log(f"Waiting for {package}=={version} to appear on registry…")
|
|
452
|
+
|
|
453
|
+
for attempt in range(1, max_attempts + 1):
|
|
454
|
+
try:
|
|
455
|
+
req = urllib.request.Request(url)
|
|
456
|
+
if token:
|
|
457
|
+
import base64
|
|
458
|
+
|
|
459
|
+
credentials = base64.b64encode(
|
|
460
|
+
f"{username}:{token}".encode()
|
|
461
|
+
).decode()
|
|
462
|
+
req.add_header("Authorization", f"Basic {credentials}")
|
|
463
|
+
with urllib.request.urlopen(req, timeout=10) as resp:
|
|
464
|
+
if resp.status == 200:
|
|
465
|
+
content = resp.read().decode()
|
|
466
|
+
if version in content:
|
|
467
|
+
self.success(f"{package}=={version} is available.")
|
|
468
|
+
return
|
|
469
|
+
except urllib.error.HTTPError as e:
|
|
470
|
+
if e.code != 404:
|
|
471
|
+
raise
|
|
472
|
+
except Exception:
|
|
473
|
+
pass
|
|
474
|
+
|
|
475
|
+
self.log(
|
|
476
|
+
f"Not yet available (attempt {attempt}/{max_attempts}), "
|
|
477
|
+
f"retrying in {int(delay)}s…"
|
|
478
|
+
)
|
|
479
|
+
time.sleep(delay)
|
|
480
|
+
|
|
481
|
+
raise RuntimeError(
|
|
482
|
+
f"Timed out waiting for {package}=={version} on registry after "
|
|
483
|
+
f"{max_attempts * int(delay) // 60} minutes."
|
|
484
|
+
)
|
|
@@ -243,15 +243,15 @@ class PythonWorkdir(CodeBaseWorkdir):
|
|
|
243
243
|
|
|
244
244
|
return raw_value
|
|
245
245
|
|
|
246
|
-
def save_dependency(
|
|
247
|
-
|
|
246
|
+
def save_dependency(
|
|
247
|
+
self, package: CodeBaseWorkdir, version: str, operator: str = "=="
|
|
248
|
+
) -> bool:
|
|
248
249
|
config = self.get_app_config_file()
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return updated
|
|
250
|
+
return config.add_dependency_from_string(
|
|
251
|
+
package_name=package.get_package_name(),
|
|
252
|
+
version=version,
|
|
253
|
+
operator=operator,
|
|
254
|
+
)
|
|
255
255
|
|
|
256
256
|
def save_project_config_file(self, config: StructuredData) -> None:
|
|
257
257
|
"""Save the project configuration to pyproject.toml."""
|
|
@@ -298,47 +298,6 @@ class PythonWorkdir(CodeBaseWorkdir):
|
|
|
298
298
|
if report_path.exists():
|
|
299
299
|
self.info(f"Report: @path{{{report_path}}}")
|
|
300
300
|
|
|
301
|
-
def update_dependencies(self, dependencies_map: dict[str, str]) -> None:
|
|
302
|
-
"""Update dependencies versions based on the provided map.
|
|
303
|
-
|
|
304
|
-
Args:
|
|
305
|
-
dependencies_map: Dictionary mapping package names to their new versions.
|
|
306
|
-
Example: {"wexample-helpers": "0.2.3", "attrs": "23.1.0"}
|
|
307
|
-
"""
|
|
308
|
-
from packaging.requirements import Requirement
|
|
309
|
-
from packaging.utils import canonicalize_name
|
|
310
|
-
|
|
311
|
-
config_file = self.get_app_config_file()
|
|
312
|
-
|
|
313
|
-
# Canonicalize the keys in dependencies_map for consistent matching
|
|
314
|
-
canonical_map = {
|
|
315
|
-
canonicalize_name(name): version
|
|
316
|
-
for name, version in dependencies_map.items()
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
# Get current dependencies
|
|
320
|
-
current_deps = config_file.list_dependencies_names()
|
|
321
|
-
|
|
322
|
-
# Update each dependency if it's in the map
|
|
323
|
-
for dep_spec in current_deps:
|
|
324
|
-
try:
|
|
325
|
-
req = Requirement(dep_spec)
|
|
326
|
-
canonical_name = canonicalize_name(req.name)
|
|
327
|
-
|
|
328
|
-
# If this dependency is in our update map, update it
|
|
329
|
-
if canonical_name in canonical_map:
|
|
330
|
-
new_version = canonical_map[canonical_name]
|
|
331
|
-
# Use add_dependency which handles removal of old version
|
|
332
|
-
config_file.add_dependency(
|
|
333
|
-
package_name=req.name, version=new_version
|
|
334
|
-
)
|
|
335
|
-
except Exception:
|
|
336
|
-
# Skip unparsable dependencies
|
|
337
|
-
continue
|
|
338
|
-
|
|
339
|
-
# Save the updated config
|
|
340
|
-
config_file.write_parsed()
|
|
341
|
-
|
|
342
301
|
def _create_init_children_factory(self) -> ChildrenFileFactoryOption:
|
|
343
302
|
from wexample_filestate.const.disk import DiskItemType
|
|
344
303
|
from wexample_filestate.const.globals import NAME_PATTERN_NO_LEADING_DOT
|
|
@@ -517,7 +476,7 @@ class PythonWorkdir(CodeBaseWorkdir):
|
|
|
517
476
|
toml_file = self.get_app_config_file()
|
|
518
477
|
# Get all dependencies from pyproject.toml
|
|
519
478
|
python_install_dependencies_in_venv(
|
|
520
|
-
venv_path=venv_path, names=toml_file.
|
|
479
|
+
venv_path=venv_path, names=toml_file.get_dependencies_versions().keys()
|
|
521
480
|
)
|
|
522
481
|
|
|
523
482
|
def _on_test_event(self, event: Event) -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-python
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: Python dev addon for wex
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -11,61 +11,36 @@ Project-URL: homepage, https://github.com/wexample/python-wex-dev-python
|
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
12
|
Requires-Dist: attrs>=23.1.0
|
|
13
13
|
Requires-Dist: cattrs>=23.1.0
|
|
14
|
+
Requires-Dist: griffe>=2.0.2
|
|
14
15
|
Requires-Dist: networkx
|
|
15
16
|
Requires-Dist: pylint
|
|
16
17
|
Requires-Dist: pyright
|
|
17
|
-
Requires-Dist: wexample-filestate-python
|
|
18
|
-
Requires-Dist: wexample-wex-addon-app
|
|
19
|
-
Requires-Dist: wexample-wex-core==6.0.67
|
|
18
|
+
Requires-Dist: wexample-filestate-python>=0.1.0
|
|
19
|
+
Requires-Dist: wexample-wex-addon-app>=1.0.0
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: pytest; extra == "dev"
|
|
22
22
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
|
|
25
|
-
#
|
|
25
|
+
# wex_addon_dev_python
|
|
26
26
|
|
|
27
|
-
Version: 0.0
|
|
27
|
+
Version: 0.1.0
|
|
28
28
|
|
|
29
29
|
Python dev addon for wex
|
|
30
30
|
|
|
31
31
|
## Table of Contents
|
|
32
32
|
|
|
33
|
-
- [Status Compatibility](#status-compatibility)
|
|
34
|
-
- [Api Reference](#api-reference)
|
|
35
33
|
- [Tests](#tests)
|
|
36
|
-
- [
|
|
34
|
+
- [Suite Integration](#suite-integration)
|
|
35
|
+
- [Dependencies](#dependencies)
|
|
37
36
|
- [Versioning](#versioning)
|
|
38
|
-
- [Changelog](#changelog)
|
|
39
|
-
- [Migration Notes](#migration-notes)
|
|
40
|
-
- [Roadmap](#roadmap)
|
|
41
|
-
- [Security](#security)
|
|
42
|
-
- [Privacy](#privacy)
|
|
43
|
-
- [Support](#support)
|
|
44
|
-
- [Contribution Guidelines](#contribution-guidelines)
|
|
45
|
-
- [Maintainers](#maintainers)
|
|
46
37
|
- [License](#license)
|
|
47
|
-
- [Useful Links](#useful-links)
|
|
48
38
|
- [Suite Integration](#suite-integration)
|
|
49
|
-
- [Compatibility Matrix](#compatibility-matrix)
|
|
50
|
-
- [Dependencies](#dependencies)
|
|
51
39
|
- [Suite Signature](#suite-signature)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
**Maturity**: Production-ready
|
|
57
|
-
|
|
58
|
-
**Python Support**: >=3.10
|
|
59
|
-
|
|
60
|
-
**OS Support**: Linux, macOS, Windows
|
|
61
|
-
|
|
62
|
-
**Status**: Actively maintained
|
|
63
|
-
|
|
64
|
-
## API Reference
|
|
65
|
-
|
|
66
|
-
Full API documentation is available in the source code docstrings.
|
|
67
|
-
|
|
68
|
-
Key modules and classes are documented with type hints for better IDE support.
|
|
40
|
+
- [Roadmap](#roadmap)
|
|
41
|
+
- [Status Compatibility](#status-compatibility)
|
|
42
|
+
- [Useful Links](#useful-links)
|
|
43
|
+
- [Migration Notes](#migration-notes)
|
|
69
44
|
|
|
70
45
|
## Tests
|
|
71
46
|
|
|
@@ -116,16 +91,26 @@ To enforce a minimum coverage percentage:
|
|
|
116
91
|
|
|
117
92
|
This will cause the test suite to fail if coverage drops below 80%.
|
|
118
93
|
|
|
119
|
-
##
|
|
94
|
+
## Integration in the Suite
|
|
120
95
|
|
|
121
|
-
|
|
96
|
+
This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
|
|
122
97
|
|
|
123
|
-
|
|
124
|
-
- **Code formatting**: Enforced with black and isort
|
|
125
|
-
- **Linting**: Comprehensive checks with custom scripts and tools
|
|
126
|
-
- **Testing**: High test coverage requirements
|
|
98
|
+
### Related Packages
|
|
127
99
|
|
|
128
|
-
|
|
100
|
+
The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
|
|
101
|
+
|
|
102
|
+
Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
|
|
103
|
+
|
|
104
|
+
## Dependencies
|
|
105
|
+
|
|
106
|
+
- attrs: >=23.1.0
|
|
107
|
+
- cattrs: >=23.1.0
|
|
108
|
+
- griffe: >=2.0.2
|
|
109
|
+
- networkx:
|
|
110
|
+
- pylint:
|
|
111
|
+
- pyright:
|
|
112
|
+
- wexample-filestate-python: >=0.1.0
|
|
113
|
+
- wexample-wex-addon-app: >=1.0.0
|
|
129
114
|
|
|
130
115
|
## Versioning & Compatibility Policy
|
|
131
116
|
|
|
@@ -137,72 +122,45 @@ Wexample packages follow **Semantic Versioning** (SemVer):
|
|
|
137
122
|
|
|
138
123
|
We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
|
|
139
124
|
|
|
140
|
-
##
|
|
141
|
-
|
|
142
|
-
See [CHANGELOG.md](CHANGELOG.md) for detailed version history and release notes.
|
|
143
|
-
|
|
144
|
-
Major changes are documented with migration guides when applicable.
|
|
145
|
-
|
|
146
|
-
## Migration Notes
|
|
147
|
-
|
|
148
|
-
When upgrading between major versions, refer to the migration guides in the documentation.
|
|
149
|
-
|
|
150
|
-
Breaking changes are clearly documented with upgrade paths and examples.
|
|
151
|
-
|
|
152
|
-
## Known Limitations & Roadmap
|
|
153
|
-
|
|
154
|
-
Current limitations and planned features are tracked in the GitHub issues.
|
|
155
|
-
|
|
156
|
-
See the [project roadmap](https://github.com/wexample/python-wex_addon_dev_python/issues) for upcoming features and improvements.
|
|
157
|
-
|
|
158
|
-
## Security Policy
|
|
159
|
-
|
|
160
|
-
### Reporting Vulnerabilities
|
|
125
|
+
## License
|
|
161
126
|
|
|
162
|
-
|
|
127
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
163
128
|
|
|
164
|
-
|
|
129
|
+
Free to use in both personal and commercial projects.
|
|
165
130
|
|
|
166
|
-
|
|
131
|
+
## Integration in the Suite
|
|
167
132
|
|
|
168
|
-
|
|
133
|
+
This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
|
|
169
134
|
|
|
170
|
-
|
|
135
|
+
### Related Packages
|
|
171
136
|
|
|
172
|
-
|
|
137
|
+
The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
|
|
173
138
|
|
|
174
|
-
|
|
139
|
+
Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
|
|
175
140
|
|
|
176
|
-
|
|
177
|
-
- **GitHub Discussions**: Questions and community support
|
|
178
|
-
- **Documentation**: Comprehensive guides and API reference
|
|
179
|
-
- **Email**: contact@wexample.com for general inquiries
|
|
141
|
+
# About us
|
|
180
142
|
|
|
181
|
-
|
|
143
|
+
[Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
|
|
182
144
|
|
|
183
|
-
|
|
145
|
+
This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
|
|
184
146
|
|
|
185
|
-
|
|
147
|
+
Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
|
|
186
148
|
|
|
187
|
-
|
|
149
|
+
## Known Limitations & Roadmap
|
|
188
150
|
|
|
189
|
-
|
|
190
|
-
2. **Create** a feature branch
|
|
191
|
-
3. **Make** your changes
|
|
192
|
-
4. **Test** thoroughly
|
|
193
|
-
5. **Submit** a pull request
|
|
151
|
+
Current limitations and planned features are tracked in the GitHub issues.
|
|
194
152
|
|
|
195
|
-
|
|
153
|
+
See the [project roadmap](https://github.com/wexample/python-wex_addon_dev_python/issues) for upcoming features and improvements.
|
|
196
154
|
|
|
197
|
-
|
|
155
|
+
## Status & Compatibility
|
|
198
156
|
|
|
199
|
-
|
|
157
|
+
**Maturity**: Production-ready
|
|
200
158
|
|
|
201
|
-
|
|
159
|
+
**Python Support**: >=3.10
|
|
202
160
|
|
|
203
|
-
|
|
161
|
+
**OS Support**: Linux, macOS, Windows
|
|
204
162
|
|
|
205
|
-
|
|
163
|
+
**Status**: Actively maintained
|
|
206
164
|
|
|
207
165
|
## Useful Links
|
|
208
166
|
|
|
@@ -210,41 +168,10 @@ Free to use in both personal and commercial projects.
|
|
|
210
168
|
- **Documentation**: [docs.wexample.com](https://docs.wexample.com)
|
|
211
169
|
- **Issue Tracker**: https://github.com/wexample/python-wex-addon-dev-python/issues
|
|
212
170
|
- **Discussions**: https://github.com/wexample/python-wex-addon-dev-python/discussions
|
|
213
|
-
- **PyPI**: [pypi.org/project/
|
|
214
|
-
|
|
215
|
-
## Integration in the Suite
|
|
216
|
-
|
|
217
|
-
This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
|
|
171
|
+
- **PyPI**: [pypi.org/project/wex_addon_dev_python](https://pypi.org/project/wex_addon_dev_python/)
|
|
218
172
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
|
|
222
|
-
|
|
223
|
-
Visit the [Wexample Suite documentation](https://docs.wexample.com) for the complete package ecosystem.
|
|
224
|
-
|
|
225
|
-
## Compatibility Matrix
|
|
226
|
-
|
|
227
|
-
This package is part of the Wexample suite and is compatible with other suite packages.
|
|
228
|
-
|
|
229
|
-
Refer to each package's documentation for specific version compatibility requirements.
|
|
230
|
-
|
|
231
|
-
## Dependencies
|
|
232
|
-
|
|
233
|
-
- attrs: >=23.1.0
|
|
234
|
-
- cattrs: >=23.1.0
|
|
235
|
-
- networkx:
|
|
236
|
-
- pylint:
|
|
237
|
-
- pyright:
|
|
238
|
-
- wexample-filestate-python: ==0.0.58
|
|
239
|
-
- wexample-wex-addon-app: ==0.0.55
|
|
240
|
-
- wexample-wex-core: ==6.0.67
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
# About us
|
|
244
|
-
|
|
245
|
-
[Wexample](https://wexample.com) stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
|
|
246
|
-
|
|
247
|
-
This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
|
|
173
|
+
## Migration Notes
|
|
248
174
|
|
|
249
|
-
|
|
175
|
+
When upgrading between major versions, refer to the migration guides in the documentation.
|
|
250
176
|
|
|
177
|
+
Breaking changes are clearly documented with upgrade paths and examples.
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
wexample_wex_addon_dev_python-0.0.
|
|
2
|
-
wexample_wex_addon_dev_python-0.0.
|
|
3
|
-
wexample_wex_addon_dev_python-0.0.
|
|
1
|
+
wexample_wex_addon_dev_python-0.1.0.dist-info/METADATA,sha256=Fc49_n_IPbkQvqXpmsXHCGnZL5WqcwMiuDcYJIOmIVQ,6259
|
|
2
|
+
wexample_wex_addon_dev_python-0.1.0.dist-info/WHEEL,sha256=Z36eTX6lG3PITRleSd5hAZHCcz52yg3c0JQVxKBbLW0,90
|
|
3
|
+
wexample_wex_addon_dev_python-0.1.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
|
4
4
|
wexample_wex_addon_dev_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
wexample_wex_addon_dev_python/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
wexample_wex_addon_dev_python/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
wexample_wex_addon_dev_python/commands/code/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
wexample_wex_addon_dev_python/commands/code/check.py,sha256=
|
|
8
|
+
wexample_wex_addon_dev_python/commands/code/check.py,sha256=Bm5ON0UA7QmFTfO70QkfkqjzpGJu3fAw3tQjzdxbW7I,3404
|
|
9
9
|
wexample_wex_addon_dev_python/commands/code/check/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
wexample_wex_addon_dev_python/commands/code/check/mypy.py,sha256=hZ1taOAofaFgqhtbHLXA14-4cFkVcw6QUi9PmpbEKuk,1401
|
|
11
11
|
wexample_wex_addon_dev_python/commands/code/check/pylint.py,sha256=cSnirIVrMH9-_ETAiIVdjCvHQWcNJzCwwAfvcxNBodM,3328
|
|
12
12
|
wexample_wex_addon_dev_python/commands/code/check/pyright.py,sha256=jCKZxQ5Ln2Vh1QlhKqz3i0djnQwWbNHzDcttu41jhsI,3619
|
|
13
|
-
wexample_wex_addon_dev_python/commands/code/format.py,sha256=
|
|
13
|
+
wexample_wex_addon_dev_python/commands/code/format.py,sha256=7HnXLl2-b_ZYsuj45wDr1ue9AL7g7gOo12fLkV1dilE,2530
|
|
14
14
|
wexample_wex_addon_dev_python/commands/code/format/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
15
15
|
wexample_wex_addon_dev_python/commands/code/format/black.py,sha256=wo3BEODFD6BUrmnfheESMyLppLPwtvcgkOVfvHWdAZs,1462
|
|
16
16
|
wexample_wex_addon_dev_python/commands/code/format/isort.py,sha256=pRYYPZWFza6e_HgKYpYplzV5hwJvbM3NNJ_-A3x1yV8,1540
|
|
17
17
|
wexample_wex_addon_dev_python/commands/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
wexample_wex_addon_dev_python/commands/examples/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
wexample_wex_addon_dev_python/commands/examples/utils/some_example_type.py,sha256=zusGlLOLkt2EpPFk38FIRA6d_5Q92Y7-TLj8ofHhQk0,121
|
|
20
|
-
wexample_wex_addon_dev_python/commands/examples/validate.py,sha256=
|
|
20
|
+
wexample_wex_addon_dev_python/commands/examples/validate.py,sha256=IgUHNpkdc_Z76HGDWmCvztP7B3ars0Cu2Yknq9MGt0o,752
|
|
21
21
|
wexample_wex_addon_dev_python/commands/release/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
wexample_wex_addon_dev_python/config_value/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
wexample_wex_addon_dev_python/config_value/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -29,18 +29,19 @@ wexample_wex_addon_dev_python/const/python.py,sha256=jxdPt5CnD0dcp4SmobEc_c7XcCk
|
|
|
29
29
|
wexample_wex_addon_dev_python/file/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
30
|
wexample_wex_addon_dev_python/file/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
31
|
wexample_wex_addon_dev_python/file/python_app_iml_file.py,sha256=l6YHEILxSGFjOvYWY20zIyAODjOIfuyHsuCfSMw0jVE,1201
|
|
32
|
-
wexample_wex_addon_dev_python/file/python_pyproject_toml_file.py,sha256=
|
|
32
|
+
wexample_wex_addon_dev_python/file/python_pyproject_toml_file.py,sha256=31KcRaewYzK1mHYFLSltyZ9WhuEzV98I5vllmmGWGkU,15952
|
|
33
33
|
wexample_wex_addon_dev_python/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
wexample_wex_addon_dev_python/middleware/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
35
|
wexample_wex_addon_dev_python/middleware/each_python_file_middleware.py,sha256=UzNEpedCYf31aNONFl0SuSJnoXRzhJhgEiTCaPark6E,2311
|
|
36
36
|
wexample_wex_addon_dev_python/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
wexample_wex_addon_dev_python/python_addon_manager.py,sha256=Mmr9F5lOS2gbb8JTB4-vTri4Qn5Cd2Jukjk7uiTr1Hs,582
|
|
38
38
|
wexample_wex_addon_dev_python/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
wexample_wex_addon_dev_python/resources/package_publish_gitlab.yml,sha256=WVMj-DeFedQak5s5FraEnM1Rx1-ut4KgPodvAVv25ZM,304
|
|
39
40
|
wexample_wex_addon_dev_python/resources/readme_templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
41
|
wexample_wex_addon_dev_python/resources/readme_templates/tests.md.j2,sha256=tKLcDwx7jhQkryXIxWr12AK-hKEaP6Rusu2MrluiABs,1289
|
|
41
42
|
wexample_wex_addon_dev_python/workdir/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
43
|
wexample_wex_addon_dev_python/workdir/__pycache__/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
-
wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=
|
|
44
|
+
wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=Fd2A7Qpsy_jstE4zj6AD4PPbMSOGkoBibhCFLDAZrXo,17637
|
|
44
45
|
wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py,sha256=ICHHewLpsXiheYzGDEahphBryH98ZVezWzSAy6A5w5I,2874
|
|
45
|
-
wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=
|
|
46
|
-
wexample_wex_addon_dev_python-0.0.
|
|
46
|
+
wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=tx6UcaBHnrq9khQ6ndG14BzFPNOlqhl-626iNoL6T1o,18078
|
|
47
|
+
wexample_wex_addon_dev_python-0.1.0.dist-info/RECORD,,
|
|
File without changes
|