
    iq                     V   d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	  G d de      Z
 G d d	e      Z ej                  d
      Zdedee   fdZddededededef
dZdee   dee
   dee   dz  fdZdeeef   dedee   dz  fdZdeeef   dedefdZdeeef   dedefdZy)u  M-18 패치 파서 — unified diff 파싱/적용/롤백 유틸리티.

Python difflib 기반으로 unified diff 형식의 패치를 파싱하고,
atomic_write를 사용해 파일에 안전하게 적용합니다.

Usage:
    from utils.patch_parser import parse_patch, apply_patch, generate_patch, verify_patch

    patch = generate_patch(original_text, modified_text, fromfile="a/src.py", tofile="b/src.py")
    success = apply_patch("src.py", patch)
    N)Path)	TypedDictUnion)atomic_text_writec                   J    e Zd ZU dZeed<   eed<   eed<   eed<   ee   ed<   y)Hunku   unified diff hunk 구조체.	old_start	old_count	new_start	new_countlinesN)__name__
__module____qualname____doc__int__annotations__liststr     C/home/jay/workspace/.worktrees/task-2116-dev1/utils/patch_parser.pyr   r      s#    &NNNN9r   r   c                   6    e Zd ZU dZeed<   eed<   ee   ed<   y)	FilePatchu   파일 단위 패치 구조체.old_filenew_filehunksN)r   r   r   r   r   r   r   r   r   r   r   r   r      s    )MM:r   r   z+^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@
patch_textreturnc           
      .   | r| j                         sg S g }d}d}| j                         D ]=  }|j                  d      rK|)||d   j                  |       d}|j                  |       t	        |dd j                         dg       }`|j                  d      r||dd j                         |d<   t
        j                  |      }|rx|v||d   j                  |       |j                         }t        t        |d	         |d
   t        |d
         nd
t        |d         |d   t        |d         nd
g       }||s!|d	   dv s*|d   j                  |       @ |'||d   j                  |       |j                  |       |S )uK   unified diff 텍스트를 파싱하여 FilePatch 목록을 반환합니다.Nz--- r       )r   r   r   z+++ r   r            )r	   r
   r   r   r   ) +-r   )
strip
splitlines
startswithappendr   _HUNK_HEADER_REmatchgroupsr   r   )r   resultscurrent_filecurrent_hunklinemgs          r   parse_patchr6   +   s   Z--/	!G%)L $L%%' 3??6"'+ )00>#'L|,$d12hnn.>SUVL__V$)A'+ABx~~'7L$%%d+A\-+ )00>HHJ#!!A$i+,Q4+;c!A$i!!A$i+,Q4+;c!A$i  )dtAw/7QW%,,T2134 #!((6|$Nr   originalmodifiedfromfiletofilec                     t        t        j                  | j                  d      |j                  d      ||            }dj	                  |      S )u_   두 텍스트 사이의 unified diff 패치를 생성합니다. 변경 없으면 빈 문자열.Tkeepends)r9   r:   r"   )r   difflibunified_diffr*   join)r7   r8   r9   r:   
diff_liness        r   generate_patchrB   V   sS    ..		
J 77:r   original_linesr   c                 B   t        |       }d}|D ]  }|d   dz
  |z   }|d   }|}|D ]L  }|s|d   dv s|t        |      k\  s)||   j                  d      |dd j                  d      k7  r  y|dz  }N g }	|}
|D ]}  }|s|d   dk(  r-|	j                  |
t        |      k  r||
   n|dd        |
dz  }
;|d   d	k(  r-|dd }|	j                  |j	                  d      r|n|dz          p|d   d
k(  sy|
dz  }
 |	||||d   z    |t        |	      |d   z
  z  } |S )uO   hunk 목록을 원본 라인에 적용. 컨텍스트 불일치 시 None 반환.r   r	   r#   r   )r(   r&   
Nr&   r'   r(   r
   )r   lenrstripr,   endswith)rC   r   resultoffsethunkr	   r   src_idxhl	new_chunkorig_idxcontents               r   _apply_hunksrQ   c   s   ^,FF 5%)F2	W  	Bbez)c&k)VG_-C-CD-IRPQPRV]][_M`-`1		  "	 
	B!u|  XF5K!1QSTUTVQWXAA#QR&  G,<,<T,BRVWA#A
	 =Fy9tK'889#i.4#44495< Mr   target_filec                    t        |       }|j                         sy|r|j                         s"|j                  d      j	                  d      S t        |      }|s"|j                  d      j	                  d      S |j                  d      j	                  d      }|D ]  }| yt        t        |      |d         }  |S )uU   파일을 읽어 패치를 적용한 결과 라인 목록을 반환. 실패 시 None.Nzutf-8)encodingTr<   r   )r   existsr)   	read_textr*   r6   rQ   r   )rR   r   pathfile_patchesr   fps         r   _load_and_applyrZ      s    D;;=Z--/~~w~/::D:IIz*L~~w~/::D:II"nngn>IISWIXE 7=T%["W+67 Lr   c                 j    t        | |      }|yt        t        |       dj                  |             y)uR   파일에 unified diff 패치를 원자적으로 적용합니다. 성공 시 True.Fr"   T)rZ   r   r   r@   )rR   r   rI   s      r   apply_patchr\      s0    [*5F~d;'9r   c                     t        | |      duS )ud   파일에 패치를 적용할 수 있는지 확인합니다 (실제 적용 없음). 가능 시 True.N)rZ   )rR   r   s     r   verify_patchr^      s    ;
34??r   )r7   r8   )r   r>   repathlibr   typingr   r   utils.atomic_writer   r   r   compiler-   r   r   r6   rB   rQ   rZ   boolr\   r^   r   r   r   <module>re      s+  
  	  # 09 	  "**KL(C (DO (V
S 
C 
3 
UX 
jm 
#c #4: #$s)dBR #LsDy!1 s tCySWGW (U39- 3 4 @eCI. @C @D @r   