
    zi%                        d Z ddlZddlZddlZddlmZ dedefdZ ej                  d       ej                  d       ej                  d	      gZ
 ej                  d
      Z ej                  dej                  ej                  z        Zdededee   fdZddededefdZdedefdZdedefdZdededefdZddededefdZedk(  rddlZddlZ eej8                        dk  r1 e ej<                  ddgddd              ej>                  d       ej8                  d   Z  eej8                        dkD  rej8                  d   ndZ! ee e!      Z" e ej<                  e"dd             yy) u  
symbol_existence_check.py - 심볼 존재 여부 검증 verifier

보고서(.md)에서 "구현 완료"라고 한 핵심 심볼(함수명, 클래스명 등)이
실제 파일에 존재하는지 자동 검증.

이리스(Iris) dev1팀 프론트엔드 개발자 작성
task-1882
    N)Optionalworkspace_rootreturnc                     t        j                  |       }t        j                  d|z   dz         t        j                  d|z   dz         t        j                  d|z   dz         gS )u9   workspace_root 기반 파일 경로 추출 패턴 생성.z\|\s*(z	/[^\s|]+)z-\s*(z/[^\s]+)z(?<!\w)(z/[^\s|)>`\]]+))reescapecompile)r   escapeds     I/home/jay/workspace/teams/dev4/qc/verifiers.bak/symbol_existence_check.py_build_file_path_patternsr      s]    ii'G


9w&56


8g%34


;(+<<=     z\bdef\s+(\w+)z\bfunction\s+(\w+)z\bclass\s+(\w+)z#(/home/jay/workspace/[^\s:]+):(\d+)uW   ^#{1,4}\s*(수정\s*파일|산출물|변경\s*파일|Modified\s*Files?|Output\s*Files?)task_idc                    t         j                  j                  |dd|  d      t         j                  j                  |dd|  d      g}|D ]%  }t         j                  j                  |      s#|c S  t         j                  j                  |dd      }t         j                  j	                  |      rRt        j
                  |      D ]:  }| |v s|j                  d      st         j                  j                  ||      c S  y)u:   task_id에 해당하는 보고서 파일 경로를 반환.memoryreportsz.mdz
_report.mdN)ospathjoinisfileisdirlistdirendswith)r   r   
candidatesr   reports_dirfnames         r   _find_reportr   *   s     	^XyWIS/J
^XyWIZ:PQJ  77>>$K '',,~xCK	ww}}[!ZZ, 	8E%ENN5$9ww||K77	8 r   /home/jay/workspacecontentc                    t               }t        t        j                  |             }|r| j	                  d      }d}g }|D ][  }t        j                  |      rd}|st        j
                  d|      rt        j                  |      s n|j                  |       ] dj                  |      }n| }t        |      }	|	D ]|  }
|
j                  |      D ]f  }|j                  d      j                         j                  d      }t        j                  j!                  |      d   dv sV|j#                  |       h ~ t%        |      |fS )uU   보고서에서 '수정 파일' 또는 '산출물' 섹션의 파일 경로를 추출.
FTz^#{1,4}\s+\S   z.,;:))z.pyz.jsz.tsz.jsxz.tsxz.yamlz.ymlz.jsonz.shz.rbz.go)setbool_SECTION_PATTERNsearchsplitmatchr   appendr   r   finditergroupstriprstripr   r   splitextaddsorted)r   r   fileshas_sectionlines
in_sectionsection_content_lineslinesection_contentfile_path_patternspatternr'   r   s                r   _extract_modified_filesr9   <   sA   EE '..w78Kd#
 " 	3D%%d+!
88OT2;K;Q;QRV;W%,,T2	3 ))$9: " 3>B%  %%o6 	 E;;q>'')009Dww%a( -  		$	   %=+%%r   c                 R   t               }t        j                  dt        j                        }|j	                  |       D ][  }|j                  d      }t        D ]?  }|j	                  |      D ])  }|j                  d      }|dvs|j                  |       + A ] t        |      S )uO   코드 블록(``` ... ```) 내에서 심볼(함수명, 클래스명)을 추출.z```[^\n]*\n(.*?)```r!   )selfclsNoneTrueFalsepassr   )	r"   r   r	   DOTALLr)   r*   _SYMBOL_PATTERNSr.   r/   )r   symbolscode_block_patternblock_match
block_textsym_pattern	sym_matchnames           r   !_extract_symbols_from_code_blocksrJ   g   s    eG $:BIIF)227; & &&q)
+ 	&K(11*= &	 q)YYKK%	&	&& '?r   c                     g }t         j                  |       D ]@  }|j                  d      }t        |j                  d            }|j	                  ||f       B |S )uG   보고서에서 '파일경로:라인번호' 형태의 참조를 추출.r!      )_FILE_LINE_PATTERNr)   r*   intr(   )r   refsr'   filepathlinenos        r   _extract_file_line_refsrR   y   sX    D#,,W5 (;;q>U[[^$Xv&'( Kr   rP   symbolc                 R   t         j                  j                  |       syd| d| d| d| d| g}	 |D ]K  }t        j                  dd|| gd	d	d
      }|j
                  dk(  s0|j                  j                         sK y	 	 y# t        j                  t        f$ r Y yw xY w)uR   파일에서 심볼(함수명, 클래스명)이 존재하는지 grep으로 확인.Fzdef zclass z	function z
async def zasync function grepz-nT
   )capture_outputtexttimeoutr   )
r   r   r   
subprocessrun
returncodestdoutr+   TimeoutExpiredOSError)rP   rS   patternspatresults        r   _symbol_exists_in_filerc      s    77>>(# vh

F8
VH
&"H 	C^^sH-#	F   A%&--*=*=*?	  %%w/ s#   1B
 *B
 B
 B
 
B&%B&c                    t        | |      }|
dd|  dgdS 	 t        |dd      5 }|j                         }ddd       t        |      \  }}|sddgdS |s
ddd| gdS t        |      }|sdddt        |       gdS d| dt        |       ddj                  |       g}	g }
g }|D ]v  }t        j                  j                  |      s|	j                  d|        7|D ];  }t        ||      }|r|j                  d| d|        )|
j                  ||f       = x g }|D ]O  }d}|D ]2  }t        j                  j                  |      s#t        ||      s0d} n |r?|j                  |       Q |r|D ]  }|	j                  |        |r!|D ]  }|	j                  d| d        d|	dS d|	dS # 1 sw Y   xY w# t        $ r)}dd	t	        |      j
                   d
| gdcY d}~S d}~ww xY w)u3  
    보고서에서 언급된 심볼(함수명, 클래스명)이 실제 파일에 존재하는지 검증합니다.

    Args:
        task_id: 검사 대상 task ID
        workspace_root: 워크스페이스 루트 경로

    Returns:
        {"status": "PASS"|"FAIL"|"SKIP"|"WARN", "details": [...]}
    NSKIPzReport not found for task_id=''statusdetailsrzutf-8)encodingzFailed to read report: z: uG   보고서에 '수정 파일' 또는 '산출물' 섹션이 없습니다.uY   보고서에 '수정 파일' 섹션은 있으나 추출된 파일 경로가 없습니다.zReport: ug   보고서 코드 블록에서 검증할 심볼(함수명/클래스명)을 추출하지 못했습니다.zModified files: zSymbols to check: z, zSKIP (file not found): zOK: z in FTz
MISSING: 'z ' not found in any modified fileFAILPASS)r   openreadr_   type__name__r9   rJ   lenr   r   r   r   r(   rc   )r   r   report_pathfr   emodified_filesr1   rC   ri   missingcheckedrP   rS   existstruly_missingfound_in_anyitemsyms                      r   verifyr~      s    w7K8	CD
 	


+sW5 	ffhG	 #:'>"RNKab
 	

 k;-(
 	
 08Gy"3~#6"78
 	
 ;- 
3~./0
TYYw/01G GG" 3ww~~h'NN4XJ?@ 	3F+Hf=FfXT(<= 12	33 M )& 	Hww~~h',B8V,T#	   ()  	!DNN4 	!   	OCNNZu,LMN	O W5511e	 	 
1$q'2B2B1C2aSIJ
 	

s3   G GG GG 	H G;5H ;H __main__rL   re   z;Usage: symbol_existence_check.py <task_id> [workspace_root]rg   F)ensure_asciiindentr!   )r   )#__doc__r   r   rZ   typingr   strlistr   r	   rB   rM   
IGNORECASE	MULTILINEr$   r   tupler9   rJ   rR   r#   rc   dictr~   rq   jsonsysrr   argvprintdumpsexit_task_id_workspace_rootrb    r   r   <module>r      s   
 	  c d  BJJ BJJ$%BJJ!"   RZZ FG  2::^MMBLL  # s x} $(&S (&# (&Z_ (&Vs t $S T S # $ <f2C f2 f2 f2R z
388}qDJJ!/l.mn"	
 	xx{H%(]Q%6chhqk<QOHo.F	*$**V%
:;# r   