patch-package-py 0.1.0__tar.gz → 0.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.
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/PKG-INFO +1 -1
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/patch_package_py/cli.py +2 -12
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/patch_package_py/core.py +51 -23
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/pyproject.toml +1 -1
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/uv.lock +1 -1
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/.gitignore +0 -0
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/.python-version +0 -0
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/README.md +0 -0
- {patch_package_py-0.1.0 → patch_package_py-0.1.2}/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
|
|
@@ -190,8 +194,9 @@ def commit_changes(package_name: str, version: str, site_packages_path: Path) ->
|
|
|
190
194
|
with open(patch_file_path, "w") as f:
|
|
191
195
|
f.write(diff_content)
|
|
192
196
|
|
|
197
|
+
current_site_packages = find_site_packages(Path.cwd() / ".venv")
|
|
193
198
|
try:
|
|
194
|
-
apply_patch(patch_file_path,
|
|
199
|
+
apply_patch(patch_file_path, current_site_packages)
|
|
195
200
|
except subprocess.CalledProcessError:
|
|
196
201
|
logger.error(
|
|
197
202
|
f"Error: failed to apply the patch after creation. There's maybe a conflict, you can try to reinstall the package and apply the patch manually via `{CLI_NAME} apply {patch_file_name}`"
|
|
@@ -201,9 +206,33 @@ def commit_changes(package_name: str, version: str, site_packages_path: Path) ->
|
|
|
201
206
|
|
|
202
207
|
|
|
203
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
|
+
raise ValueError(
|
|
213
|
+
f"Invalid patch file name format: {patch_file.name}. Expected format: package_name+version.patch"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
package_name, version = patch_name.rsplit("+", 1)
|
|
217
|
+
|
|
218
|
+
# Verify the package exists in site_packages_dir with matching version
|
|
219
|
+
resolver = Resolver()
|
|
220
|
+
result = resolver.resolve_in_site_packages(site_packages_dir, package_name)
|
|
221
|
+
if result is None:
|
|
222
|
+
logger.warning(
|
|
223
|
+
f"Package '{package_name}' not found in site-packages directory, skipping..."
|
|
224
|
+
)
|
|
225
|
+
return
|
|
226
|
+
|
|
227
|
+
_, installed_version = result
|
|
228
|
+
if installed_version != version:
|
|
229
|
+
raise ValueError(
|
|
230
|
+
f"Version mismatch: patch is for {package_name}=={version} but installed version is {installed_version}"
|
|
231
|
+
)
|
|
232
|
+
|
|
204
233
|
# First, check if the patch is already applied using dry-run
|
|
205
234
|
try:
|
|
206
|
-
subprocess.
|
|
235
|
+
subprocess.check_call(
|
|
207
236
|
[
|
|
208
237
|
"patch",
|
|
209
238
|
"-p1",
|
|
@@ -214,17 +243,17 @@ def apply_patch(patch_file: Path, site_packages_dir: Path) -> None:
|
|
|
214
243
|
str(patch_file.absolute()),
|
|
215
244
|
],
|
|
216
245
|
cwd=site_packages_dir,
|
|
217
|
-
|
|
218
|
-
|
|
246
|
+
stderr=subprocess.DEVNULL,
|
|
247
|
+
stdout=subprocess.DEVNULL,
|
|
219
248
|
)
|
|
220
249
|
except subprocess.CalledProcessError:
|
|
221
250
|
logger.warning(
|
|
222
|
-
f"Patch `{
|
|
251
|
+
f"Patch `{patch_name}` appears to be already applied, skipping...",
|
|
223
252
|
)
|
|
224
253
|
return
|
|
225
254
|
|
|
226
255
|
# If dry-run succeeds, apply the patch for real
|
|
227
|
-
subprocess.
|
|
256
|
+
subprocess.check_call(
|
|
228
257
|
[
|
|
229
258
|
"patch",
|
|
230
259
|
"-p1",
|
|
@@ -234,5 +263,4 @@ def apply_patch(patch_file: Path, site_packages_dir: Path) -> None:
|
|
|
234
263
|
str(patch_file.absolute()),
|
|
235
264
|
],
|
|
236
265
|
cwd=site_packages_dir,
|
|
237
|
-
check=True,
|
|
238
266
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|