U
    ڲgX7                     @   s   d Z ddl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
mZ dgZeeZedejZed	ejejB Zejdd
 ZG dd deZdS )zu
Class representing the list of files in a distribution.

Equivalent to distutils.filelist, but fixes some problems.
    N   )DistlibException)fsdecodeconvert_pathManifestz\\w*
z#.*?(?=
)|
(?=$)   c                   @   sz   e Zd ZdZdddZdd Zdd Zd	d
 ZdddZdd Z	dd Z
dd ZdddZd ddZd!ddZdd ZdS )"r   z
    A list of files built by exploring the filesystem and filtered by applying various
    patterns to what we find there.
    Nc                 C   s>   t jt j|pt  | _| jt j | _d| _t	 | _
dS )zd
        Initialise an instance.

        :param base: The base directory to explore under.
        N)ospathabspathnormpathgetcwdbasesepprefixallfilessetfiles)selfr    r   4/tmp/pip-unpacked-wheel-mq592sfu/distlib/manifest.py__init__,   s    zManifest.__init__c                 C   s   ddl m}m}m} g  | _}| j}|g}|j}|j}|r| }t	|}	|	D ]R}
tj
||
}t |}|j}||r|t| qN||rN||sN|| qNq6dS )zmFind all files under the base and set ``allfiles`` to the absolute
        pathnames of files found.
        r   )S_ISREGS_ISDIRS_ISLNKN)statr   r   r   r   r   popappendr	   listdirr
   joinst_moder   )r   r   r   r   r   rootstackr   pushnamesnamefullnamer   moder   r   r   findall;   s"    


zManifest.findallc                 C   s4   | | jstj| j|}| jtj| dS )zz
        Add a file to the manifest.

        :param item: The pathname to add. This can be relative to the base.
        N)	
startswithr   r	   r
   r   r   r   addr   )r   itemr   r   r   r*   V   s    zManifest.addc                 C   s   |D ]}|  | qdS )z
        Add a list of files to the manifest.

        :param items: The pathnames to add. These can be relative to the base.
        N)r*   )r   itemsr+   r   r   r   add_many`   s    zManifest.add_manyFc                    sb    fdd t j}|rFt  }|D ]} |tj| q&||O }dd tdd |D D S )z8
        Return sorted files in directory order
        c                    sJ   |  | td| |jkrFtj|\}}|dks<t | | d S )Nzadd_dir added %s) /)r*   loggerdebugr   r	   r
   splitAssertionError)dirsdparent_add_dirr   r   r   r9   n   s    

z Manifest.sorted.<locals>.add_dirc                 S   s   g | ]}t jj| qS r   )r	   r
   r   ).0Z
path_tupler   r   r   
<listcomp>|   s     z#Manifest.sorted.<locals>.<listcomp>c                 s   s   | ]}t j|V  qd S )N)r	   r
   r2   )r:   r
   r   r   r   	<genexpr>}   s     z"Manifest.sorted.<locals>.<genexpr>)r   r   r	   r
   dirnamesorted)r   Zwantdirsresultr4   fr   r8   r   r>   i   s    
zManifest.sortedc                 C   s   t  | _g | _dS )zClear all collected files.N)r   r   r   )r   r   r   r   clear   s    zManifest.clearc                 C   sj  |  |\}}}}|dkrB|D ]}| j|ddstd| qn$|dkrf|D ]}| j|dd qNn |dkr|D ]}| j|ddsrtd| qrn|d	kr|D ]}| j|dd qn|d
kr|D ] }| j||dstd|| qn|dkr
|D ]}| j||d qn\|dkr2| jd|dsftd| n4|dkrZ| jd|dsftd| ntd| dS )av  
        Process a directive which either adds some files from ``allfiles`` to
        ``files``, or removes some files from ``files``.

        :param directive: The directive to process. This should be in a format
                     compatible with distutils ``MANIFEST.in`` files:

                     http://docs.python.org/distutils/sourcedist.html#commands
        includeT)anchorzno files found matching %rexcludeglobal-includeFz3no files found matching %r anywhere in distributionglobal-excluderecursive-include)r   z-no files found matching %r under directory %rrecursive-excludegraftNz no directories found matching %rprunez4no previously-included directories found matching %rzinvalid action %r)_parse_directive_include_patternr0   warning_exclude_patternr   )r   	directiveactionpatternsthedirZ
dirpatternpatternr   r   r   process_directive   sP     


zManifest.process_directivec                 C   s  |  }t|dkr,|d dkr,|dd |d }d } }}|dkrxt|dk r`td| d	d
 |dd D }n~|dkrt|dk rtd| t|d }dd
 |dd D }n:|dkrt|dkrtd| t|d }ntd| ||||fS )z
        Validate a directive.
        :param directive: The directive to validate.
        :return: A tuple of action, patterns, thedir, dir_patterns
        r   r   )rB   rD   rE   rF   rG   rH   rI   rJ   rB   N)rB   rD   rE   rF   r   z$%r expects <pattern1> <pattern2> ...c                 S   s   g | ]}t |qS r   r   r:   wordr   r   r   r;      s     z-Manifest._parse_directive.<locals>.<listcomp>)rG   rH      z*%r expects <dir> <pattern1> <pattern2> ...c                 S   s   g | ]}t |qS r   r   rU   r   r   r   r;      s     )rI   rJ   z!%r expects a single <dir_pattern>zunknown action %r)r2   leninsertr   r   )r   rO   wordsrP   rQ   rR   Zdir_patternr   r   r   rK      s4    zManifest._parse_directiveTc                 C   sP   d}|  ||||}| jdkr&|   | jD ]}||r,| j| d}q,|S )a  Select strings (presumably filenames) from 'self.files' that
        match 'pattern', a Unix-style wildcard (glob) pattern.

        Patterns are not quite the same as implemented by the 'fnmatch'
        module: '*' and '?'  match non-special characters, where "special"
        is platform-dependent: slash on Unix; colon, slash, and backslash on
        DOS/Windows; and colon on Mac OS.

        If 'anchor' is true (the default), then the pattern match is more
        stringent: "*.py" will match "foo.py" but not "foo/bar.py".  If
        'anchor' is false, both of these will match.

        If 'prefix' is supplied, then only filenames starting with 'prefix'
        (itself a pattern) and ending with 'pattern', with anything in between
        them, will match.  'anchor' is ignored in this case.

        If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and
        'pattern' is assumed to be either a string containing a regex or a
        regex object -- no translation is done, the regex is just compiled
        and used as-is.

        Selected strings will be added to self.files.

        Return True if files are found.
        FNT)_translate_patternr   r(   searchr   r*   )r   rS   rC   r   is_regexfound
