
    ?# j                    H   d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlZ ed      ZdddZej                  dd       Zej                  d	        Zej                  d
        Zej                  d        Zej                  d        Zej                  d        Zy)u  task-2457 Phase 2-A: git hooks (pre-commit / pre-push) 테스트용 공용 픽스처.

- 모리건 (dev3-team / tester) 작성.
- 실제 hook 스크립트 경로:
    /home/jay/workspace/.worktrees/task-2457-dev3/scripts/git-hooks/{pre-commit,pre-push}
- 각 테스트는 tmp_path 안에 git init된 격리 repo를 받아, 진짜 hook 파일을 그대로 복사해 실행한다.
- 명세 가정 (루가 작성 중인 hook 본체 기준):
  * pre-commit: lock 존재 + branch task-id 일치 + main 아닌 task 패턴(task/task-<n>-...) 검증
  * pre-push: 위 + scope_check + cancelled marker + main direct push 거부
  * TASKCTL_BYPASS=1 + TASKCTL_BYPASS_REASON=<text> 시 bypass 허용 + evidence 기록
    )annotationsN)Path)Iterablez?/home/jay/workspace/.worktrees/task-2457-dev3/scripts/git-hooksc                    t        j                  | t        |      ||nt        j                  j                         ddd      S )uZ   헬퍼: 서브프로세스 실행. 실패 시 에러 메시지를 가독성 있게 표시.TF)cwdenvcapture_outputtextcheck)
subprocessrunstrosenvironcopy)cmdr   r   s      I/home/jay/workspace/.worktrees/task-2537-dev4/tests/git_hooks/conftest.py_runr      s:    >>H?C

(9     c           	        | dz  }|j                          t        g d|      }|j                  dk7  rt        ddg|       t        g d|       t        g d|       t        g d	|       t        g d
|       |dz  dz  }|j                  dd       t        j	                         rMdD ]H  }t        |z  }|j	                         s||z  }t        j                  ||       |j                  d       J t        g d|       |dz  dz  j                  dd       |dz  dz  j                  dd       |dz  dz  j                  dd       |dz  dz  j                  dd       |dz  j                  dd       t        g d|       t        g d|       | dz  }t        dddt        |      g|        t        dd d!d"t        |      g|       t        g d#|       |S )$u  임시 git repo + scripts/git-hooks 복사 + core.hooksPath 설정.

    반환: repo 루트 Path.

    구성:
      - git init -b main (main 브랜치로 시작)
      - user.email / user.name 설정 (CI에서도 commit 가능)
      - scripts/git-hooks/ 에 실제 hook 파일 복사 (실행 권한 유지)
      - .tasks/{locks,evidence} / memory/{events,capabilities} 디렉토리 미리 생성
      - 초기 commit 1개 생성 (HEAD가 존재해야 git rev-parse 등이 정상 동작)
    repo)gitinit-bmainr   r   r   r   )r   checkoutr   r   )r   configz
