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 cs>|j|tjd||jkr:tjj|\}}||dS)Nzadd_dir added %s)r)loggerdebugr rr split)dirsdparent_)add_dirrrrr4ls    z Manifest.sorted..add_dircSsg|]}tjj|qSr)rr r).0Z path_tuplerrr zsz#Manifest.sorted..css|]}tjj|VqdS)N)rr r/)r5r rrr {sz"Manifest.sorted..)rrrr dirnamesorted)rZwantdirsresultr0fr)r4rrr9gs  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=r?global-includeglobal-excluderecursive-includerecursive-excluder@rANrz$%r expects ...cSsg|] }t|qSr)r)r5wordrrrr6sz-Manifest._parse_directive..z*%r expects ...cSsg|] }t|qSr)r)r5rPrrrr6sz!%r expects a single zunknown action %r)r=r?rLrMrNrOr@rA)r=r?rLrM)rNrO)r@rA)r/leninsertrr)rrEZwordsrFrGrHZ dir_patternrrrrBs:           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))rrIr>ris_regexrJ pattern_rer$rrrrCs    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)rTlistrrUremove)rrIr>rrVrJrWr;rrrrD)s   zManifest._exclude_patternc Csv|rt|trtj|S|Std kr:|jdjd\}}}|rR|j|}td krVnd}tjtj j |j d} |dk r4tdkr|jd} |j|dt |  } n&|j|} | t |t | t |} tj } tj dkrd} tdkrd| | j | d |f}n0|t |t |t |}d || | | ||f}n8|rltdkrRd| |}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). rQrr3N\z\\^z.*z%s%s%s%s.*%s%sz%s%s%s)rQr)rQr)rQr)rQr)rQr) isinstancestrrecompile_PYTHON_VERSION _glob_to_re partitionescaperr rr rRr) rrIr>rrVstartr3endrWr Z empty_patternZ prefix_rerrrrrT=s@             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