wexample-wex-addon-dev-python 15.8.1__py3-none-any.whl → 15.10.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/workdir/python_package_workdir.py +70 -3
- {wexample_wex_addon_dev_python-15.8.1.dist-info → wexample_wex_addon_dev_python-15.10.0.dist-info}/METADATA +3 -3
- {wexample_wex_addon_dev_python-15.8.1.dist-info → wexample_wex_addon_dev_python-15.10.0.dist-info}/RECORD +5 -5
- {wexample_wex_addon_dev_python-15.8.1.dist-info → wexample_wex_addon_dev_python-15.10.0.dist-info}/WHEEL +0 -0
- {wexample_wex_addon_dev_python-15.8.1.dist-info → wexample_wex_addon_dev_python-15.10.0.dist-info}/entry_points.txt +0 -0
|
@@ -58,6 +58,44 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
58
58
|
"Install: pipx install pdm — then run: wex core::env/configure"
|
|
59
59
|
)
|
|
60
60
|
|
|
61
|
+
def collect_pypi_upload(self) -> str | None:
|
|
62
|
+
"""Wait for this package's background PyPI upload, if one is running,
|
|
63
|
+
and say what went wrong when it failed (None when it did not)."""
|
|
64
|
+
import os
|
|
65
|
+
import shutil
|
|
66
|
+
import time
|
|
67
|
+
|
|
68
|
+
upload_dir = self._get_pypi_upload_dir()
|
|
69
|
+
pid_file = upload_dir / "pid"
|
|
70
|
+
if not pid_file.is_file():
|
|
71
|
+
return None
|
|
72
|
+
pid = int(pid_file.read_text().strip() or 0)
|
|
73
|
+
rc_file = upload_dir / "rc"
|
|
74
|
+
# Done once the shell wrote the exit code, its last act. Its /proc entry
|
|
75
|
+
# outlives it as a zombie until this process reaps it, so it is no sign
|
|
76
|
+
# of life — waiting on it alone hung the release forever.
|
|
77
|
+
while pid and not rc_file.is_file() and os.path.exists(f"/proc/{pid}"):
|
|
78
|
+
try:
|
|
79
|
+
if os.waitpid(pid, os.WNOHANG)[0]:
|
|
80
|
+
break
|
|
81
|
+
except ChildProcessError:
|
|
82
|
+
# Not this process's child (started by an earlier one): only
|
|
83
|
+
# its /proc entry tells.
|
|
84
|
+
pass
|
|
85
|
+
time.sleep(1)
|
|
86
|
+
try:
|
|
87
|
+
os.waitpid(pid, os.WNOHANG)
|
|
88
|
+
except ChildProcessError:
|
|
89
|
+
pass
|
|
90
|
+
rc = rc_file.read_text().strip() if rc_file.is_file() else "unknown"
|
|
91
|
+
log_file = upload_dir / "log"
|
|
92
|
+
report = None
|
|
93
|
+
if rc != "0":
|
|
94
|
+
tail = log_file.read_text(errors="replace").splitlines()[-5:] if log_file.is_file() else []
|
|
95
|
+
report = f"{self.get_package_name()}: PyPI upload failed (exit {rc}): " + " / ".join(tail)
|
|
96
|
+
shutil.rmtree(upload_dir, ignore_errors=True)
|
|
97
|
+
return report
|
|
98
|
+
|
|
61
99
|
def get_gitlab_registry_url(self) -> str | None:
|
|
62
100
|
"""The GitLab PyPI registry of the group, when the suite publishes there.
|
|
63
101
|
|
|
@@ -339,6 +377,9 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
339
377
|
def _get_critical_directories(self) -> list[str]:
|
|
340
378
|
return ["src"]
|
|
341
379
|
|
|
380
|
+
def _get_pypi_upload_dir(self):
|
|
381
|
+
return self.get_path() / ".wex" / "tmp" / "pypi-upload"
|
|
382
|
+
|
|
342
383
|
def _get_readme_content(self) -> ReadmeContentConfigValue | None:
|
|
343
384
|
from wexample_wex_addon_dev_python.config_value.python_package_readme_config_value import (
|
|
344
385
|
PythonPackageReadmeContentConfigValue,
|
|
@@ -494,7 +535,10 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
494
535
|
if self.get_gitlab_registry_url():
|
|
495
536
|
self._publish_to_gitlab_registry(force=force)
|
|
496
537
|
try:
|
|
497
|
-
|
|
538
|
+
# In the background: PyPI only mirrors the GitLab registry,
|
|
539
|
+
# nothing waits for it. The suite's publication collects
|
|
540
|
+
# the uploads at its end (`collect_pypi_upload`).
|
|
541
|
+
self._publish_to_pypi(force=force, background=True)
|
|
498
542
|
except ShellCommandFailedException as exception:
|
|
499
543
|
self.warning(
|
|
500
544
|
f"PyPI refused {package_name} {version}, published on the GitLab "
|
|
@@ -560,7 +604,7 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
560
604
|
cwd=self.get_path(),
|
|
561
605
|
)
|
|
562
606
|
|
|
563
|
-
def _publish_to_pypi(self, force: bool = False) -> None:
|
|
607
|
+
def _publish_to_pypi(self, force: bool = False, background: bool = False) -> None:
|
|
564
608
|
from wexample_filestate_python.common.pipy_gateway import PipyGateway
|
|
565
609
|
from wexample_helpers.helper.shell import shell_run
|
|
566
610
|
|
|
@@ -596,7 +640,30 @@ class PythonPackageWorkdir(PythonWorkdir):
|
|
|
596
640
|
if password:
|
|
597
641
|
publish_cmd += ["--password", password]
|
|
598
642
|
|
|
599
|
-
|
|
643
|
+
if not background:
|
|
644
|
+
shell_run(publish_cmd, inherit_stdio=True, cwd=self.get_path())
|
|
645
|
+
return
|
|
646
|
+
|
|
647
|
+
import shlex
|
|
648
|
+
import shutil
|
|
649
|
+
import subprocess
|
|
650
|
+
|
|
651
|
+
# From a copy of the distributions: dist/ is cleaned as soon as this
|
|
652
|
+
# returns. The exit code is written where collect_pypi_upload reads it.
|
|
653
|
+
upload_dir = self._get_pypi_upload_dir()
|
|
654
|
+
shutil.rmtree(upload_dir, ignore_errors=True)
|
|
655
|
+
shutil.copytree(self.get_path() / "dist", upload_dir / "dist")
|
|
656
|
+
command = " ".join(shlex.quote(part) for part in [*publish_cmd, "--dest", str(upload_dir / "dist")])
|
|
657
|
+
with open(upload_dir / "log", "w") as log:
|
|
658
|
+
process = subprocess.Popen(
|
|
659
|
+
["sh", "-c", f'( {command} ); echo $? > "{upload_dir / "rc"}"'],
|
|
660
|
+
cwd=self.get_path(),
|
|
661
|
+
stdout=log,
|
|
662
|
+
stderr=subprocess.STDOUT,
|
|
663
|
+
start_new_session=True,
|
|
664
|
+
)
|
|
665
|
+
(upload_dir / "pid").write_text(str(process.pid))
|
|
666
|
+
self.log(f"PyPI upload of {package_name} {version} running in the background.")
|
|
600
667
|
|
|
601
668
|
def _wait_for_registry(self) -> None:
|
|
602
669
|
from wexample_helpers.helper.polling_callback_manager import (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-python
|
|
3
|
-
Version: 15.
|
|
3
|
+
Version: 15.10.0
|
|
4
4
|
Summary: Extends wex with commands to format, lint, and rename Python symbols, plus workdir types for Python packages and suites
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Requires-Dist: pyright
|
|
|
20
20
|
Requires-Dist: wexample-api>=6.8.0
|
|
21
21
|
Requires-Dist: wexample-filestate-python>=9.4.0
|
|
22
22
|
Requires-Dist: wexample-wex-addon-ai>=19.1.0
|
|
23
|
-
Requires-Dist: wexample-wex-addon-app>=35.
|
|
23
|
+
Requires-Dist: wexample-wex-addon-app>=35.4.0
|
|
24
24
|
Provides-Extra: dev
|
|
25
25
|
Requires-Dist: pytest; extra == "dev"
|
|
26
26
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -28,7 +28,7 @@ Description-Content-Type: text/markdown
|
|
|
28
28
|
|
|
29
29
|
# wex_addon_dev_python
|
|
30
30
|
|
|
31
|
-
Version: 15.
|
|
31
|
+
Version: 15.10.0
|
|
32
32
|
|
|
33
33
|
Extends wex with commands to format, lint, and rename Python symbols, plus workdir types for Python packages and suites
|
|
34
34
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
wexample_wex_addon_dev_python-15.
|
|
2
|
-
wexample_wex_addon_dev_python-15.
|
|
3
|
-
wexample_wex_addon_dev_python-15.
|
|
1
|
+
wexample_wex_addon_dev_python-15.10.0.dist-info/METADATA,sha256=pweUBvKRQKFgP_QvJFJfTvEJbO0HOE-qsxxPc0pypvA,3510
|
|
2
|
+
wexample_wex_addon_dev_python-15.10.0.dist-info/WHEEL,sha256=IuIk3wbaEnFH1cx75iM2R1CmliRI3dFLXTbRakgvgFQ,90
|
|
3
|
+
wexample_wex_addon_dev_python-15.10.0.dist-info/entry_points.txt,sha256=4WCjdYUa09eJPSM1ahhnId0BTg7ncgmLgeKtfKjuUy4,127
|
|
4
4
|
wexample_wex_addon_dev_python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
wexample_wex_addon_dev_python/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
wexample_wex_addon_dev_python/commands/code/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -85,7 +85,7 @@ wexample_wex_addon_dev_python/services/python/service.yml,sha256=28gvNQIzZ0T0PBw
|
|
|
85
85
|
wexample_wex_addon_dev_python/workdir/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
86
86
|
wexample_wex_addon_dev_python/workdir/mixin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
87
|
wexample_wex_addon_dev_python/workdir/mixin/with_profiling_python_workdir_mixin.py,sha256=PA_kqwe2kF5t1nKakX5Q-6fant2R18aEnZfkjr6iJ6k,3097
|
|
88
|
-
wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=
|
|
88
|
+
wexample_wex_addon_dev_python/workdir/python_package_workdir.py,sha256=RNfDVsQ28jU99ydliNhk5eE1bKv4ln6KSieqeYM71ic,28035
|
|
89
89
|
wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py,sha256=7Jb5mKGNV2RjFtrFhUm6jbkiTfLDmy7sA97UGHITVdw,2902
|
|
90
90
|
wexample_wex_addon_dev_python/workdir/python_workdir.py,sha256=DS3kGcy7pmeL5ZjlttaKKifBemRyipLGQuWeDDVceFw,33227
|
|
91
|
-
wexample_wex_addon_dev_python-15.
|
|
91
|
+
wexample_wex_addon_dev_python-15.10.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|