p4cmd 2.8.0__tar.gz → 2.8.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.8.0 → p4cmd-2.8.2}/PKG-INFO +1 -1
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/__init__.py +1 -1
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/p4cmd.py +94 -68
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd.egg-info/PKG-INFO +1 -1
- {p4cmd-2.8.0 → p4cmd-2.8.2}/LICENSE +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/README.md +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/p4errors.py +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/p4file.py +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/__init__.py +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_DEPOT_ONLY.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_MOVED.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_NEED_SYNC.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_OPEN_FOR_ADD.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_OPEN_FOR_DELETE.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_OPEN_FOR_EDIT.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_UNKNOWN.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_UNTRACKED.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/resources/perforce_UP_TO_DATE.png +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd/utils.py +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd.egg-info/SOURCES.txt +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd.egg-info/dependency_links.txt +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/p4cmd.egg-info/top_level.txt +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/setup.cfg +0 -0
- {p4cmd-2.8.0 → p4cmd-2.8.2}/setup.py +0 -0
|
@@ -51,7 +51,7 @@ class P4Client(object):
|
|
|
51
51
|
self.server = self.get_p4_setting("P4PORT")
|
|
52
52
|
if self.server is None:
|
|
53
53
|
raise p4errors.WorkSpaceError("Could not find P4PORT")
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
self.depot_root = self.get_depot_paths([self.perforce_root])[0]
|
|
56
56
|
|
|
57
57
|
@classmethod
|
|
@@ -73,6 +73,9 @@ class P4Client(object):
|
|
|
73
73
|
"""
|
|
74
74
|
self.perforce_root = root
|
|
75
75
|
|
|
76
|
+
if not self.perforce_root:
|
|
77
|
+
raise p4errors.WorkSpaceError(f"self.perforce_root (value: {self.perforce_root}) is not set!")
|
|
78
|
+
|
|
76
79
|
def set_max_parallel_connections(self, value):
|
|
77
80
|
"""
|
|
78
81
|
Set the number of maximum parallel connections to use for sync/submit. Default class value is 4
|
|
@@ -94,12 +97,14 @@ class P4Client(object):
|
|
|
94
97
|
:return: *list* of dictionaries with either the marshaled returns of the command or dictionaries with the
|
|
95
98
|
raw output of the command
|
|
96
99
|
"""
|
|
100
|
+
|
|
101
|
+
if not self.perforce_root:
|
|
102
|
+
raise p4errors.WorkSpaceError(f"self.perforce_root (value: {self.perforce_root}) is not set!")
|
|
103
|
+
|
|
97
104
|
if online_check:
|
|
98
|
-
|
|
99
|
-
logging.warning("Can't connect to %s on port %s" % (self.__server_address(), self.__port_number()))
|
|
105
|
+
self.host_online()
|
|
100
106
|
|
|
101
|
-
|
|
102
|
-
os.chdir(self.perforce_root)
|
|
107
|
+
os.chdir(self.perforce_root)
|
|
103
108
|
|
|
104
109
|
file_list = [f'"{f}"' for f in file_list]
|
|
105
110
|
|
|
@@ -117,7 +122,8 @@ class P4Client(object):
|
|
|
117
122
|
|
|
118
123
|
if len(command) > MAX_CMD_LEN:
|
|
119
124
|
# This shouldn't happen, but just in case the command prefix end up really long
|
|
120
|
-
logging.warning(
|
|
125
|
+
logging.warning(
|
|
126
|
+
f"Command length: {format(len(command))} exceeds MAX_CMD_LEN {MAX_CMD_LEN} on command: {MAX_CMD_LEN}")
|
|
121
127
|
|
|
122
128
|
with subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) as pipe:
|
|
123
129
|
output = pipe.stdout
|
|
@@ -268,7 +274,8 @@ class P4Client(object):
|
|
|
268
274
|
if not complete_file_path in files:
|
|
269
275
|
all_files.append(complete_file_path)
|
|
270
276
|
else:
|
|
271
|
-
all_files = [os.path.join(folder, file) for file in os.listdir(folder) if
|
|
277
|
+
all_files = [os.path.join(folder, file) for file in os.listdir(folder) if
|
|
278
|
+
os.path.isfile(os.path.join(folder, file))]
|
|
272
279
|
|
|
273
280
|
return self.files_to_p4files(all_files)
|
|
274
281
|
|
|
@@ -281,12 +288,13 @@ class P4Client(object):
|
|
|
281
288
|
"""
|
|
282
289
|
if not self.host_online():
|
|
283
290
|
logging.warning("Can't connect to %s on port %s" % (self.__server_address(), self.__port_number()))
|
|
284
|
-
#raise p4errors.ServerOffline("Can't connect to %s on port %s" % (self.__server_address(), self.__port_number()))
|
|
291
|
+
# raise p4errors.ServerOffline("Can't connect to %s on port %s" % (self.__server_address(), self.__port_number()))
|
|
285
292
|
return
|
|
286
293
|
|
|
287
|
-
output = subprocess.check_output(
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
output = subprocess.check_output(
|
|
295
|
+
'p4 --field "Description=%s" --field "Files=" change -o | p4 change -i' % description,
|
|
296
|
+
stderr=subprocess.STDOUT,
|
|
297
|
+
shell=True).decode()
|
|
290
298
|
changelist_number = output.split(" ")[1]
|
|
291
299
|
return int(changelist_number)
|
|
292
300
|
|
|
@@ -302,7 +310,8 @@ class P4Client(object):
|
|
|
302
310
|
return True
|
|
303
311
|
else:
|
|
304
312
|
changelist = str(changelist)
|
|
305
|
-
changelists = self.get_pending_changelists(description_filter=changelist, perfect_match_only=True,
|
|
313
|
+
changelists = self.get_pending_changelists(description_filter=changelist, perfect_match_only=True,
|
|
314
|
+
case_sensitive=True)
|
|
306
315
|
if len(changelists):
|
|
307
316
|
return True
|
|
308
317
|
return False
|
|
@@ -315,24 +324,24 @@ class P4Client(object):
|
|
|
315
324
|
:param new_description: *string* new description for the changelist
|
|
316
325
|
:return: *bool* True if successful, False otherwise
|
|
317
326
|
"""
|
|
318
|
-
|
|
327
|
+
|
|
319
328
|
# ... not super elegant, but it works
|
|
320
329
|
try:
|
|
321
330
|
changelist = self.__ensure_changelist(changelist)
|
|
322
|
-
|
|
331
|
+
|
|
323
332
|
# do some formatting so that we have the proper indentation
|
|
324
333
|
formatted_description = []
|
|
325
334
|
for line in new_description.split('\n'):
|
|
326
335
|
formatted_description.append(f"\t{line}")
|
|
327
336
|
formatted_description = '\n'.join(formatted_description)
|
|
328
|
-
|
|
337
|
+
|
|
329
338
|
output = subprocess.check_output(f'p4 change -o {changelist}', shell=True).decode()
|
|
330
|
-
|
|
339
|
+
|
|
331
340
|
# Split the output into sections based on field names
|
|
332
341
|
sections = []
|
|
333
342
|
current_section = []
|
|
334
343
|
current_field = None
|
|
335
|
-
|
|
344
|
+
|
|
336
345
|
# take the output and start parsing it
|
|
337
346
|
for line in output.split('\n'):
|
|
338
347
|
# check if it's a new field
|
|
@@ -346,11 +355,11 @@ class P4Client(object):
|
|
|
346
355
|
else:
|
|
347
356
|
# if it's not a new field, add to the current section
|
|
348
357
|
current_section.append(line)
|
|
349
|
-
|
|
358
|
+
|
|
350
359
|
# add the last section
|
|
351
360
|
if current_field:
|
|
352
361
|
sections.append((current_field, current_section))
|
|
353
|
-
|
|
362
|
+
|
|
354
363
|
# new remake the Description field with the update description
|
|
355
364
|
new_output = []
|
|
356
365
|
for field, section_lines in sections:
|
|
@@ -361,18 +370,18 @@ class P4Client(object):
|
|
|
361
370
|
else:
|
|
362
371
|
# keep everything else as-is
|
|
363
372
|
new_output.extend(section_lines)
|
|
364
|
-
|
|
373
|
+
|
|
365
374
|
updated_output = '\n'.join(new_output)
|
|
366
|
-
|
|
375
|
+
|
|
367
376
|
# TODO: modify run_cmd to allow input so that commands like this can also run through it.
|
|
368
377
|
result = subprocess.check_output(f'p4 change -i', input=updated_output.encode(), shell=True).decode()
|
|
369
|
-
|
|
378
|
+
|
|
370
379
|
return True
|
|
371
380
|
except Exception as e:
|
|
372
381
|
if not self.silent:
|
|
373
382
|
logging.error(f"Failed to update changelist description: {e}")
|
|
374
383
|
return False
|
|
375
|
-
|
|
384
|
+
|
|
376
385
|
@validate_not_empty
|
|
377
386
|
def move_files_to_changelist(self, file_list, changelist="default"):
|
|
378
387
|
"""
|
|
@@ -410,7 +419,6 @@ class P4Client(object):
|
|
|
410
419
|
result = self.move_files_to_changelist(files_to_move, target_changelist)
|
|
411
420
|
return result
|
|
412
421
|
|
|
413
|
-
|
|
414
422
|
def rename_file(self, old_file_path, new_file_path, changelist="default"):
|
|
415
423
|
"""
|
|
416
424
|
P4 move-renames a file
|
|
@@ -438,7 +446,8 @@ class P4Client(object):
|
|
|
438
446
|
"""
|
|
439
447
|
changelist = self.__ensure_changelist(changelist)
|
|
440
448
|
|
|
441
|
-
info_dict =
|
|
449
|
+
info_dict = \
|
|
450
|
+
self.run_cmd("copy", args=["-c", str(changelist)], file_list=[original_file_path, copied_file_path])[0]
|
|
442
451
|
if self.__get_dict_value(info_dict, "code") != "error":
|
|
443
452
|
return True
|
|
444
453
|
return False
|
|
@@ -462,7 +471,6 @@ class P4Client(object):
|
|
|
462
471
|
|
|
463
472
|
return info_dicts
|
|
464
473
|
|
|
465
|
-
|
|
466
474
|
@validate_not_empty
|
|
467
475
|
def revert_folders(self, folder_list, unchanged_only=False):
|
|
468
476
|
"""
|
|
@@ -514,7 +522,8 @@ class P4Client(object):
|
|
|
514
522
|
if revert_unchanged_files:
|
|
515
523
|
self.revert_changelist(unchanged_only=True, changelist=changelist)
|
|
516
524
|
|
|
517
|
-
info_dicts = self.run_cmd("submit",
|
|
525
|
+
info_dicts = self.run_cmd("submit",
|
|
526
|
+
args=["-c", changelist, "--parallel", f"threads={self.max_parallel_connections}"])
|
|
518
527
|
return info_dicts
|
|
519
528
|
|
|
520
529
|
@validate_not_empty
|
|
@@ -536,7 +545,8 @@ class P4Client(object):
|
|
|
536
545
|
folder += "/..."
|
|
537
546
|
cleaned_folder_list.append(folder)
|
|
538
547
|
|
|
539
|
-
info_dicts = self.run_cmd("sync", args=["--parallel", f"threads={self.max_parallel_connections}"],
|
|
548
|
+
info_dicts = self.run_cmd("sync", args=["--parallel", f"threads={self.max_parallel_connections}"],
|
|
549
|
+
file_list=cleaned_folder_list)
|
|
540
550
|
return info_dicts
|
|
541
551
|
|
|
542
552
|
@validate_not_empty
|
|
@@ -556,7 +566,8 @@ class P4Client(object):
|
|
|
556
566
|
verify = False
|
|
557
567
|
file_list = [f"{path}#{revision}" for path in file_list]
|
|
558
568
|
|
|
559
|
-
initial_arg_list = ["-f", "--parallel", f"threads={self.max_parallel_connections}"] if force else ["--parallel",
|
|
569
|
+
initial_arg_list = ["-f", "--parallel", f"threads={self.max_parallel_connections}"] if force else ["--parallel",
|
|
570
|
+
f"threads={self.max_parallel_connections}"]
|
|
560
571
|
if not self.silent:
|
|
561
572
|
self.__validate_file_list(file_list)
|
|
562
573
|
|
|
@@ -629,7 +640,8 @@ class P4Client(object):
|
|
|
629
640
|
info_dicts = self.run_cmd("delete", args=["-c", changelist], file_list=file_list)
|
|
630
641
|
return info_dicts
|
|
631
642
|
|
|
632
|
-
def delete_changelist(self, changelist, perfect_match_only=False, case_sensitive=False, delete_shelved_files=False,
|
|
643
|
+
def delete_changelist(self, changelist, perfect_match_only=False, case_sensitive=False, delete_shelved_files=False,
|
|
644
|
+
obliterate=False):
|
|
633
645
|
"""
|
|
634
646
|
Deletes a changelist via changelist number or description. Will fail if any files are checked out or shelved files exist.
|
|
635
647
|
:param changelist: *string* or *int* change list number
|
|
@@ -645,10 +657,10 @@ class P4Client(object):
|
|
|
645
657
|
if obliterate:
|
|
646
658
|
info_dicts.append(self.revert_changelist(changelist=cl))
|
|
647
659
|
delete_shelved_files = True
|
|
648
|
-
|
|
660
|
+
|
|
649
661
|
if delete_shelved_files:
|
|
650
662
|
info_dicts.append(self.delete_shelf(cl))
|
|
651
|
-
|
|
663
|
+
|
|
652
664
|
info_dicts.append(self.run_cmd('change', args=['-d', cl]))
|
|
653
665
|
# TODO: Break down info dicts and look for errors
|
|
654
666
|
return info_dicts
|
|
@@ -684,7 +696,7 @@ class P4Client(object):
|
|
|
684
696
|
:return: *list* of info dictionaries
|
|
685
697
|
"""
|
|
686
698
|
changelist = self.__ensure_changelist(changelist)
|
|
687
|
-
|
|
699
|
+
|
|
688
700
|
# if no files specified, get all files in the changelist
|
|
689
701
|
if file_list is None:
|
|
690
702
|
file_list = self.get_files_in_changelist(changelist)
|
|
@@ -692,34 +704,35 @@ class P4Client(object):
|
|
|
692
704
|
file_list = convert_to_list(file_list) if not isinstance(file_list, list) else file_list
|
|
693
705
|
if not self.silent:
|
|
694
706
|
self.__validate_file_list(file_list)
|
|
695
|
-
|
|
707
|
+
|
|
696
708
|
# if there are no files to shelve, return empty list
|
|
697
709
|
if not file_list:
|
|
698
710
|
if not self.silent:
|
|
699
711
|
logging.warning(f"No files to shelve in changelist {changelist}")
|
|
700
712
|
return []
|
|
701
|
-
|
|
713
|
+
|
|
702
714
|
# iuild args list based on options
|
|
703
715
|
args = ["-c", str(changelist)]
|
|
704
716
|
if force:
|
|
705
717
|
args.append("-f")
|
|
706
|
-
|
|
718
|
+
|
|
707
719
|
# run the shelve command
|
|
708
720
|
info_dicts = self.run_cmd("shelve", args=args, file_list=file_list)
|
|
709
|
-
|
|
721
|
+
|
|
710
722
|
for info_dict in info_dicts:
|
|
711
723
|
if self.__get_dict_value(info_dict, "code") == "error" and not self.silent:
|
|
712
724
|
logging.error(self.__get_dict_value(info_dict, "data"))
|
|
713
|
-
|
|
725
|
+
|
|
714
726
|
# revert files if requested
|
|
715
727
|
if revert_after_shelve and file_list:
|
|
716
728
|
revert_info_dicts = self.revert_files(file_list)
|
|
717
729
|
# add revert info to the return data
|
|
718
730
|
info_dicts.extend(revert_info_dicts)
|
|
719
|
-
|
|
731
|
+
|
|
720
732
|
return info_dicts
|
|
721
733
|
|
|
722
|
-
def unshelve_files(self, changelist, file_list=None, target_changelist="default", force=False,
|
|
734
|
+
def unshelve_files(self, changelist, file_list=None, target_changelist="default", force=False,
|
|
735
|
+
delete_shelved_files=False):
|
|
723
736
|
"""
|
|
724
737
|
Unshelves files from a shelved changelist. If no files are specified, unshelves all files.
|
|
725
738
|
|
|
@@ -732,21 +745,21 @@ class P4Client(object):
|
|
|
732
745
|
"""
|
|
733
746
|
source_changelist = self.__ensure_changelist(changelist)
|
|
734
747
|
target_changelist = self.__ensure_changelist(target_changelist)
|
|
735
|
-
|
|
748
|
+
|
|
736
749
|
# build the arguments list
|
|
737
750
|
args = []
|
|
738
|
-
|
|
751
|
+
|
|
739
752
|
# add force flag if requested
|
|
740
753
|
if force:
|
|
741
754
|
args.append("-f")
|
|
742
|
-
|
|
755
|
+
|
|
743
756
|
# add source changelist (required)
|
|
744
757
|
args.extend(["-s", str(source_changelist)])
|
|
745
|
-
|
|
758
|
+
|
|
746
759
|
# add target changelist if specified and not default
|
|
747
760
|
if target_changelist != "default":
|
|
748
761
|
args.extend(["-c", str(target_changelist)])
|
|
749
|
-
|
|
762
|
+
|
|
750
763
|
# prepare file list if provided
|
|
751
764
|
if file_list is not None:
|
|
752
765
|
file_list = convert_to_list(file_list) if not isinstance(file_list, list) else file_list
|
|
@@ -754,33 +767,33 @@ class P4Client(object):
|
|
|
754
767
|
self.__validate_file_list(file_list)
|
|
755
768
|
else:
|
|
756
769
|
file_list = []
|
|
757
|
-
|
|
770
|
+
|
|
758
771
|
# run the unshelve command
|
|
759
772
|
info_dicts = self.run_cmd("unshelve", args=args, file_list=file_list)
|
|
760
|
-
|
|
773
|
+
|
|
761
774
|
# check for errors in the unshelve operation
|
|
762
775
|
has_error = False
|
|
763
776
|
for info_dict in info_dicts:
|
|
764
777
|
if self.__get_dict_value(info_dict, "code") == "error" and not self.silent:
|
|
765
778
|
logging.error(self.__get_dict_value(info_dict, "data"))
|
|
766
779
|
has_error = True
|
|
767
|
-
|
|
780
|
+
|
|
768
781
|
# delete shelved files if requested and unshelve was successful
|
|
769
782
|
if delete_shelved_files and not has_error:
|
|
770
783
|
# build the arguments for the shelve -d command
|
|
771
784
|
delete_args = ["-d", "-c", str(source_changelist)]
|
|
772
|
-
|
|
785
|
+
|
|
773
786
|
# if file_list provided, use it for the delete operation as well
|
|
774
787
|
delete_info_dicts = self.run_cmd("shelve", args=delete_args, file_list=file_list)
|
|
775
|
-
|
|
788
|
+
|
|
776
789
|
# check for errors in the delete operation
|
|
777
790
|
for info_dict in delete_info_dicts:
|
|
778
791
|
if self.__get_dict_value(info_dict, "code") == "error" and not self.silent:
|
|
779
792
|
logging.error(self.__get_dict_value(info_dict, "data"))
|
|
780
|
-
|
|
793
|
+
|
|
781
794
|
# add the delete info to the return data
|
|
782
795
|
info_dicts.extend(delete_info_dicts)
|
|
783
|
-
|
|
796
|
+
|
|
784
797
|
return info_dicts
|
|
785
798
|
|
|
786
799
|
def delete_shelf(self, changelist):
|
|
@@ -793,13 +806,13 @@ class P4Client(object):
|
|
|
793
806
|
try:
|
|
794
807
|
# Ensure the changelist exists and is a number
|
|
795
808
|
changelist = self.__ensure_changelist(changelist)
|
|
796
|
-
|
|
809
|
+
|
|
797
810
|
# Don't allow deleting shelves from the default changelist
|
|
798
811
|
if changelist == "default":
|
|
799
812
|
if not self.silent:
|
|
800
813
|
logging.error("Cannot delete shelved files from the default changelist")
|
|
801
814
|
return [{"code": "error", "data": "Cannot delete shelved files from the default changelist"}]
|
|
802
|
-
|
|
815
|
+
|
|
803
816
|
# Check if the changelist has shelved files
|
|
804
817
|
has_shelved_files = False
|
|
805
818
|
info_dicts = self.run_cmd("describe", args=["-S", str(changelist)])
|
|
@@ -810,16 +823,16 @@ class P4Client(object):
|
|
|
810
823
|
break
|
|
811
824
|
if has_shelved_files:
|
|
812
825
|
break
|
|
813
|
-
|
|
826
|
+
|
|
814
827
|
if not has_shelved_files:
|
|
815
828
|
if not self.silent:
|
|
816
829
|
logging.warning(f"No shelved files found in changelist {changelist}")
|
|
817
830
|
return [{"code": "info", "data": f"No shelved files found in changelist {changelist}"}]
|
|
818
|
-
|
|
831
|
+
|
|
819
832
|
# Delete all shelved files in the changelist
|
|
820
833
|
info_dicts = self.run_cmd("shelve", args=["-d", "-c", str(changelist)])
|
|
821
834
|
return info_dicts
|
|
822
|
-
|
|
835
|
+
|
|
823
836
|
except Exception as e:
|
|
824
837
|
if not self.silent:
|
|
825
838
|
logging.error(f"Failed to delete shelved files: {e}")
|
|
@@ -845,11 +858,11 @@ class P4Client(object):
|
|
|
845
858
|
if not complete_file_path in files:
|
|
846
859
|
all_files.append(complete_file_path)
|
|
847
860
|
else:
|
|
848
|
-
all_files.extend([os.path.join(folder, file) for file in os.listdir(folder) if
|
|
861
|
+
all_files.extend([os.path.join(folder, file) for file in os.listdir(folder) if
|
|
862
|
+
os.path.isfile(os.path.join(folder, file))])
|
|
849
863
|
|
|
850
864
|
return self.add_or_edit_files(all_files, changelist=changelist)
|
|
851
865
|
|
|
852
|
-
|
|
853
866
|
@validate_not_empty
|
|
854
867
|
def add_or_edit_files(self, file_list, changelist="default"):
|
|
855
868
|
"""
|
|
@@ -971,7 +984,8 @@ class P4Client(object):
|
|
|
971
984
|
|
|
972
985
|
return depot_paths
|
|
973
986
|
|
|
974
|
-
def get_pending_changelists(self, description_filter="", perfect_match_only=False, case_sensitive=False,
|
|
987
|
+
def get_pending_changelists(self, description_filter="", perfect_match_only=False, case_sensitive=False,
|
|
988
|
+
descriptions=False):
|
|
975
989
|
"""
|
|
976
990
|
Returns all the pending change lists, filtered on the changelist description
|
|
977
991
|
|
|
@@ -1038,7 +1052,7 @@ class P4Client(object):
|
|
|
1038
1052
|
case_sensitive=case_sensitive,
|
|
1039
1053
|
)
|
|
1040
1054
|
|
|
1041
|
-
if len(changelists) > 1:
|
|
1055
|
+
if len(changelists) > 1: # > 1 because "default" is always appended
|
|
1042
1056
|
return changelists[0]
|
|
1043
1057
|
else:
|
|
1044
1058
|
return self.make_new_changelist(description=changelist_description)
|
|
@@ -1076,7 +1090,6 @@ class P4Client(object):
|
|
|
1076
1090
|
depot_paths = [self.__get_dict_value(info, "depotFile").rstrip("/...") for info in info_dicts]
|
|
1077
1091
|
return depot_paths
|
|
1078
1092
|
|
|
1079
|
-
|
|
1080
1093
|
@validate_not_empty
|
|
1081
1094
|
def get_local_paths(self, paths):
|
|
1082
1095
|
"""
|
|
@@ -1116,7 +1129,7 @@ class P4Client(object):
|
|
|
1116
1129
|
|
|
1117
1130
|
return info_dicts
|
|
1118
1131
|
|
|
1119
|
-
def host_online(self):
|
|
1132
|
+
def host_online(self, timeout=2.0):
|
|
1120
1133
|
"""
|
|
1121
1134
|
Checks if the host for this client is online
|
|
1122
1135
|
|
|
@@ -1126,10 +1139,16 @@ class P4Client(object):
|
|
|
1126
1139
|
host = self.__server_address()
|
|
1127
1140
|
|
|
1128
1141
|
try:
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1142
|
+
with socket.create_connection((host, port), timeout=timeout):
|
|
1143
|
+
return True
|
|
1144
|
+
except socket.timeout:
|
|
1145
|
+
logging.warning(f"Connection to {host} on port {port} timed out after {timeout} seconds, the running command might not complete correctly")
|
|
1146
|
+
return False
|
|
1147
|
+
except ConnectionRefusedError:
|
|
1148
|
+
logging.warning(f"Connection to {host} on port {port} refused to connect, is the server still up?")
|
|
1149
|
+
return False
|
|
1150
|
+
except OSError as e:
|
|
1151
|
+
logging.warning(f"oserror: {e.strerror or e}")
|
|
1133
1152
|
return False
|
|
1134
1153
|
|
|
1135
1154
|
def __server_address(self):
|
|
@@ -1243,6 +1262,9 @@ class P4Client(object):
|
|
|
1243
1262
|
|
|
1244
1263
|
:return: *bool*
|
|
1245
1264
|
"""
|
|
1265
|
+
if not self.perforce_root:
|
|
1266
|
+
raise p4errors.WorkSpaceError(f"self.perforce_root (value: {self.perforce_root}) is not set!")
|
|
1267
|
+
|
|
1246
1268
|
starting_dir = self.perforce_root
|
|
1247
1269
|
last_dir = ""
|
|
1248
1270
|
current_dir = starting_dir
|
|
@@ -1265,11 +1287,15 @@ class P4Client(object):
|
|
|
1265
1287
|
:param file_list: List of files to iterate
|
|
1266
1288
|
:return:
|
|
1267
1289
|
"""
|
|
1290
|
+
if not self.perforce_root:
|
|
1291
|
+
raise p4errors.WorkSpaceError(f"self.perforce_root (value: {self.perforce_root}) is not set!")
|
|
1292
|
+
|
|
1268
1293
|
file_list = convert_to_list(file_list) if not isinstance(file_list, list) else file_list
|
|
1269
1294
|
|
|
1270
1295
|
# Easy utility to check that the file is underneath the correct perforce root
|
|
1271
1296
|
# Quicker than waiting for the result of a p4 fstat
|
|
1272
1297
|
for f in file_list:
|
|
1273
|
-
if not f.lower().startswith(self.perforce_root.lower()) and not f.lower().startswith(
|
|
1298
|
+
if not f.lower().startswith(self.perforce_root.lower()) and not f.lower().startswith(
|
|
1299
|
+
self.depot_root.lower()):
|
|
1274
1300
|
raise Exception(f'{f} is not under perforce root: {self.perforce_root}, {self.depot_root}')
|
|
1275
1301
|
|
|
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
|