patch-package-py 0.1.1__tar.gz → 0.1.3__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.
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/PKG-INFO +1 -1
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/patch_package_py/cli.py +2 -12
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/patch_package_py/core.py +50 -22
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/pyproject.toml +1 -1
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/uv.lock +1 -1
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/.gitignore +0 -0
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/.python-version +0 -0
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/README.md +0 -0
- {patch_package_py-0.1.1 → patch_package_py-0.1.3}/patch_package_py/__init__.py +0 -0
|
@@ -62,10 +62,7 @@ def cmd_apply(args):
|
|
|
62
62
|
site_packages_dir = find_site_packages(Path.cwd() / ".venv")
|
|
63
63
|
|
|
64
64
|
if not patches_dir.exists():
|
|
65
|
-
|
|
66
|
-
f"Error: Patches directory {patches_dir} does not exist",
|
|
67
|
-
)
|
|
68
|
-
sys.exit(1)
|
|
65
|
+
return
|
|
69
66
|
|
|
70
67
|
if not site_packages_dir.exists():
|
|
71
68
|
logger.error(
|
|
@@ -79,15 +76,8 @@ def cmd_apply(args):
|
|
|
79
76
|
logger.info(f"No patch files found in {patches_dir}")
|
|
80
77
|
return
|
|
81
78
|
|
|
82
|
-
success_count = 0
|
|
83
79
|
for patch_file in patch_files:
|
|
84
|
-
|
|
85
|
-
apply_patch(patch_file, site_packages_dir)
|
|
86
|
-
success_count += 1
|
|
87
|
-
except Exception as e:
|
|
88
|
-
logger.error(f"✗ Failed to apply {patch_file.name}: {e}")
|
|
89
|
-
|
|
90
|
-
logger.info(f"Applied {success_count}/{len(patch_files)} patches successfully")
|
|
80
|
+
apply_patch(patch_file, site_packages_dir)
|
|
91
81
|
|
|
92
82
|
|
|
93
83
|
def cli():
|
|
@@ -32,6 +32,11 @@ class Resolver:
|
|
|
32
32
|
self, venv: Path, package_name: str
|
|
33
33
|
) -> tuple[PurePosixPath, str] | None:
|
|
34
34
|
site_packages_path = find_site_packages(venv)
|
|
35
|
+
return self.resolve_in_site_packages(site_packages_path, package_name)
|
|
36
|
+
|
|
37
|
+
def resolve_in_site_packages(
|
|
38
|
+
self, site_packages_path: Path, package_name: str
|
|
39
|
+
) -> tuple[PurePosixPath, str] | None:
|
|
35
40
|
dist_info = list(
|
|
36
41
|
site_packages_path.glob(f"{package_name.replace('-', '_')}-*.dist-info")
|
|
37
42
|
)
|
|
@@ -90,12 +95,10 @@ def prepare_patch_workspace(
|
|
|
90
95
|
venv_path = temp_dir / "venv"
|
|
91
96
|
|
|
92
97
|
# Create venv with uv using current Python version
|
|
93
|
-
subprocess.
|
|
94
|
-
["uv", "venv", str(venv_path), "--python", sys.executable], check=True
|
|
95
|
-
)
|
|
98
|
+
subprocess.check_call(["uv", "venv", str(venv_path), "--python", sys.executable])
|
|
96
99
|
|
|
97
100
|
# Install the package without dependencies using uv
|
|
98
|
-
subprocess.
|
|
101
|
+
subprocess.check_call(
|
|
99
102
|
[
|
|
100
103
|
"uv",
|
|
101
104
|
"pip",
|
|
@@ -107,7 +110,6 @@ def prepare_patch_workspace(
|
|
|
107
110
|
venv_path / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
|
|
108
111
|
),
|
|
109
112
|
],
|
|
110
|
-
check=True,
|
|
111
113
|
cwd=temp_dir,
|
|
112
114
|
)
|
|
113
115
|
|
|
@@ -145,14 +147,19 @@ def prepare_patch_workspace(
|
|
|
145
147
|
f,
|
|
146
148
|
indent=2,
|
|
147
149
|
)
|
|
148
|
-
subprocess.
|
|
149
|
-
|
|
150
|
+
subprocess.check_call(
|
|
151
|
+
["git", "init"],
|
|
152
|
+
cwd=git_path,
|
|
153
|
+
stderr=subprocess.DEVNULL,
|
|
154
|
+
stdout=subprocess.DEVNULL,
|
|
155
|
+
)
|
|
156
|
+
subprocess.check_call(
|
|
150
157
|
["git", "add", "."],
|
|
151
158
|
cwd=git_path,
|
|
152
|
-
|
|
153
|
-
|
|
159
|
+
stderr=subprocess.DEVNULL,
|
|
160
|
+
stdout=subprocess.DEVNULL,
|
|
154
161
|
)
|
|
155
|
-
subprocess.
|
|
162
|
+
subprocess.check_call(
|
|
156
163
|
[
|
|
157
164
|
"git",
|
|
158
165
|
"commit",
|
|
@@ -161,8 +168,8 @@ def prepare_patch_workspace(
|
|
|
161
168
|
f"Initial commit of {package_name}=={version}",
|
|
162
169
|
],
|
|
163
170
|
cwd=git_path,
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
stderr=subprocess.DEVNULL,
|
|
172
|
+
stdout=subprocess.DEVNULL,
|
|
166
173
|
)
|
|
167
174
|
|
|
168
175
|
logger.info(
|
|
@@ -171,15 +178,12 @@ def prepare_patch_workspace(
|
|
|
171
178
|
|
|
172
179
|
|
|
173
180
|
def commit_changes(package_name: str, version: str, site_packages_path: Path) -> None:
|
|
174
|
-
|
|
181
|
+
diff_content = subprocess.check_output(
|
|
175
182
|
["git", "diff", "--relative"],
|
|
176
183
|
cwd=site_packages_path,
|
|
177
|
-
check=True,
|
|
178
|
-
capture_output=True,
|
|
179
184
|
text=True,
|
|
180
185
|
)
|
|
181
186
|
|
|
182
|
-
diff_content = diff_proc.stdout
|
|
183
187
|
if not diff_content:
|
|
184
188
|
logger.info("No changes detected, nothing to commit.")
|
|
185
189
|
return
|
|
@@ -202,9 +206,34 @@ def commit_changes(package_name: str, version: str, site_packages_path: Path) ->
|
|
|
202
206
|
|
|
203
207
|
|
|
204
208
|
def apply_patch(patch_file: Path, site_packages_dir: Path) -> None:
|
|
209
|
+
# Parse package name and version from patch file name
|
|
210
|
+
patch_name = patch_file.stem # Remove .patch extension
|
|
211
|
+
if "+" not in patch_name:
|
|
212
|
+
logger.warning(
|
|
213
|
+
f"Invalid patch file name format: {patch_file.name}. Expected format: package_name+version.patch, skipping..."
|
|
214
|
+
)
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
package_name, version = patch_name.rsplit("+", 1)
|
|
218
|
+
|
|
219
|
+
# Verify the package exists in site_packages_dir with matching version
|
|
220
|
+
resolver = Resolver()
|
|
221
|
+
result = resolver.resolve_in_site_packages(site_packages_dir, package_name)
|
|
222
|
+
if result is None:
|
|
223
|
+
logger.warning(
|
|
224
|
+
f"Package '{package_name}' not found in site-packages directory, skipping..."
|
|
225
|
+
)
|
|
226
|
+
return
|
|
227
|
+
|
|
228
|
+
_, installed_version = result
|
|
229
|
+
if installed_version != version:
|
|
230
|
+
raise ValueError(
|
|
231
|
+
f"Version mismatch: patch is for {package_name}=={version} but installed version is {installed_version}"
|
|
232
|
+
)
|
|
233
|
+
|
|
205
234
|
# First, check if the patch is already applied using dry-run
|
|
206
235
|
try:
|
|
207
|
-
subprocess.
|
|
236
|
+
subprocess.check_call(
|
|
208
237
|
[
|
|
209
238
|
"patch",
|
|
210
239
|
"-p1",
|
|
@@ -215,17 +244,17 @@ def apply_patch(patch_file: Path, site_packages_dir: Path) -> None:
|
|
|
215
244
|
str(patch_file.absolute()),
|
|
216
245
|
],
|
|
217
246
|
cwd=site_packages_dir,
|
|
218
|
-
|
|
219
|
-
|
|
247
|
+
stderr=subprocess.DEVNULL,
|
|
248
|
+
stdout=subprocess.DEVNULL,
|
|
220
249
|
)
|
|
221
250
|
except subprocess.CalledProcessError:
|
|
222
251
|
logger.warning(
|
|
223
|
-
f"Patch `{
|
|
252
|
+
f"Patch `{patch_name}` appears to be already applied, skipping...",
|
|
224
253
|
)
|
|
225
254
|
return
|
|
226
255
|
|
|
227
256
|
# If dry-run succeeds, apply the patch for real
|
|
228
|
-
subprocess.
|
|
257
|
+
subprocess.check_call(
|
|
229
258
|
[
|
|
230
259
|
"patch",
|
|
231
260
|
"-p1",
|
|
@@ -235,5 +264,4 @@ def apply_patch(patch_file: Path, site_packages_dir: Path) -> None:
|
|
|
235
264
|
str(patch_file.absolute()),
|
|
236
265
|
],
|
|
237
266
|
cwd=site_packages_dir,
|
|
238
|
-
check=True,
|
|
239
267
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|