
    -              	       *   S r SSKrSSKrSSKJrJrJrJrJ	r	J
r
Jr  \	(       a  SSKJr  SSKJrJr  S\S\4S jrS	\S\4S
 jrS\S\\   4S jrSS\S\S\S\4S jjr " S S\5      r " S S\5      r " S S\5      rS\S\4S jr " S S\5      rg)zhParsing of gitignore files.

For details for the matching rules, see https://git-scm.com/docs/gitignore
    N)BinaryIOIterableListOptionalTYPE_CHECKINGDictUnion)Repo)get_xdg_config_home_pathConfigsegmentreturnc                 L   U S:X  a  gSnS[        U 5      p2X#:  Ga  XUS-    nUS-   nUS:X  a  US-  nOUS:X  a  US-  nOUS	:X  a  UnXS:  a  XUS-    S
:X  a  US-   nXS:  a  XUS-    S:X  a  US-   nXS:  a"  XUS-    S:w  a  US-   nXS:  a  XUS-    S:w  a  M  XS:  a  US-  nOxXU R                  SS5      nUS-   nUR                  S
5      (       a	  SUSS  -   nOUR                  S5      (       a  SU-   nUS	U-   S-   -  nOU[        R                  " U5      -  nX#:  a  GM  U$ )N   *s   [^/]+    r      s   [^/]*   ?s   [^/]   [   !   ]s   \[   \s   \\   ^)lenreplace
startswithreescape)r   resincjstuffs          !lib/third_party/dulwich/ignore.py_translate_segmentr%   +   sp   $
Cc'lq
%AE98OC$Y7NC$YAuQU+t3EuQU+t3E%GA.$6E %GA.$6vv!,,UG<E##D)) 59,E%%d++!EMEte|d**299Q<C5 %6 Jr   patc                    SnSU SS ;  a  US-  nU R                  S5      (       a
  U SS n US-  nU R                  S5      (       a  U SS n [        U R                  S5      5       H>  u  p#US	:X  a  US
-  nM  XS:  a  [        R                  " S5      OS[        U5      -   -  nM@     U R                  S5      (       d  US-  nUS-   $ )zTranslate a shell PATTERN to a regular expression.

There is no way to quote meta-characters.

Originally copied from fnmatch in Python 2.7, but modified for Dulwich
to cope with features in Git ignore patterns.
s   (?ms)   /Ns   (.*/)?s   **/   r   s   **s   (/.*)?r   r   s   /?s   \Z)r   	enumeratesplitr   r   r%   endswith)r&   r   r   r   s       r$   	translater.   N   s     C3s8y
~~f!"gy
~~d!"g		$0
e9C1uBIIdO#9KG9TTTC 1 <<u<r   fc              #   l  #    U  H  nUR                  S5      nU(       d  M  UR                  S5      (       a  M5  UR                  S5      (       aI  UR                  S5      (       d3  USS nUR                  S5      (       a  UR                  S5      (       d  M3  UR                  SS5      nUv   M     g7f)z\Read a git ignore file.

Args:
  f: File-like object to read from
Returns: List of patterns
s   
   #    s   \ Nr)   )rstripr   r-   r   )r/   lines     r$   read_ignore_patternsr5   r   s      {{7# ??4   mmD!!$--*?*?9D mmD!!$--*?*?||FD)
! s   BB4B4pathpattern
ignorecasec                 6    [        X5      R                  U 5      $ )zMatch a gitignore-style pattern against a path.

Args:
  path: Path to match
  pattern: Pattern to match
  ignorecase: Whether to do case-sensitive matching
Returns:
  bool indicating whether the pattern matched
)Patternmatch)r6   r7   r8   s      r$   match_patternr<      s     7'--d33r   c                   |    \ rS rSrSrSS\S\4S jjrS\4S jrS\	4S jr
S	\S\4S
 jrS\	4S jrS\S\4S jrSrg)r:      zA single ignore pattern.r7   r8   c                    Xl         X l        USS S:X  a  SU l        USS  nOUSS S:X  a  USS  nSU l        SnU R                  (       a  [        R                  n[        R
                  " [        U5      U5      U l        g )Nr   r   r   Fr   T)r7   r8   
is_excluder   
IGNORECASEcompiler.   _re)selfr7   r8   flagss       r$   __init__Pattern.__init__   sx    $1Q<4#DOabkGq|u$!!"+"DO??MME::i0%8r   r   c                     U R                   $ N)r7   rD   s    r$   	__bytes__Pattern.__bytes__   s    ||r   c                 B    [         R                  " U R                  5      $ rI   )osfsdecoder7   rJ   s    r$   __str__Pattern.__str__   s    {{4<<((r   otherc                     [        U[        U 5      5      =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ rI   )
isinstancetyper7   r8   )rD   rR   s     r$   __eq__Pattern.__eq__   sA    ud4j) 4-45#3#33	
r   c                 l    [        U 5      R                  < SU R                  < SU R                  < S3$ N(z, ))rU   __name__r7   r8   rJ   s    r$   __repr__Pattern.__repr__   s'    JLLOO
 	
r   r6   c                 J    [        U R                  R                  U5      5      $ )z}Try to match a path against this ignore pattern.

