pyjallib 0.1.13__tar.gz → 0.1.14__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.
- {pyjallib-0.1.13 → pyjallib-0.1.14}/PKG-INFO +1 -1
- {pyjallib-0.1.13 → pyjallib-0.1.14}/pyproject.toml +1 -1
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/__init__.py +1 -1
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/perforce.py +82 -4
- {pyjallib-0.1.13 → pyjallib-0.1.14}/.gitignore +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/.python-version +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/PRD/BIPPY_/353/260/224/354/235/264/355/214/250/353/223/234_/354/203/235/354/204/261_/353/266/204/354/204/235.md" +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/PRD/PyJalLib_Mocap_Module_PRD.md +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/README.md +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/index.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/max.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/namePart.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/nameToPath.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/naming.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/namingConfig.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/p4module.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/perforce.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib/reloadModules.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/pyjallib.html +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/docs/search.js +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/generate_docs.ps1 +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/ref/BIPPY.ms +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/ConfigFiles/namingConfig.json +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/ConfigFiles/3DSMaxNamingConfig.json +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/ConfigFiles/Default_3DSMaxNamingConfig.json +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/__init__.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/align.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/anim.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/autoClavicle.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/bip.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/bone.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/boneChain.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/constraint.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/fbxHandler.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/groinBone.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/header.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/helper.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/hip.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/kneeBone.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/layer.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/link.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/macro/jal_macro_align.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/macro/jal_macro_bone.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/macro/jal_macro_constraint.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/macro/jal_macro_helper.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/macro/jal_macro_link.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/macro/jal_macro_select.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/mirror.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/mocap.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/morph.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/name.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/rootMotion.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/select.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/skin.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/toolManager.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/twistBone.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/ui/Container.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/volumeBone.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/namePart.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/nameToPath.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/naming.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/namingConfig.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/py.typed +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/reloadModules.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/animNodeTest.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/autoclavicleTest.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/fbxExportTest.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/globalVarTest.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/moduleImportTest.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/p4Test.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/tests/volumePreserveBoneTest.py +0 -0
- {pyjallib-0.1.13 → pyjallib-0.1.14}/uv.lock +0 -0
@@ -16,10 +16,14 @@ from pathlib import Path
|
|
16
16
|
|
17
17
|
# 로깅 설정
|
18
18
|
logger = logging.getLogger(__name__)
|
19
|
-
|
19
|
+
|
20
|
+
# 기본 로그 레벨은 ERROR로 설정 (디버그 모드는 생성자에서 설정)
|
21
|
+
logger.setLevel(logging.ERROR)
|
22
|
+
|
20
23
|
# 사용자 문서 폴더 내 로그 파일 저장
|
21
24
|
log_path = os.path.join(Path.home() / "Documents", 'Perforce.log')
|
22
25
|
file_handler = logging.FileHandler(log_path, encoding='utf-8')
|
26
|
+
file_handler.setLevel(logging.ERROR) # 기본적으로 ERROR 레벨만 기록
|
23
27
|
file_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
24
28
|
logger.addHandler(file_handler)
|
25
29
|
|
@@ -27,8 +31,19 @@ logger.addHandler(file_handler)
|
|
27
31
|
class Perforce:
|
28
32
|
"""P4Python을 사용하여 Perforce 작업을 수행하는 클래스."""
|
29
33
|
|
30
|
-
def __init__(self):
|
31
|
-
"""Perforce 인스턴스를 초기화합니다.
|
34
|
+
def __init__(self, debug_mode: bool = False):
|
35
|
+
"""Perforce 인스턴스를 초기화합니다.
|
36
|
+
|
37
|
+
Args:
|
38
|
+
debug_mode (bool): True로 설정하면 DEBUG 레벨 로그를 활성화합니다.
|
39
|
+
기본값은 False (ERROR 레벨만 기록)
|
40
|
+
"""
|
41
|
+
# 디버그 모드에 따라 로그 레벨 설정
|
42
|
+
if debug_mode:
|
43
|
+
logger.setLevel(logging.DEBUG)
|
44
|
+
file_handler.setLevel(logging.DEBUG)
|
45
|
+
logger.debug("디버그 모드가 활성화되었습니다.")
|
46
|
+
|
32
47
|
self.p4 = P4()
|
33
48
|
self.connected = False
|
34
49
|
self.workspaceRoot = r""
|
@@ -575,11 +590,13 @@ class Perforce:
|
|
575
590
|
|
576
591
|
return all_success
|
577
592
|
|
578
|
-
def submit_change_list(self, change_list_number: int) -> bool:
|
593
|
+
def submit_change_list(self, change_list_number: int, auto_revert_unchanged: bool = True) -> bool:
|
579
594
|
"""체인지 리스트를 제출합니다.
|
580
595
|
|
581
596
|
Args:
|
582
597
|
change_list_number (int): 제출할 체인지 리스트 번호
|
598
|
+
auto_revert_unchanged (bool, optional): 제출 후 변경사항이 없는 체크아웃된 파일들을
|
599
|
+
자동으로 리버트할지 여부. 기본값 True
|
583
600
|
|
584
601
|
Returns:
|
585
602
|
bool: 제출 성공 시 True, 실패 시 False
|
@@ -590,6 +607,11 @@ class Perforce:
|
|
590
607
|
try:
|
591
608
|
self.p4.run_submit("-c", change_list_number)
|
592
609
|
logger.info(f"체인지 리스트 {change_list_number} 제출 성공.")
|
610
|
+
|
611
|
+
# 제출 후 변경사항이 없는 체크아웃된 파일들을 자동으로 리버트
|
612
|
+
if auto_revert_unchanged:
|
613
|
+
self._auto_revert_unchanged_files(change_list_number)
|
614
|
+
|
593
615
|
return True
|
594
616
|
except P4Exception as e:
|
595
617
|
self._handle_p4_exception(e, f"체인지 리스트 {change_list_number} 제출")
|
@@ -597,6 +619,62 @@ class Perforce:
|
|
597
619
|
logger.warning(f"체인지 리스트 {change_list_number}에 제출할 파일이 없습니다.")
|
598
620
|
return False
|
599
621
|
|
622
|
+
def _auto_revert_unchanged_files(self, change_list_number: int) -> None:
|
623
|
+
"""제출 후 변경사항이 없는 체크아웃된 파일들을 자동으로 리버트합니다.
|
624
|
+
|
625
|
+
Args:
|
626
|
+
change_list_number (int): 체인지 리스트 번호
|
627
|
+
"""
|
628
|
+
logger.debug(f"체인지 리스트 {change_list_number}에서 변경사항이 없는 파일들 자동 리버트 시도...")
|
629
|
+
try:
|
630
|
+
# 체인지 리스트에서 체크아웃된 파일들 가져오기
|
631
|
+
opened_files = self.p4.run_opened("-c", change_list_number)
|
632
|
+
|
633
|
+
if not opened_files:
|
634
|
+
logger.debug(f"체인지 리스트 {change_list_number}에 체크아웃된 파일이 없습니다.")
|
635
|
+
return
|
636
|
+
|
637
|
+
unchanged_files = []
|
638
|
+
for file_info in opened_files:
|
639
|
+
file_path = file_info.get('clientFile', '')
|
640
|
+
action = file_info.get('action', '')
|
641
|
+
|
642
|
+
# edit 액션의 파일만 확인 (add, delete는 변경사항이 있음)
|
643
|
+
if action == 'edit':
|
644
|
+
try:
|
645
|
+
# p4 diff 명령으로 파일의 변경사항 확인
|
646
|
+
diff_result = self.p4.run_diff("-sa", file_path)
|
647
|
+
|
648
|
+
# diff 결과가 비어있으면 변경사항이 없음
|
649
|
+
if not diff_result:
|
650
|
+
unchanged_files.append(file_path)
|
651
|
+
logger.debug(f"파일 '{file_path}'에 변경사항이 없어 리버트 대상으로 추가")
|
652
|
+
else:
|
653
|
+
logger.debug(f"파일 '{file_path}'에 변경사항이 있어 리버트하지 않음")
|
654
|
+
|
655
|
+
except P4Exception as e:
|
656
|
+
# diff 명령 실패 시에도 리버트 대상으로 추가 (안전하게 처리)
|
657
|
+
unchanged_files.append(file_path)
|
658
|
+
logger.debug(f"파일 '{file_path}' diff 확인 실패, 리버트 대상으로 추가: {e}")
|
659
|
+
else:
|
660
|
+
logger.debug(f"파일 '{file_path}'는 {action} 액션이므로 리버트하지 않음")
|
661
|
+
|
662
|
+
# 변경사항이 없는 파일들을 리버트
|
663
|
+
if unchanged_files:
|
664
|
+
logger.info(f"체인지 리스트 {change_list_number}에서 변경사항이 없는 파일 {len(unchanged_files)}개 자동 리버트 시도...")
|
665
|
+
for file_path in unchanged_files:
|
666
|
+
try:
|
667
|
+
self.p4.run_revert("-c", change_list_number, file_path)
|
668
|
+
logger.info(f"파일 '{file_path}' 자동 리버트 완료")
|
669
|
+
except P4Exception as e:
|
670
|
+
self._handle_p4_exception(e, f"파일 '{file_path}' 자동 리버트")
|
671
|
+
logger.info(f"체인지 리스트 {change_list_number}에서 변경사항이 없는 파일 {len(unchanged_files)}개 자동 리버트 완료")
|
672
|
+
else:
|
673
|
+
logger.debug(f"체인지 리스트 {change_list_number}에서 변경사항이 없는 파일이 없습니다.")
|
674
|
+
|
675
|
+
except P4Exception as e:
|
676
|
+
self._handle_p4_exception(e, f"체인지 리스트 {change_list_number} 자동 리버트 처리")
|
677
|
+
|
600
678
|
def revert_change_list(self, change_list_number: int) -> bool:
|
601
679
|
"""체인지 리스트를 되돌리고 삭제합니다.
|
602
680
|
|
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
|
{pyjallib-0.1.13 → pyjallib-0.1.14}/src/pyjallib/max/ConfigFiles/Default_3DSMaxNamingConfig.json
RENAMED
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
|
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
|