3 Pf9@sdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z dgZ ej eZejdejZejd ejejBZejdd ZGd ddeZdS) zu Class representing the list of files in a distribution. Equivalent to distutils.filelist, but fixes some problems. N)DistlibException)fsdecode) convert_pathManifestz\\w* z#.*?(?= )| (?=$)c@szeZdZdZdddZddZddZd d Zdd d ZddZ ddZ ddZ dddZ d ddZ d!ddZddZdS)"rz~A list of files built by on exploring the filesystem and filtered by applying various patterns to what we find there. NcCs>tjjtjj|ptj|_|jtj|_d|_t |_ dS)zd Initialise an instance. :param base: The base directory to explore under. N) ospathabspathnormpathgetcwdbasesepprefixallfilessetfiles)selfr r/usr/lib/python3.6/manifest.py__init__*szManifest.__init__cCsddlm}m}m}g|_}|j}|g}|j}|j}xv|r|}tj |} x\| D]T} tj j || } tj| } | j } || r|jt | qR|| rR||  rR|| qRWq8WdS)zmFind all files under the base and set ``allfiles`` to the absolute pathnames of files found. r)S_ISREGS_ISDIRS_ISLNKN)statrrrrr popappendrlistdirr joinst_moder)rrrrrrootstackrpushnamesnamefullnamermoderrrfindall9s"    zManifest.findallcCs4|j|jstjj|j|}|jjtjj|dS)zz Add a file to the manifest. :param item: The pathname to add. This can be relative to the base. N) startswithrrr rr raddr )ritemrrrr)Ts z Manifest.addcCsx|D]}|j|qWdS)z Add a list of files to the manifest. :param items: The pathnames to add. These can be relative to the base. N)r))ritemsr*rrradd_many^s zManifest.add_manyFcsffddtj}|rJt}x|D]}|tjj|q(W||O}ddtdd|DDS)z8 Return sorted files in directory order csJ|j|tjd||jkrFtjj|\}}|dks.add_dircSsg|]}tjj|qSr)rr r).0Z path_tuplerrr zsz#Manifest.sorted..css|]}tjj|VqdS)N)rr r1)r8r rrr {sz"Manifest.sorted..)rrrr dirnamesorted)rZwantdirsresultr3fr)r7rrr<gs  zManifest.sortedcCst|_g|_dS)zClear all collected files.N)rrr)rrrrclear}szManifest.clearcCs|j|\}}}}|dkrFx&|D]}|j|dds tjd|q Wn<|dkrnx|D]}|j|dd}qTWn|dkrx&|D]}|j|dds|tjd|q|Wn|d krx|D]}|j|dd}qWn|d krx|D] }|j||d stjd ||qWn|d kr&xz|D]}|j||d }q Wn\|dkrN|jd|d stjd|n4|dkrv|jd|d stjd|n td|dS)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)anchorzno files found matching %rexcludezglobal-includeFz3no files found matching %r anywhere in distributionzglobal-excludezrecursive-include)rz-no files found matching %r under directory %rzrecursive-excludegraftNz no directories found matching %rprunez4no previously-included directories found matching %rzinvalid action %r)_parse_directive_include_patternr/Zwarning_exclude_patternr)r directiveactionpatternsthedirZ dirpatternpatternfoundrrrprocess_directivesD           zManifest.process_directivec Cs|j}t|dkr,|ddkr,|jdd|d}d }}}|dkrxt|d kr`td |dd|dd D}n|dkrt|dkrtd|t|d}dd|d d D}n<|dkrt|d krtd|t|d}n td|||||fS)z Validate a directive. :param directive: The directive to validate. :return: A tuple of action, patterns, thedir, dir_patterns rrr@rBglobal-includeglobal-excluderecursive-includerecursive-excluderCrDNrz$%r expects ...cSsg|] }t|qSr)r)r8wordrrrr9sz-Manifest._parse_directive..z*%r expects ...cSsg|] }t|qSr)r)r8rSrrrr9sz!%r expects a single zunknown action %r)r@rBrOrPrQrRrCrD)r@rBrOrP)rQrR)rCrD)r1leninsertrr)rrHZwordsrIrJrKZ dir_patternrrrrEs:           zManifest._parse_directiveTcCsTd}|j||||}|jdkr&|jx(|jD]}|j|r.|jj|d}q.W|S)aSelect 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_patternrr'searchrr))rrLrAris_regexrM pattern_rer$rrrrFs    zManifest._include_patterncCsFd}|j||||}x,t|jD]}|j|r |jj|d}q W|S)atRemove 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)rWlistrrXremove)rrLrArrYrMrZr>rrrrG)s   zManifest._exclude_patternc Cs|rt|trtj|S|Std kr:|jdjd\}}}|rj|j|}td krn|j|rd|j|snt nd}tj t j j |jd} |dk rftdkr|jd} |j|dt|  } n>|j|} | j|r| j|st | t|t| t|} t j} t jdkrd} tdkr4d| | j | d |f}n0|t|t|t|}d || | | ||f}n8|rtdkrd| |}nd || |t|df}tj|S)aTranslate 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). rTrr6r-N\z\\^z.*z%s%s%s%s.*%s%sz%s%s%s)rTr)rTr)rTr)rTr)rTr) isinstancestrrecompile_PYTHON_VERSION _glob_to_re partitionr(endswithr2escaperr rr rUr) rrLrArrYstartr6endrZr Z empty_patternZ prefix_rerrrrrW=sB             zManifest._translate_patterncCs8tj|}tj}tjdkrd}d|}tjd||}|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). r]z\\\\z\1[^%s]z((? s