Args:
  path: Path to match (relative to ignore location)
Returns: boolean
)boolrC   r;   rD   r6   s     r$   r;   Pattern.match   s     DHHNN4())r   )rC   r8   r@   r7   NF)r\   
__module____qualname____firstlineno____doc__bytesr`   rF   rK   strrP   objectrV   r]   r;   __static_attributes__ r   r$   r:   r:      sb    "9 94 95 ) )
F 
t 

# 
*% *D *r   r:   c                       \ rS rSrSS\\   S\4S jjrS\SS4S jrS	\	\\
4   S\\   4S
 jrS	\S\\   4S jr\SS\SS 4S jj5       rS\
4S jrSrg)IgnoreFilter   Npatternsr8   c                 ^    / U l         X l        X0l        U H  nU R                  U5        M     g rI   )	_patterns_ignorecase_pathappend_pattern)rD   rp   r8   r6   r7   s        r$   rF   IgnoreFilter.__init__   s,    %
G(  r   r7   r   c                 `    U R                   R                  [        XR                  5      5        g)zAdd a pattern to the set.N)rr   appendr:   rs   )rD   r7   s     r$   ru   IgnoreFilter.append_pattern   s    gg/?/?@Ar   r6   c              #      #    [        U[        5      (       d  [        R                  " U5      nU R                   H  nUR                  U5      (       d  M  Uv   M!     g7f)zfYield all matching patterns for path.

Args:
  path: Path to match
Returns:
  Iterator over iterators
N)rT   rh   rN   fsencoderr   r;   )rD   r6   r7   s      r$   find_matchingIgnoreFilter.find_matching   sD      $&&;;t$D~~G}}T"" &s   AA	Ac                 R    SnU R                  U5       H  nUR                  nM     U$ )zCheck whether a path is ignored.

For directories, include a trailing slash.

Returns: status is None if file is not mentioned, True if it is
    included, False if it is explicitly excluded.
N)r|   r@   )rD   r6   statusr7   s       r$   
is_ignoredIgnoreFilter.is_ignored   s.     ))$/G''F 0r   c                 p    [        US5       nU " [        U5      X!S9sS S S 5        $ ! , (       d  f       g = f)Nrb)r6   )openr5   )clsr6   r8   r/   s       r$   	from_pathIgnoreFilter.from_path   s*    $+A.
F s   '
5c                     [        U SS 5      nUb  [        U 5      R                  < SU< S3$ S[        U 5      R                  -  $ )Nrt   z.from_path(r[   z<%s>)getattrrU   r\   ra   s     r$   r]   IgnoreFilter.__repr__   s@    tWd+)-d)<)<dCCT$Z0011r   )rs   rt   rr   )FNrc   )r\   rd   re   rf   r   rh   r`   rF   ru   r	   ri   r:   r|   r   r   classmethodr   r]   rk   rl   r   r$   rn   rn      s    )% )d )Be B B%s
"3 8I u $  G G. G G2# 2r   rn   c                   6    \ rS rSrSrS rS\S\\   4S jr	Sr
g)	IgnoreFilterStack   z,Check for ignore status in multiple filters.c                     Xl         g rI   _filters)rD   filterss     r$   rF   IgnoreFilterStack.__init__  s    r   r6   r   c                 `    SnU R                    H  nUR                  U5      nUc  M  Us  $    U$ )Check whether a path is explicitly included or excluded in ignores.

Args:
  path: Path to check
Returns:
  None if the file is not mentioned, True if it is included,
  False if it is explicitly excluded.
