p4cmd 2.11.0__tar.gz → 2.11.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.
- {p4cmd-2.11.0 → p4cmd-2.11.2}/PKG-INFO +1 -1
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/__init__.py +1 -1
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/p4cmd.py +15 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/p4file.py +0 -2
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd.egg-info/PKG-INFO +1 -1
- {p4cmd-2.11.0 → p4cmd-2.11.2}/tests/test_p4client.py +36 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/tests/test_p4file.py +20 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/LICENSE +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/README.md +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/p4errors.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/__init__.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_DEPOT_ONLY.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_MOVED.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_NEED_SYNC.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_OPEN_FOR_ADD.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_OPEN_FOR_DELETE.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_OPEN_FOR_EDIT.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_UNKNOWN.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_UNTRACKED.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/resources/perforce_UP_TO_DATE.png +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd/utils.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd.egg-info/SOURCES.txt +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd.egg-info/dependency_links.txt +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd.egg-info/requires.txt +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/p4cmd.egg-info/top_level.txt +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/setup.cfg +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/setup.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/tests/__init__.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/tests/conftest.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/tests/test_integration.py +0 -0
- {p4cmd-2.11.0 → p4cmd-2.11.2}/tests/test_utils.py +0 -0
|
@@ -635,10 +635,25 @@ class P4Client(object):
|
|
|
635
635
|
info_dicts = self.run_cmd("sync", args=initial_arg_list, file_list=file_list)
|
|
636
636
|
|
|
637
637
|
if verify:
|
|
638
|
+
# Files p4 itself deleted on this sync are EXPECTED to be absent from
|
|
639
|
+
# disk — don't warn for them. Normalize paths so platform-specific
|
|
640
|
+
# quirks (slash direction, case on Windows) don't cause false misses.
|
|
641
|
+
def _norm(p):
|
|
642
|
+
return os.path.normcase(os.path.normpath(p))
|
|
643
|
+
|
|
644
|
+
deleted_locals = {
|
|
645
|
+
_norm(self.__get_dict_value(d, "clientFile"))
|
|
646
|
+
for d in info_dicts
|
|
647
|
+
if self.__get_dict_value(d, "action") == "deleted"
|
|
648
|
+
and self.__get_dict_value(d, "clientFile") is not None
|
|
649
|
+
}
|
|
650
|
+
|
|
638
651
|
local_file_paths = self.get_local_paths(file_list)
|
|
639
652
|
for local_file_path in local_file_paths:
|
|
640
653
|
if local_file_path is None:
|
|
641
654
|
continue
|
|
655
|
+
if _norm(local_file_path) in deleted_locals:
|
|
656
|
+
continue
|
|
642
657
|
if not os.path.isfile(local_file_path):
|
|
643
658
|
_log.warning(f"File didn't exist after syncing, try force syncing it instead: {local_file_path}")
|
|
644
659
|
|
|
@@ -81,8 +81,6 @@ class P4File:
|
|
|
81
81
|
return not (self._raw_data and "is not under client's root" in self._raw_data)
|
|
82
82
|
|
|
83
83
|
def needs_syncing(self):
|
|
84
|
-
if self.is_deleted() or self.is_moved_deleted():
|
|
85
|
-
return False
|
|
86
84
|
if self.is_open_for_add() or self.is_open_for_edit():
|
|
87
85
|
return False
|
|
88
86
|
if self._head_revision is None:
|
|
@@ -791,3 +791,39 @@ def test_silent_kwarg_default_no_warning(tmp_path):
|
|
|
791
791
|
P4Client(str(tmp_path), user="u", client="c", server="s")
|
|
792
792
|
assert not any(issubclass(w.category, DeprecationWarning) and "silent" in str(w.message)
|
|
793
793
|
for w in caught), f"unexpected silent warning: {[str(w.message) for w in caught]}"
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
# ---------------------------------------------------------------------------
|
|
797
|
+
# sync_files verify — must not warn on files p4 itself deleted
|
|
798
|
+
# ---------------------------------------------------------------------------
|
|
799
|
+
|
|
800
|
+
def test_sync_files_no_warning_when_p4_deleted_file(p4client, caplog):
|
|
801
|
+
"""If p4 sync reports action=deleted for a file, the post-sync verify
|
|
802
|
+
must not warn that the file is missing — its absence is expected."""
|
|
803
|
+
deleted_path = "C:/workspace/path/to/file.txt"
|
|
804
|
+
sync_result = [
|
|
805
|
+
{b"action": b"deleted", b"clientFile": deleted_path.encode(), b"code": b"stat"}
|
|
806
|
+
]
|
|
807
|
+
with patch.object(p4client, "run_cmd", return_value=sync_result):
|
|
808
|
+
with patch.object(p4client, "get_local_paths", return_value=[deleted_path]):
|
|
809
|
+
with patch("p4cmd.p4cmd.os.path.isfile", return_value=False):
|
|
810
|
+
with caplog.at_level("WARNING", logger="p4cmd.p4cmd"):
|
|
811
|
+
p4client.sync_files([deleted_path])
|
|
812
|
+
assert "didn't exist after syncing" not in caplog.text, (
|
|
813
|
+
f"unexpected verify warning: {caplog.text}"
|
|
814
|
+
)
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
def test_sync_files_warns_when_file_missing_unexpectedly(p4client, caplog):
|
|
818
|
+
"""Regression guard: when p4 did NOT delete the file but it's still missing
|
|
819
|
+
on disk, the existing 'try force syncing' warning must still fire."""
|
|
820
|
+
path = "C:/workspace/path/to/file.txt"
|
|
821
|
+
sync_result = [
|
|
822
|
+
{b"action": b"updated", b"clientFile": path.encode(), b"code": b"stat"}
|
|
823
|
+
]
|
|
824
|
+
with patch.object(p4client, "run_cmd", return_value=sync_result):
|
|
825
|
+
with patch.object(p4client, "get_local_paths", return_value=[path]):
|
|
826
|
+
with patch("p4cmd.p4cmd.os.path.isfile", return_value=False):
|
|
827
|
+
with caplog.at_level("WARNING", logger="p4cmd.p4cmd"):
|
|
828
|
+
p4client.sync_files([path])
|
|
829
|
+
assert "didn't exist after syncing" in caplog.text
|
|
@@ -283,6 +283,26 @@ def test_needs_syncing_up_to_date_returns_false():
|
|
|
283
283
|
assert f.needs_syncing() is False
|
|
284
284
|
|
|
285
285
|
|
|
286
|
+
def test_needs_syncing_deleted_at_head_with_old_have_returns_true():
|
|
287
|
+
# File deleted at head but user still has an older revision on disk —
|
|
288
|
+
# syncing will remove it. Previously the is_deleted() early-return
|
|
289
|
+
# masked this case, leaving orphaned files in the workspace.
|
|
290
|
+
f = P4File()
|
|
291
|
+
f.have_revision = "5"
|
|
292
|
+
f.head_revision = "6"
|
|
293
|
+
f.head_action = "delete"
|
|
294
|
+
assert f.needs_syncing() is True
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def test_needs_syncing_moved_deleted_with_old_have_returns_true():
|
|
298
|
+
# Same case for move/delete at head.
|
|
299
|
+
f = P4File()
|
|
300
|
+
f.have_revision = "5"
|
|
301
|
+
f.head_revision = "6"
|
|
302
|
+
f.head_action = "move/delete"
|
|
303
|
+
assert f.needs_syncing() is True
|
|
304
|
+
|
|
305
|
+
|
|
286
306
|
# ---------------------------------------------------------------------------
|
|
287
307
|
# get_status
|
|
288
308
|
# ---------------------------------------------------------------------------
|
|
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
|
|
File without changes
|
|
File without changes
|