user.emailzmorrigan@dev3.local)r   r   z	user.nameMorrigan)r   r   zcommit.gpgsignfalsescripts	git-hooksTparentsexist_ok)z
pre-commitzpre-pushi  )r   r   zcore.hooksPathzscripts/git-hooks.taskslocksevidencememoryeventscapabilities	README.mdz# test repo
utf-8encoding)r   addr,   )r   commitz-mr   --no-verifyz
origin.gitz--bareremoter0   origin)r   pushr2   z-ur4   r   )
mkdirr   
returncodeREAL_HOOKS_DIRexistsshutilcopy2chmod
write_textr   )tmp_pathr   r   	hooks_dst	hook_namesrcdstbares           r   git_reporD   *   s    fDJJL -48D!eV_$'.D9	?TJ	3>	54@ y ;.IOOD4O03 	!I 9,Czz|)+S#&		% 	! 	@ 
H_w%%dT%B	H_z!(((E	H_x&&td&C	H_~%,,TD,I 
K##Og#F	$$/6 l"D%3t9	-8<%5(CI	6DA	?TJKr   c                     dd} | S )u   헬퍼 픽스처: .tasks/locks/<task-id>.lock JSON 파일 생성.

    사용 예:
        make_lock(repo, task_id="task-2457", branch="task/task-2457-dev3")
    c                   | dz  dz  | dz  }||t         j                  j                  dd      dd}|j                  |       |j                  j                  dd	       |j                  t        j                  |d
d      d       |S )Nr&   r'   z.lockUSERunknownz2026-05-05T00:00:00Z)task_idbranchowneracquired_atTr#   F   ensure_asciiindentr-   r.   )	r   r   getupdateparentr6   r=   jsondumps)r   rI   rJ   extra	lock_pathpayloads         r   _factoryzmake_lock.<locals>._factoryx   s    8Og-7)50AA	ZZ^^FI61	
 	utd;TZZeANY`ar   )r   r   rI   r   rJ   r   returnr    rY   s    r   	make_lockr]   p   s     Or   c                     dd} | S )uF   헬퍼 픽스처: memory/events/<task-id>.cancelled 빈 파일 생성.c                    | dz  dz  | dz  }|j                   j                  dd       |j                  dd       |S )	Nr)   r*   z
.cancelledTr#    r-   r.   )rS   r6   r=   )r   rI   markers      r   rY   z make_cancelled.<locals>._factory   sK    8+	.DDD48"w/r   )r   r   rI   r   rZ   r   r[   r\   s    r   make_cancelledrb      s     Or   c                     dd} | S )u   헬퍼 픽스처: memory/capabilities/<task-id>.json 생성 (scope_check용).

    allowed_paths: 변경 허용 경로(글롭/접두) 리스트.
    c                    | dz  dz  | dz  }|dt        |      id}|j                  j                  dd       |j                  t	        j
                  |dd	
      d       |S )Nr)   r+   z.jsonpaths)rI   allowed_resourcesTr#   FrM   rN   r-   r.   )listrS   r6   r=   rT   rU   )r   rI   allowed_pathscap_pathrX   s        r   rY   z!make_capability.<locals>._factory   st    (?^3	6GG ")4+>!?
 	dT:DJJwU1MX_`r   )r   r   rI   r   rh   zIterable[str]rZ   r   r[   r\   s    r   make_capabilityrj      s    
 Or   c                     dd} | S )u.   헬퍼: repo 안에서 새 branch로 checkout.c                    t        ddd|g|       }|j                  dk(  rt        dd|g|        y t        ddd|g|        y )Nr   z	rev-parsez--verifyr   r   r   r   )r   r7   )r   rJ   existings      r   rY   z!checkout_branch.<locals>._factory   sI    Z@dK!#%V,$7%T62=r   )r   r   rJ   r   rZ   Noner[   r\   s    r   checkout_branchro      s    > Or   c                 &    	 	 d	 	 	 	 	 	 	 	 	 dd} | S )u   헬퍼: hook 스크립트를 직접 bash로 실행한다.

    사용 예:
        result = run_hook(repo, "pre-commit", env_extra={"TASKCTL_BYPASS": "1"})
        result = run_hook(repo, "pre-push", stdin="refs/heads/x sha refs/heads/main sha
")
    c           	         | dz  dz  |z  }t         j                  j                         }t        | dz        |d<   t        |       |d<   |r|j	                  |       t        j                  dt        |      gt        |       |||ndddd	
      S )Nr!   r"   z.gitGIT_DIR	WORKSPACEbashr`   TF)r   r   inputr	   r
   r   )r   r   r   r   rR   r   r   )r   r@   stdin	env_extra	hook_pathr   s         r   rY   zrun_hook.<locals>._factory   s     9${2Y>	jjooTF]+It9KJJy!~~S^$D	 ,%"
 	
r   )NN)
r   r   r@   r   rv   z
str | Nonerw   dict | NonerZ   subprocess.CompletedProcessr[   r\   s    r   run_hookr{      sD     !!%	


 
 	

 
%
. Or   )N)r   z	list[str]r   r   r   ry   rZ   rz   )r>   r   rZ   r   )__doc__
__future__r   rT   r   r:   r   pathlibr   typingr   pytestr8   r   fixturerD   r]   rb   rj   ro   r{   r[   r   r   <module>r      s   
 #  	      E
	 B BJ  . 	 	  *    r   