def collect(self, src, recurse=1, empties=1, exclude_globs=()): """Use files in src as the content of the Inno script. The script will use every file in that directory, and (by default) its subdirectories. You can call this more than once to collect several directories. @param src: stuff to package @param recurse: Whether to descend subdirectories @param empties: Whether to keep empty directories in the package @param exclude_globs: list of patterns relative to src which will be packaged (dirs or files) @type exclude_globs: iterable """ self._base = psrc = path(src) assert psrc.isdir() def filtername(pth): for pat in exclude_globs: if pth.fnmatch(pat): return 0 return 1 all_dirs = list(psrc.walkdirs()) filtered_dirs = [d for d in all_dirs if filtername(d)] for d in [psrc] + filtered_dirs: all = d.files() filtered = [f for f in all if filtername(f)] self.sources.extend(filtered) if empties and len(filtered) == 0: self.sources.append(d)
def do_add(self, glob): """grab all files (not subdirectories) in this dir matching the glob """ hits = matches(self.cwd, glob, self.exclusions) [hits.remove(x) for x in hits[:] if path(x[1]).isdir()] self._update(OrderedDict(hits))
def __init__(self, replacements={}, *args, **kwargs): cmd.Cmd.__init__(self, *args, **kwargs) self.replacements = replacements self.exclusions = [] self.replaceDuplicates = 0 self.data = OrderedDict() self.cwd = path('.')
def do_diradd(self, glob): """add directories matching this glob (not its contents - use for empty dirs) """ hits = [] for m in matches(self.cwd, glob, self.exclusions): hits.append((m[0] + os.sep, m[1])) [hits.remove(x) for x in hits[:] if path(x[1]).isfile()] self._update(OrderedDict(hits))
def matches(curdir, glob, xglobs=()): """Return the entries that match glob and do not match any xglob""" old = os.getcwd() os.chdir(curdir) try: # sanity check.. make sure glob uses os.sep if glob in ('', None): glob = '*' glob = path(glob).normpath() components = str(glob).split(os.sep) return gatherHits('.', components, xglobs) finally: os.chdir(old)
def distutilsData(fmscript, replaceDuplicates=0, prefix=''): """Return a list of items compatible with distutils' datafiles setup arg: [(dirname, (source_items_in_dirname)), ...] prefix is prepended to each dirname so you can control where they go after installation. (Does not take care of fixing distutils' brain-dead handling of data files. See Google for recipes to fix that. :-) """ items = sourceItems(fmscript, replaceDuplicates) thedirs = {} for i in items: thedirs.setdefault(str(path(i).dirname()), []).append(i) return thedirs.items()
def gatherHits(curdir, components, xglobs=()): if len(components)==0: return [] gathered = OrderedDict() add = lambda d,s: gathered.__setitem__(str(d), str(s)) here = path(curdir) comp = path(components.pop(0)) # the rule is: # 1. normal globs match files or dirs in the current directory # 2. ** recursive globs match any dir in the subtree including '.' # 3. unless there are no components left to process, in which case # treat as a normal glob. if len(components)==0: matcher = here.listdir else: if str(comp)=='**': matcher = lambda g: chain((here,), here.walkdirs(g)) else: matcher = here.dirs xrelist = [] # list of regular expressions for matching excluded files for xg in xglobs: cre = re.compile(fnmatch.translate(xg)) xrelist.append(cre) for f in matcher(comp): excluded = 0 # filter with xglobs for xg, xg_re in zip(xglobs, xrelist): if re.match(xg_re, f) or f.fnmatch(xg): excluded = 1 break if not excluded: add(f, f.abspath()) if f.isdir(): for d, s in gatherHits(f, components[:], xglobs): add(d,s) return gathered.items()
def sibpath(file1, name): return path(file1).dirname()/path(name)