-
Notifications
You must be signed in to change notification settings - Fork 0
feat: scaffold portablemc 5.x build and packaging #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,7 +23,7 @@ | |
| import importlib | ||
| import importlib.abc | ||
| import importlib.machinery | ||
| import importlib.util | ||
|
Check failure on line 26 in scripts/local_portablemc.py
|
||
| import logging | ||
| import sys | ||
| import types | ||
|
|
@@ -32,7 +32,7 @@ | |
| from typing import TYPE_CHECKING | ||
|
|
||
| if TYPE_CHECKING: | ||
| from typing import Sequence | ||
|
Check failure on line 35 in scripts/local_portablemc.py
|
||
|
|
||
| log = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -54,44 +54,81 @@ | |
| """Return the first portablemc wheel found in the target/wheels dir.""" | ||
| if not _WHEEL_SEARCH.is_dir(): | ||
| return None | ||
| for whl in sorted(_WHEEL_SEARCH.glob("portablemc-*.whl")): | ||
| return whl | ||
| # Try different wheel naming patterns (maturin uses portablemc_py-*) | ||
| patterns = ["portablemc_py-*.whl", "portablemc-*.whl"] | ||
| for pattern in patterns: | ||
| for whl in sorted(_WHEEL_SEARCH.glob(pattern), reverse=True): | ||
|
Comment on lines
+58
to
+60
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (bug_risk): Wheel selection uses lexicographic order and prefers This contradicts the “Return most recent” intent: selection is based on filename ordering within each pattern, plus unconditional preference for |
||
| return whl # Return most recent | ||
| return None | ||
|
|
||
|
|
||
| def _pyd_present() -> bool: | ||
| """True when the native extension already lives in the vendored tree.""" | ||
| if not _PMC_PKG_DIR.is_dir(): | ||
| return False | ||
| return any(_PMC_PKG_DIR.glob("_portablemc*.pyd")) | ||
| # Check for both naming conventions (.pyd for Windows, .so for Linux/Mac) | ||
| patterns = ["_portablemc*.pyd", "_portablemc*.so", "portablemc_py*.pyd", "portablemc_py*.so"] | ||
| for pattern in patterns: | ||
| if any(_PMC_PKG_DIR.glob(pattern)): | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| def _extract_pyd_from_wheel(wheel: Path) -> bool: | ||
| """ | ||
| Extract every file from the wheel's ``portablemc/`` directory into the | ||
| Extract every file from the wheel's package directory into the | ||
| vendored Python tree. Skips dist-info and __pycache__ entries. | ||
|
|
||
| The wheel may contain either: | ||
| - portablemc/ (if built with package name portablemc) | ||
| - portablemc_py/ (if built with maturin default naming) | ||
|
|
||
| Files are renamed appropriately to create a portablemc/ package. | ||
|
|
||
| Returns True on success. | ||
| """ | ||
| try: | ||
| _PMC_PKG_DIR.mkdir(parents=True, exist_ok=True) | ||
| with zipfile.ZipFile(wheel, "r") as zf: | ||
| extracted = 0 | ||
| # Detect the package prefix in the wheel | ||
| prefixes = ["portablemc/", "portablemc_py/"] | ||
| found_prefix = None | ||
| for name in zf.namelist(): | ||
| for prefix in prefixes: | ||
| if name.startswith(prefix): | ||
| found_prefix = prefix | ||
| break | ||
| if found_prefix: | ||
| break | ||
|
|
||
| if not found_prefix: | ||
| log.warning("No portablemc package found in wheel %s", wheel.name) | ||
| return False | ||
|
|
||
| for name in zf.namelist(): | ||
| if not name.startswith("portablemc/"): | ||
| if not name.startswith(found_prefix): | ||
| continue | ||
| if "__pycache__" in name or name.endswith("/"): | ||
| continue | ||
| # Strip the leading "portablemc/" prefix; write relative to _PMC_PKG_DIR | ||
| rel = name[len("portablemc/"):] | ||
| if ".dist-info" in name: | ||
| continue | ||
|
|
||
| # Strip the leading prefix; write relative to _PMC_PKG_DIR | ||
| rel = name[len(found_prefix):] | ||
| if not rel: | ||
| continue | ||
|
|
||
| # Rename portablemc_py to _portablemc in filenames | ||
| rel = rel.replace("portablemc_py", "_portablemc") | ||
|
|
||
| dest = _PMC_PKG_DIR / rel | ||
| dest.parent.mkdir(parents=True, exist_ok=True) | ||
| data = zf.read(name) | ||
| dest.write_bytes(data) | ||
| extracted += 1 | ||
| log.debug("Extracted %s → %s", name, dest) | ||
|
|
||
| log.info("Extracted %d files from %s into %s", extracted, wheel.name, _PMC_PKG_DIR) | ||
| return extracted > 0 | ||
| except Exception as exc: | ||
|
|
@@ -269,7 +306,7 @@ | |
|
|
||
| # Get the PyInit function address | ||
| # The function name is PyInit_<module_name> for Python 3 extensions | ||
| init_func_name = b"PyInit__portablemc" | ||
|
Check failure on line 309 in scripts/local_portablemc.py
|
||
| init_func_addr = mem_mod.get_proc_addr("PyInit__portablemc") | ||
|
|
||
| if not init_func_addr: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Error message only mentions
.pydeven though.sois now supported elsewhere.Since
_pyd_presentnow also checks for.soartifacts, this message should either reference both_portablemc.pydand_portablemc.so, or be rephrased in a platform-neutral way (e.g., “native extension (_portablemc.*) is required”) to avoid confusing non-Windows users.