claude-dev-env 8.75.4 → 8.75.5
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.
package/package.json
CHANGED
|
@@ -216,10 +216,20 @@ def _is_inside(candidate_text: str, directory: Path) -> bool:
|
|
|
216
216
|
return _comparable_path(candidate_text).startswith(comparable_directory + os.sep)
|
|
217
217
|
|
|
218
218
|
|
|
219
|
+
def _link_target_is_present(link_path: Path) -> bool:
|
|
220
|
+
try:
|
|
221
|
+
link_path.stat()
|
|
222
|
+
except PermissionError:
|
|
223
|
+
return True
|
|
224
|
+
except OSError:
|
|
225
|
+
return False
|
|
226
|
+
return True
|
|
227
|
+
|
|
228
|
+
|
|
219
229
|
def _unlink_orphaned_links(main_home: Path, profile_home: Path) -> tuple[str, ...]:
|
|
220
230
|
all_unlinked: list[str] = []
|
|
221
231
|
for each_entry in sorted(profile_home.iterdir()):
|
|
222
|
-
if not _is_link(each_entry) or each_entry
|
|
232
|
+
if not _is_link(each_entry) or _link_target_is_present(each_entry):
|
|
223
233
|
continue
|
|
224
234
|
if not _is_inside(_link_target_text(each_entry), main_home):
|
|
225
235
|
continue
|
|
@@ -184,6 +184,29 @@ class TestSyncProfile:
|
|
|
184
184
|
assert not os.path.lexists(profile_home / "rules")
|
|
185
185
|
assert report.all_unlinked == ("rules",)
|
|
186
186
|
|
|
187
|
+
def test_should_keep_a_link_whose_target_refuses_access(
|
|
188
|
+
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
189
|
+
) -> None:
|
|
190
|
+
main_home = build_main_home(tmp_path)
|
|
191
|
+
(main_home / ".pytest_cache").mkdir()
|
|
192
|
+
profile_home = tmp_path / "ev"
|
|
193
|
+
profile_home.mkdir()
|
|
194
|
+
locked_link = profile_home / ".pytest_cache"
|
|
195
|
+
locked_link.symlink_to(main_home / ".pytest_cache", target_is_directory=True)
|
|
196
|
+
unlocked_stat = Path.stat
|
|
197
|
+
|
|
198
|
+
def stat_refusing_the_locked_link(
|
|
199
|
+
self: Path, *, follow_symlinks: bool = True
|
|
200
|
+
) -> os.stat_result:
|
|
201
|
+
if self == locked_link and follow_symlinks:
|
|
202
|
+
raise PermissionError(5, "Access is denied", str(self))
|
|
203
|
+
return unlocked_stat(self, follow_symlinks=follow_symlinks)
|
|
204
|
+
|
|
205
|
+
monkeypatch.setattr(Path, "stat", stat_refusing_the_locked_link)
|
|
206
|
+
report = sync(main_home, profile_home)
|
|
207
|
+
assert profile.links_to(locked_link, main_home / ".pytest_cache")
|
|
208
|
+
assert ".pytest_cache" not in report.all_unlinked
|
|
209
|
+
|
|
187
210
|
|
|
188
211
|
def test_should_remove_a_main_link_left_under_an_account_local_name(
|
|
189
212
|
self, tmp_path: Path
|