python-package-folder 5.1.0__tar.gz → 5.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/PKG-INFO +1 -1
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/coverage.svg +2 -2
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/pyproject.toml +1 -3
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/subfolder_build.py +152 -13
- python_package_folder-5.1.0/src/python_package_folder/_hatch_build.py +0 -173
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.copier-answers.yml +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.cursor/plans/optional_version_+_semantic-release_efed88a6.plan.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.cursor/plans/replace_node.js_semantic-release_with_custom_python_implementation_64e05e1a.plan.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.cursor/rules/general.mdc +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.cursor/rules/python.mdc +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.github/workflows/ci.yml +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.github/workflows/publish.yml +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.gitignore +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/.vscode/settings.json +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/LICENSE +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/MANIFEST.in +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/Makefile +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/README.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/development.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/docs/DEVELOPMENT.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/docs/INSTALLATION.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/docs/PUBLISHING.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/docs/REFERENCE.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/docs/USAGE.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/docs/VERSION_RESOLUTION.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/installation.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/publishing.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/__init__.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/__main__.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/analyzer.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/finder.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/manager.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/publisher.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/py.typed +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/python_package_folder.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/types.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/utils.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/version.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/version_calculator.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/conftest.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/some_globals.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/subfolder_to_build/README.md +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/subfolder_to_build/__init__.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/subfolder_to_build/some_function.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/subfolder_to_build/some_globals.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/utility_folder/_SS/some_superseded_file.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/utility_folder/some_utility.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_build_with_external_deps.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_exclude_patterns.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_linting.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_preserve_directory_structure.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_publisher.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_shared_subdirectory_imports.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_spreadsheet_creation_imports.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_subfolder_build.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_third_party_dependencies.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_utils.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_version_calculator.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_version_manager.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/tests.py +0 -0
- {python_package_folder-5.1.0 → python_package_folder-5.1.2}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-package-folder
|
|
3
|
-
Version: 5.1.
|
|
3
|
+
Version: 5.1.2
|
|
4
4
|
Summary: Python package to automatically package and build a folder, fetching all relevant dependencies.
|
|
5
5
|
Project-URL: Repository, https://github.com/alelom/python-package-folder
|
|
6
6
|
Author-email: Alessio Lombardi <work@alelom.com>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
|
|
15
15
|
<text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
|
|
16
16
|
<text x="31.5" y="14">coverage</text>
|
|
17
|
-
<text x="81" y="15" fill="#010101" fill-opacity=".3">
|
|
18
|
-
<text x="81" y="14">
|
|
17
|
+
<text x="81" y="15" fill="#010101" fill-opacity=".3">63%</text>
|
|
18
|
+
<text x="81" y="14">63%</text>
|
|
19
19
|
</g>
|
|
20
20
|
</svg>
|
|
@@ -43,7 +43,7 @@ dependencies = [
|
|
|
43
43
|
|
|
44
44
|
# ---- Dev dependencies ----
|
|
45
45
|
|
|
46
|
-
version = "5.1.
|
|
46
|
+
version = "5.1.2"
|
|
47
47
|
[dependency-groups]
|
|
48
48
|
dev = [
|
|
49
49
|
"pytest>=8.3.5",
|
|
@@ -154,7 +154,5 @@ testpaths = [
|
|
|
154
154
|
"src",
|
|
155
155
|
"tests",
|
|
156
156
|
]
|
|
157
|
-
# Ignore build hooks - they're not test files and require hatchling which isn't in test deps
|
|
158
|
-
ignore = ["_hatch_build.py"]
|
|
159
157
|
norecursedirs = []
|
|
160
158
|
filterwarnings = []
|
|
@@ -10,6 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
import re
|
|
11
11
|
import shutil
|
|
12
12
|
import sys
|
|
13
|
+
import tempfile
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from typing import TYPE_CHECKING
|
|
15
16
|
|
|
@@ -75,6 +76,8 @@ class SubfolderBuildConfig:
|
|
|
75
76
|
self.temp_readme: Path | None = None
|
|
76
77
|
self.original_readme_backup: Path | None = None
|
|
77
78
|
self._used_subfolder_pyproject = False
|
|
79
|
+
self._excluded_files: list[tuple[Path, Path]] = [] # List of (original_path, temp_path) tuples
|
|
80
|
+
self._exclude_temp_dir: Path | None = None
|
|
78
81
|
|
|
79
82
|
def _derive_package_name(self) -> str:
|
|
80
83
|
"""Derive package name from source directory name."""
|
|
@@ -323,6 +326,10 @@ class SubfolderBuildConfig:
|
|
|
323
326
|
# Handle README file
|
|
324
327
|
self._handle_readme()
|
|
325
328
|
|
|
329
|
+
# Exclude files matching exclude patterns
|
|
330
|
+
if exclude_patterns:
|
|
331
|
+
self._exclude_files_by_patterns(exclude_patterns)
|
|
332
|
+
|
|
326
333
|
return original_pyproject
|
|
327
334
|
|
|
328
335
|
# No pyproject.toml in subfolder, create one from parent
|
|
@@ -430,6 +437,10 @@ class SubfolderBuildConfig:
|
|
|
430
437
|
# Handle README file
|
|
431
438
|
self._handle_readme()
|
|
432
439
|
|
|
440
|
+
# Exclude files matching exclude patterns
|
|
441
|
+
if exclude_patterns:
|
|
442
|
+
self._exclude_files_by_patterns(exclude_patterns)
|
|
443
|
+
|
|
433
444
|
return original_pyproject
|
|
434
445
|
|
|
435
446
|
def _modify_pyproject_string(
|
|
@@ -590,18 +601,39 @@ class SubfolderBuildConfig:
|
|
|
590
601
|
# Use only-include for source distributions to ensure only the subfolder is included
|
|
591
602
|
# This prevents including files from the project root
|
|
592
603
|
if package_dirs:
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
604
|
+
# Check if sdist section already exists
|
|
605
|
+
sdist_section_exists = any(
|
|
606
|
+
line.strip().startswith("[tool.hatch.build.targets.sdist]")
|
|
607
|
+
for line in result
|
|
608
|
+
)
|
|
609
|
+
# Check if only-include is already set in the sdist section
|
|
610
|
+
only_include_set = False
|
|
611
|
+
if sdist_section_exists:
|
|
612
|
+
in_sdist_section = False
|
|
613
|
+
for line in result:
|
|
614
|
+
if line.strip().startswith("[tool.hatch.build.targets.sdist]"):
|
|
615
|
+
in_sdist_section = True
|
|
616
|
+
elif line.strip().startswith("[") and in_sdist_section:
|
|
617
|
+
in_sdist_section = False
|
|
618
|
+
elif in_sdist_section and re.match(r"^\s*only-include\s*=", line):
|
|
619
|
+
only_include_set = True
|
|
620
|
+
break
|
|
621
|
+
|
|
622
|
+
if not sdist_section_exists or not only_include_set:
|
|
623
|
+
if not sdist_section_exists:
|
|
624
|
+
result.append("")
|
|
625
|
+
result.append("[tool.hatch.build.targets.sdist]")
|
|
626
|
+
# Include only the subfolder directory and necessary files
|
|
627
|
+
only_include_paths = [package_dirs[0]]
|
|
628
|
+
# Also include pyproject.toml and README if they exist
|
|
629
|
+
only_include_paths.append("pyproject.toml")
|
|
630
|
+
only_include_paths.append("README.md")
|
|
631
|
+
only_include_paths.append("README.rst")
|
|
632
|
+
only_include_paths.append("README.txt")
|
|
633
|
+
only_include_paths.append("README")
|
|
634
|
+
only_include_str = ", ".join(f'"{p}"' for p in only_include_paths)
|
|
635
|
+
if not only_include_set:
|
|
636
|
+
result.append(f"only-include = [{only_include_str}]")
|
|
605
637
|
|
|
606
638
|
# Add dependency group if specified
|
|
607
639
|
if dependency_group:
|
|
@@ -933,6 +965,110 @@ class SubfolderBuildConfig:
|
|
|
933
965
|
target_readme.write_text(readme_content, encoding="utf-8")
|
|
934
966
|
self.temp_readme = target_readme
|
|
935
967
|
|
|
968
|
+
def _exclude_files_by_patterns(self, exclude_patterns: list[str]) -> None:
|
|
969
|
+
"""
|
|
970
|
+
Temporarily move files matching exclude patterns out of the source directory.
|
|
971
|
+
|
|
972
|
+
Files are moved to a temporary directory and will be restored in restore().
|
|
973
|
+
This ensures excluded files are not included in the build.
|
|
974
|
+
|
|
975
|
+
Args:
|
|
976
|
+
exclude_patterns: List of regex patterns to match against path components
|
|
977
|
+
"""
|
|
978
|
+
if not exclude_patterns:
|
|
979
|
+
return
|
|
980
|
+
|
|
981
|
+
# Compile regex patterns for efficiency
|
|
982
|
+
compiled_patterns = [re.compile(pattern) for pattern in exclude_patterns]
|
|
983
|
+
|
|
984
|
+
def should_exclude(path: Path) -> bool:
|
|
985
|
+
"""Check if a path should be excluded based on patterns."""
|
|
986
|
+
# Check each component of the path
|
|
987
|
+
for part in path.parts:
|
|
988
|
+
# Check if any part matches any pattern
|
|
989
|
+
for pattern in compiled_patterns:
|
|
990
|
+
if pattern.search(part):
|
|
991
|
+
return True
|
|
992
|
+
return False
|
|
993
|
+
|
|
994
|
+
# Create temporary directory for excluded files
|
|
995
|
+
if self._exclude_temp_dir is None:
|
|
996
|
+
self._exclude_temp_dir = Path(tempfile.mkdtemp(prefix="python-package-folder-excluded-"))
|
|
997
|
+
|
|
998
|
+
# Find all files and directories in src_dir that match exclude patterns
|
|
999
|
+
excluded_items: list[Path] = []
|
|
1000
|
+
|
|
1001
|
+
# Walk through src_dir and find matching items
|
|
1002
|
+
# Sort by depth (shallow first) so we can skip children of excluded directories
|
|
1003
|
+
all_items = sorted(self.src_dir.rglob("*"), key=lambda p: len(p.parts))
|
|
1004
|
+
|
|
1005
|
+
for item in all_items:
|
|
1006
|
+
# Skip if already excluded (parent was excluded)
|
|
1007
|
+
if any(
|
|
1008
|
+
excluded.is_dir() and (item == excluded or item.is_relative_to(excluded))
|
|
1009
|
+
for excluded in excluded_items
|
|
1010
|
+
):
|
|
1011
|
+
continue
|
|
1012
|
+
|
|
1013
|
+
# Check if this item should be excluded
|
|
1014
|
+
try:
|
|
1015
|
+
rel_path = item.relative_to(self.src_dir)
|
|
1016
|
+
if should_exclude(rel_path):
|
|
1017
|
+
excluded_items.append(item)
|
|
1018
|
+
except ValueError:
|
|
1019
|
+
# Path is not relative to src_dir, skip
|
|
1020
|
+
continue
|
|
1021
|
+
|
|
1022
|
+
# Move excluded items to temporary directory
|
|
1023
|
+
for item in excluded_items:
|
|
1024
|
+
try:
|
|
1025
|
+
# Calculate relative path from src_dir
|
|
1026
|
+
rel_path = item.relative_to(self.src_dir)
|
|
1027
|
+
# Create corresponding path in temp directory
|
|
1028
|
+
temp_path = self._exclude_temp_dir / rel_path
|
|
1029
|
+
# Create parent directories if needed
|
|
1030
|
+
temp_path.parent.mkdir(parents=True, exist_ok=True)
|
|
1031
|
+
|
|
1032
|
+
# Move the item
|
|
1033
|
+
if item.exists():
|
|
1034
|
+
shutil.move(str(item), str(temp_path))
|
|
1035
|
+
self._excluded_files.append((item, temp_path))
|
|
1036
|
+
print(f"Excluded {rel_path} from build", file=sys.stderr)
|
|
1037
|
+
except Exception as e:
|
|
1038
|
+
print(
|
|
1039
|
+
f"Warning: Could not exclude {item}: {e}",
|
|
1040
|
+
file=sys.stderr,
|
|
1041
|
+
)
|
|
1042
|
+
|
|
1043
|
+
def _restore_excluded_files(self) -> None:
|
|
1044
|
+
"""Restore files that were excluded by _exclude_files_by_patterns."""
|
|
1045
|
+
# Restore files in reverse order (to handle nested directories correctly)
|
|
1046
|
+
for original_path, temp_path in reversed(self._excluded_files):
|
|
1047
|
+
try:
|
|
1048
|
+
if temp_path.exists():
|
|
1049
|
+
# Ensure parent directory exists
|
|
1050
|
+
original_path.parent.mkdir(parents=True, exist_ok=True)
|
|
1051
|
+
# Move back
|
|
1052
|
+
shutil.move(str(temp_path), str(original_path))
|
|
1053
|
+
except Exception as e:
|
|
1054
|
+
print(
|
|
1055
|
+
f"Warning: Could not restore excluded file {original_path}: {e}",
|
|
1056
|
+
file=sys.stderr,
|
|
1057
|
+
)
|
|
1058
|
+
|
|
1059
|
+
# Clean up temporary directory
|
|
1060
|
+
if self._exclude_temp_dir and self._exclude_temp_dir.exists():
|
|
1061
|
+
try:
|
|
1062
|
+
shutil.rmtree(self._exclude_temp_dir)
|
|
1063
|
+
except Exception as e:
|
|
1064
|
+
print(
|
|
1065
|
+
f"Warning: Could not remove temporary exclude directory {self._exclude_temp_dir}: {e}",
|
|
1066
|
+
file=sys.stderr,
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1069
|
+
self._excluded_files.clear()
|
|
1070
|
+
self._exclude_temp_dir = None
|
|
1071
|
+
|
|
936
1072
|
def restore(self) -> None:
|
|
937
1073
|
"""
|
|
938
1074
|
Restore the original pyproject.toml and remove temporary __init__.py if created.
|
|
@@ -942,6 +1078,9 @@ class SubfolderBuildConfig:
|
|
|
942
1078
|
This method removes the temporary pyproject.toml and restores the original from
|
|
943
1079
|
the backup location, ensuring the original file is never modified.
|
|
944
1080
|
"""
|
|
1081
|
+
# Restore excluded files first
|
|
1082
|
+
self._restore_excluded_files()
|
|
1083
|
+
|
|
945
1084
|
# Remove temporary __init__.py if we created it
|
|
946
1085
|
if self._temp_init_created:
|
|
947
1086
|
init_file = self.src_dir / "__init__.py"
|
|
@@ -1011,4 +1150,4 @@ class SubfolderBuildConfig:
|
|
|
1011
1150
|
|
|
1012
1151
|
def __exit__(self, exc_type, exc_val, exc_tb) -> None: # noqa: ARG002
|
|
1013
1152
|
"""Context manager exit - always restore."""
|
|
1014
|
-
self.restore()
|
|
1153
|
+
self.restore()
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Hatch build hook to automatically include all files from the scripts directory.
|
|
3
|
-
|
|
4
|
-
This hook ensures all non-Python files in the scripts directory are included
|
|
5
|
-
in the wheel without creating duplicates, and automatically includes any new
|
|
6
|
-
files added to the directory without requiring manual configuration updates.
|
|
7
|
-
|
|
8
|
-
Also filters files based on exclude patterns from pyproject.toml.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import re
|
|
12
|
-
import sys
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from typing import Any
|
|
15
|
-
|
|
16
|
-
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
17
|
-
|
|
18
|
-
from .utils import read_exclude_patterns
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class CustomBuildHook(BuildHookInterface):
|
|
22
|
-
"""Build hook to include all files from the scripts directory and filter exclude patterns."""
|
|
23
|
-
|
|
24
|
-
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
|
|
25
|
-
"""Initialize the build hook and add scripts directory files."""
|
|
26
|
-
# Debug: Print to stderr so it shows in build output
|
|
27
|
-
print(f"[DEBUG] Build hook called. Root: {self.root}", file=sys.stderr)
|
|
28
|
-
|
|
29
|
-
# Read exclude patterns from pyproject.toml
|
|
30
|
-
pyproject_path = Path(self.root) / "pyproject.toml"
|
|
31
|
-
exclude_patterns = read_exclude_patterns(pyproject_path)
|
|
32
|
-
|
|
33
|
-
if exclude_patterns:
|
|
34
|
-
print(f"[DEBUG] Found {len(exclude_patterns)} exclude pattern(s): {exclude_patterns}", file=sys.stderr)
|
|
35
|
-
# Filter build_data entries based on exclude patterns
|
|
36
|
-
self._filter_build_data(build_data, exclude_patterns)
|
|
37
|
-
|
|
38
|
-
# Try multiple possible locations for the scripts directory
|
|
39
|
-
# 1. Source layout: src/python_package_folder/scripts
|
|
40
|
-
# 2. Sdist layout: python_package_folder/scripts (after extraction)
|
|
41
|
-
# 3. Alternative sdist layout: scripts/ (if extracted differently)
|
|
42
|
-
possible_scripts_dirs = [
|
|
43
|
-
Path(self.root) / "src" / "python_package_folder" / "scripts",
|
|
44
|
-
Path(self.root) / "python_package_folder" / "scripts",
|
|
45
|
-
Path(self.root) / "scripts",
|
|
46
|
-
]
|
|
47
|
-
|
|
48
|
-
scripts_dir = None
|
|
49
|
-
for possible_dir in possible_scripts_dirs:
|
|
50
|
-
if possible_dir.exists() and possible_dir.is_dir():
|
|
51
|
-
scripts_dir = possible_dir
|
|
52
|
-
print(f"[DEBUG] Found scripts dir at: {scripts_dir}", file=sys.stderr)
|
|
53
|
-
break
|
|
54
|
-
|
|
55
|
-
if scripts_dir is None:
|
|
56
|
-
print(f"[DEBUG] Scripts directory not found. Tried: {[str(d) for d in possible_scripts_dirs]}", file=sys.stderr)
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
# If scripts directory exists, include all files from it
|
|
60
|
-
if scripts_dir.exists() and scripts_dir.is_dir():
|
|
61
|
-
# Add all files from scripts directory to force-include
|
|
62
|
-
# This ensures they're included in the wheel at the correct location
|
|
63
|
-
for script_file in scripts_dir.iterdir():
|
|
64
|
-
if script_file.is_file():
|
|
65
|
-
# Calculate relative paths from project root
|
|
66
|
-
try:
|
|
67
|
-
source_path = script_file.relative_to(self.root)
|
|
68
|
-
except ValueError:
|
|
69
|
-
# If relative_to fails, try to construct path manually
|
|
70
|
-
# This can happen with sdist layouts
|
|
71
|
-
if "python_package_folder" in str(script_file):
|
|
72
|
-
# Extract the part after python_package_folder
|
|
73
|
-
parts = script_file.parts
|
|
74
|
-
try:
|
|
75
|
-
idx = parts.index("python_package_folder")
|
|
76
|
-
source_path = Path(*parts[idx:])
|
|
77
|
-
except (ValueError, IndexError):
|
|
78
|
-
# Fallback: use the filename
|
|
79
|
-
source_path = Path("python_package_folder") / "scripts" / script_file.name
|
|
80
|
-
else:
|
|
81
|
-
source_path = Path("python_package_folder") / "scripts" / script_file.name
|
|
82
|
-
|
|
83
|
-
# Target path inside the wheel package (always the same)
|
|
84
|
-
target_path = f"python_package_folder/scripts/{script_file.name}"
|
|
85
|
-
|
|
86
|
-
print(f"[DEBUG] Adding {source_path} -> {target_path}", file=sys.stderr)
|
|
87
|
-
|
|
88
|
-
# Add to force-include (hatchling will handle this)
|
|
89
|
-
# We need to add it to build_data['force_include']
|
|
90
|
-
if "force_include" not in build_data:
|
|
91
|
-
build_data["force_include"] = {}
|
|
92
|
-
build_data["force_include"][str(source_path)] = target_path
|
|
93
|
-
|
|
94
|
-
print(f"[DEBUG] force_include now has {len(build_data.get('force_include', {}))} entries", file=sys.stderr)
|
|
95
|
-
|
|
96
|
-
def _filter_build_data(self, build_data: dict[str, Any], exclude_patterns: list[str]) -> None:
|
|
97
|
-
"""
|
|
98
|
-
Filter build_data entries based on exclude patterns.
|
|
99
|
-
|
|
100
|
-
Removes files/directories that match any of the exclude patterns from
|
|
101
|
-
build_data. Patterns are matched against any path component using regex.
|
|
102
|
-
|
|
103
|
-
Args:
|
|
104
|
-
build_data: Hatchling build data dictionary
|
|
105
|
-
exclude_patterns: List of regex patterns to match against paths
|
|
106
|
-
"""
|
|
107
|
-
# Compile regex patterns for efficiency
|
|
108
|
-
compiled_patterns = [re.compile(pattern) for pattern in exclude_patterns]
|
|
109
|
-
|
|
110
|
-
def should_exclude(path_str: str) -> bool:
|
|
111
|
-
"""Check if a path should be excluded based on patterns."""
|
|
112
|
-
# Check each component of the path
|
|
113
|
-
path = Path(path_str)
|
|
114
|
-
for part in path.parts:
|
|
115
|
-
# Check if any part matches any pattern
|
|
116
|
-
for pattern in compiled_patterns:
|
|
117
|
-
if pattern.search(part):
|
|
118
|
-
return True
|
|
119
|
-
return False
|
|
120
|
-
|
|
121
|
-
# Filter force_include entries
|
|
122
|
-
if "force_include" in build_data and isinstance(build_data["force_include"], dict):
|
|
123
|
-
original_count = len(build_data["force_include"])
|
|
124
|
-
filtered = {
|
|
125
|
-
source: target
|
|
126
|
-
for source, target in build_data["force_include"].items()
|
|
127
|
-
if not should_exclude(source) and not should_exclude(target)
|
|
128
|
-
}
|
|
129
|
-
build_data["force_include"] = filtered
|
|
130
|
-
excluded_count = original_count - len(filtered)
|
|
131
|
-
if excluded_count > 0:
|
|
132
|
-
print(
|
|
133
|
-
f"[DEBUG] Excluded {excluded_count} file(s) from force_include based on exclude patterns",
|
|
134
|
-
file=sys.stderr,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
# Filter other file collections that might exist
|
|
138
|
-
# Hatchling may store files in different keys depending on the build target
|
|
139
|
-
for key in ["shared_data", "artifacts"]:
|
|
140
|
-
if key in build_data and isinstance(build_data[key], dict):
|
|
141
|
-
original_count = len(build_data[key])
|
|
142
|
-
filtered = {
|
|
143
|
-
source: target
|
|
144
|
-
for source, target in build_data[key].items()
|
|
145
|
-
if not should_exclude(source) and not should_exclude(target)
|
|
146
|
-
}
|
|
147
|
-
build_data[key] = filtered
|
|
148
|
-
excluded_count = original_count - len(filtered)
|
|
149
|
-
if excluded_count > 0:
|
|
150
|
-
print(
|
|
151
|
-
f"[DEBUG] Excluded {excluded_count} file(s) from {key} based on exclude patterns",
|
|
152
|
-
file=sys.stderr,
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
# Filter files list if it exists (for sdist)
|
|
156
|
-
if "files" in build_data and isinstance(build_data["files"], list):
|
|
157
|
-
original_count = len(build_data["files"])
|
|
158
|
-
filtered = [
|
|
159
|
-
file_entry
|
|
160
|
-
for file_entry in build_data["files"]
|
|
161
|
-
if not should_exclude(str(file_entry))
|
|
162
|
-
]
|
|
163
|
-
build_data["files"] = filtered
|
|
164
|
-
excluded_count = original_count - len(filtered)
|
|
165
|
-
if excluded_count > 0:
|
|
166
|
-
print(
|
|
167
|
-
f"[DEBUG] Excluded {excluded_count} file(s) from files list based on exclude patterns",
|
|
168
|
-
file=sys.stderr,
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
# Export the hook class (hatchling might need this)
|
|
173
|
-
__all__ = ["CustomBuildHook"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/__init__.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/__main__.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/analyzer.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/finder.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/manager.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/publisher.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/types.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/utils.py
RENAMED
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/src/python_package_folder/version.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/folder_structure/some_globals.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_build_with_external_deps.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_third_party_dependencies.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_package_folder-5.1.0 → python_package_folder-5.1.2}/tests/test_version_calculator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|