N)r   r   )rD   r6   r   filters       r$   r   IgnoreFilterStack.is_ignored  s9     mmF&&t,F! $ r   r   N)r\   rd   re   rf   rg   rF   ri   r   r`   r   rk   rl   r   r$   r   r      s!    6 s x~ r   r   configc                 `     U R                  SS5      $ ! [         a     Of = f[        SS5      $ )zqReturn default user ignore filter path.

Args:
  config: A Config object
Returns:
  Path to a global ignore file
)   cores   excludesFilegitignore)getKeyErrorr   )r   s    r$   default_user_ignore_filter_pathr     s9    zz*o66  $E844s    
!!c                       \ rS rSrSrS\S\\   S\4S jr	S\4S jr
S	\S\\   4S
 jrS	\S\\   4S jrS	\S\\   4S jr\SS j5       rSrg)IgnoreFilterManageri%  zIgnore file manager.top_pathglobal_filtersr8   c                 6    0 U l         Xl        X l        X0l        g rI   )_path_filters	_top_path_global_filtersrs   )rD   r   r   r8   s       r$   rF   IgnoreFilterManager.__init__(  s      !-%r   r   c                     [        U 5      R                  < SU R                  < SU R                  < SU R                  < S3$ rY   )rU   r\   r   r   rs   rJ   s    r$   r]   IgnoreFilterManager.__repr__3  s2    JNN  	
 	
r   r6   c                 P    U R                   U   $ ! [         a     Of = f[        R                  R	                  U R
                  US5      n [        R                  X R                  5      U R                   U'   O! [         a    S U R                   U'    Of = fU R                   U   $ )Nz
.gitignore)
r   r   rN   r6   joinr   rn   r   rs   IOError)rD   r6   ps      r$   
_load_pathIgnoreFilterManager._load_path;  s    	%%d++ 		 GGLL|<	,'3'='=aAQAQ'RDt$ 	,'+Dt$	,!!$''s    
,A: :BBc                    [         R                  R                  U5      (       a  [        SU-  5      eU R                   Vs/ s H  nSU4PM	     nn[         R                  R
                  S:w  a*  UR                  [         R                  R
                  S5      nUR                  S5      n/ n[        [        U5      S-   5       H  nSR                  USU 5      nU HI  u  pSR                  XHU 5      n	U[        U5      :  a  U	S-  n	U[        UR                  U	5      5      -  nMK     U R                  U5      n
U
c  M|  UR                  SXj45        M     [        U5      $ s  snf )ziFind matching patterns for path.

Args:
  path: Path to check
Returns:
  Iterator over Pattern instances
z%s is an absolute pathr   /r   N)rN   r6   isabs
ValueErrorr   sepr   r,   ranger   r   listr|   r   insertiter)rD   r6   r/   r   partsmatchesr   dirnamesrelpathignore_filters              r$   r|   !IgnoreFilterManager.find_matchingH  s1    77==5<==#'#7#78#7aAq6#7877;;#<<S1D

3s5zA~&AhhuRay)G((51:.s5z> sNG4 899   !OOG4M(q1"45 ' G}# 9s   E!c                 d    [        U R                  U5      5      nU(       a  US   R                  $ g)r   r)   N)r   r|   r@   )rD   r6   r   s      r$   r   IgnoreFilterManager.is_ignorede  s/     t))$/02;)))r   c                    / n[         R                  R                  UR                  5       SS5      [	        UR                  5       5      4 HE  n UR                  [        R                  [         R                  R                  U5      5      5        MG     UR                  5       nUR                  SSS5      nU " UR                  X%5      $ ! [         a     M  f = f)z{Create a IgnoreFilterManager from a repository.

Args:
  repo: Repository object
Returns:
  A `IgnoreFilterManager` object
infoexcluder   s
   ignorecaseF)rN   r6   r   
controldirr   get_config_stackrx   rn   r   
expanduserr   get_boolean)r   repor   r   r   r8   s         r$   	from_repoIgnoreFilterManager.from_repos  s     GGLL*FI>+D,A,A,CD
A%%l&<&<RWW=O=OPQ=R&ST
 &&(''MEJ
499n99	  s   AC


CC)r   rs   r   r   N)r   r
   r   r   )r\   rd   re   rf   rg   ri   r   rn   r`   rF   r]   r   r   r   r:   r|   r   r   r   rk   rl   r   r$   r   r   %  s    	&	& \*	& 		&
# 
(s (x'= (# (7*; :s x~  : :r   r   rc   )rg   os.pathrN   r   typingr   r   r   r   r   r   r	   dulwich.repor
   dulwich.configr   r   rh   r%   r.   r5   r`   r<   rj   r:   rn   r   ri   r   r   rl   r   r$   <module>r      s   (
  	   ! ;   %  F!5 !U !HH % 6
4 
4 
44 
4D 
4-*f -*`126 12h .5F 5s 5 b:& b:r   