pattern_rer%   r   r   r   rL      s    


zManifest._include_patternc                 C   sB   d}|  ||||}t| jD ]}||r| j| d}q|S )at  Remove strings (presumably filenames) from 'files' that match
        'pattern'.

        Other parameters are the same as for 'include_pattern()', above.
        The list 'self.files' is modified in place. Return True if files are
        found.

        This API is public to allow e.g. exclusion of SCM subdirs, e.g. when
        packaging source distributions
        FT)r[   listr   r\   remove)r   rS   rC   r   r]   r^   r_   r@   r   r   r   rN      s    
zManifest._exclude_patternc                 C   s  |rt |trt|S |S tdkr:| dd\}}}|rj| |}tdkrn||rd||snt	nd}t
tj| jd}	|dk	rftdkr| d}
| |dt|
  }n>| |}||r||st	|t|t|t|  }tj}tjdkrd}tdkr4d|	 ||d| f }n0|t|t|t|  }d	||	||||f }n8|rtdkrd|	 | }nd
||	|t|d f }t|S )a  Translate a shell-like wildcard pattern to a compiled regular
        expression.

        Return the compiled regex.  If 'is_regex' true,
        then 'pattern' is directly compiled to a regex (if it's a string)
        or just returned as-is (assumes it's a regex object).
        )rW   r   r7   r.   N\z\\^z.*z%s%s%s%s.*%s%sz%s%s%s)
isinstancestrrecompile_PYTHON_VERSION_glob_to_re	partitionr)   endswithr3   escaper	   r
   r   r   rX   r   )r   rS   rC   r   r]   startr7   endr_   r   Zempty_patternZ	prefix_rer   r   r   r   r[   4  sH    	








 
zManifest._translate_patternc                 C   s8   t |}tj}tjdkrd}d| }td||}|S )zTranslate a shell-like glob pattern to a regular expression.

        Return a string containing the regex.  Differs from
        'fnmatch.translate()' in that '*' does not match "special characters"
        (which are platform-specific).
        rb   z\\\\z\1[^%s]z((?<!\\)(\\\\)*)\.)fnmatch	translater	   r   rf   sub)r   rS   r_   r   escapedr   r   r   ri   k  s    

zManifest._glob_to_re)N)F)TNF)TNF)TNF)__name__
__module____qualname____doc__r   r(   r*   r-   r>   rA   rT   rK   rL   rN   r[   ri   r   r   r   r   r   &   s&   

	
D/  
)  
  
7)rv   ro   loggingr	   rf   sysr.   r   compatr   utilr   __all__	getLoggerrs   r0   rg   MZ_COLLAPSE_PATTERNSZ_COMMENTED_LINEversion_inforh   objectr   r   r   r   r   <module>   s   
