
                             S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSrSr	 " S S	\
5      r " S
 S\5      rS rS rS r " S S\5      rg)a  Library for ignoring files for upload.

This library very closely mimics the semantics of Git's gitignore file:
https://git-scm.com/docs/gitignore

See `gcloud topic gcloudignore` for details.

A typical use would be:

  file_chooser = gcloudignore.GetFileChooserForDir(upload_directory)
  for f in file_chooser.GetIncludedFiles('some/path'):
    print 'uploading {}'.format(f)
    # actually do the upload, too
    )absolute_import)division)unicode_literalsN/z(?<!\\)\\(\\\\)*$c                       \ rS rSrSrSrg)InternalParserError*   z*An internal error in gcloudignore parsing. N__name__
__module____qualname____firstlineno____doc____static_attributes__r
       +lib/googlecloudsdk/command_lib/util/glob.pyr   r   *   s    2r   r   c                       \ rS rSrSrSrg)InvalidLineError.   z<Error indicating that a line of the ignore file was invalid.r
   Nr   r
   r   r   r   r   .   s    Dr   r   c                 *    S nS nU" U" U 5      5      $ )zHandles spaces in a line.

In particular, deals with trailing spaces (which are stripped unless
escaped) and escaped spaces throughout the line (which are unescaped).

Args:
  line: str, the line

Returns:
  str, the line with spaces handled
c                    / nSnU[        U 5      :  at  X   nUS:X  aC  US-   [        U 5      :  a  UR                  U5        OFUR                  X0US-      -   5        US-  nOUR                  U5        US-  nU[        U 5      :  a  Mt  / nSn[        U5       H%  nU(       a  US:X  a  M  SnUR                  U5        M'     SR                  [        U5      5      $ )	z!Strips unescaped trailing spaces.r   \      T F )lenappendreversedjoin)linetokensicurrresonly_seen_spacess         r   _Rstrip_HandleSpaces.<locals>._Rstrip>   s     F	A
c$i-Wd	q5CI
--

d!A#Y&'	Qd	Q c$i- C 	dck	jj	 ! 778C=!!r   c                 &    U R                  SS5      $ )zUnescapes all spaces in a line.z\ r   )replacer"   s    r   _UnescapeSpaces&_HandleSpaces.<locals>._UnescapeSpaces[   s    <<s##r   r
   )r"   r(   r-   s      r   _HandleSpacesr/   2   s    ":$ 
	''r   c                 R    [         R                  " SSU 5      R                  SS5      $ )zUnescapes a line.

The escape character is '\'. An escaped backslash turns into one backslash;
any other escaped character is ignored.

Args:
  line: str, the line to unescape

Returns:
  str, the unescaped line

z	\\([^\\])z\1z\\r   )resubr+   r,   s    r   	_Unescaper3   b   s$     
eT	*	2	264	@@r   c                     U /nSnU (       aJ  U(       aC  [         R                  R                  U 5      u  pUR                  SU 5        U (       a	  U(       a  MC  U$ )zReturns all prefixes for the given path, inclusive.

That is, for 'foo/bar/baz', returns ['', 'foo', 'foo/bar', 'foo/bar/baz'].

Args:
  path: str, the path for which to get prefixes.

Returns:
  list of str, the prefixes.
Tr   )ospathsplitinsert)r6   path_prefixespath_reminders      r   GetPathPrefixesr;   r   sM     &-- 	''---DD! 	 
r   c                   B    \ rS rSrSrS	S jrS rS	S jr\S 5       r	Sr
g)
Glob   zA file-matching glob pattern.

See https://git-scm.com/docs/gitignore for full syntax specification.

Attributes:
  pattern: str, a globbing pattern.
  must_be_dir: bool, true if only dirs match.
c                     Xl         X l        g N)patternmust_be_dir)selfrA   rB   s      r   __init__Glob.__init__   s    L"r   c                   ^ ^ U(       d  gUc  gUS   nUSS mU(       a  [         R                  R                  U5      n[         R                  R                  U5      u  pEU(       d  SnUS:X  aC  [	        U5      nT(       a	  TS   S:X  d  TR                  SS5        [        UU 4S jU 5       5      $ US	:X  a  T(       d  U(       a  [        U5      S
:  a  g[        R                  " XS5      (       d  gT R                  TU5      $ )a2  Determines whether the given pattern matches the given path.

Args:
  pattern_parts: list of str, the list of pattern parts that must all match
    the path.
  path: str, the path to match.

Returns:
  bool, whether the patch matches the pattern_parts (Matches() will convert
    this into a Match value).
TNFz**r   r   c              3   H   >#    U  H  nTR                  TU5      v   M     g 7fr@   )_MatchesHelper).0prefixremaining_patternrC   s     r   	<genexpr>&Glob._MatchesHelper.<locals>.<genexpr>   s+      #! EK$$%6??!s   "*r   )
r5   r6   normpathr7   r;   r8   anyr   fnmatchrI   )rC   pattern_partsr6   pattern_partremaining_path	path_partr9   rL   s   `      @r   rI   Glob._MatchesHelper   s     |  $L%cr*WWd#d "d 3Nnt &d+m  $5a$8B$>  B' #!# # # s#4
 
C/!3??933 0.AAr   c                     U R                   (       a  U(       d  gU R                  U R                  R                  S5      U5      (       a  gg)z4Returns a Match for this pattern and the given path.Fr   T)rB   rI   rA   r7   )rC   r6   is_dirs      r   MatchesGlob.Matches   s8    4<<--c2D99r   c                 0   UR                  S5      (       a  USS nSnOSn[        U5      n[        R                  " [        U5      (       a  [        SR                  U5      5      e[        U5      nU(       d  [        SR                  U5      5      eU " XS9$ )	a  Creates a pattern for an individual line of an ignore file.

Windows-style newlines must be removed.

Args:
  line: str, The line to parse.

Returns:
  Pattern.

Raises:
  InvalidLineError: if the line was invalid (comment, blank, contains
    invalid consecutive stars).
r   NrG   TFz(Line [{}] ends in an odd number of [\]s.zLine [{}] is blank.)rB   )endswithr/   r1   search_ENDS_IN_ODD_NUMBER_SLASHES_REr   formatr3   )clsr"   rB   s      r   
FromStringGlob.FromString   s      }}S#2YdkkD	yy/66
5
<
<T
BD DT?D299$?@@t--r   )rB   rA   N)F)r   r   r   r   r   rD   rI   rZ   classmethodrb   r   r
   r   r   r=   r=      s-    #ABF . .r   r=   )r   
__future__r   r   r   rR   r5   r1   _GCLOUDIGNORE_PATH_SEPr_   	Exceptionr   r   r/   r3   r;   objectr=   r
   r   r   <module>ri      sd    '  '  	 	 !5 3) 3E* E-(`A *v.6 v.r   