From 6a9b580132b6e82c9505a9f0f8b855a3b8d282ff Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 25 Feb 2010 05:15:09 +0000 Subject: Move cacheddir and listdir to portage.util.listdir. svn path=/main/trunk/; revision=15450 --- pym/portage/util/listdir.py | 153 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 pym/portage/util/listdir.py (limited to 'pym/portage/util/listdir.py') diff --git a/pym/portage/util/listdir.py b/pym/portage/util/listdir.py new file mode 100644 index 000000000..82705acc9 --- /dev/null +++ b/pym/portage/util/listdir.py @@ -0,0 +1,153 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +__all__ = ['cacheddir', 'listdir'] + +import errno +import stat +import time + +from portage import os +from portage.exception import DirectoryNotFound, PermissionDenied, PortageException +from portage.util import normalize_path, writemsg + +dircache = {} +cacheHit = 0 +cacheMiss = 0 +cacheStale = 0 + +def cacheddir(my_original_path, ignorecvs, ignorelist, EmptyOnError, followSymlinks=True): + global cacheHit,cacheMiss,cacheStale + mypath = normalize_path(my_original_path) + if mypath in dircache: + cacheHit += 1 + cached_mtime, list, ftype = dircache[mypath] + else: + cacheMiss += 1 + cached_mtime, list, ftype = -1, [], [] + try: + pathstat = os.stat(mypath) + if stat.S_ISDIR(pathstat[stat.ST_MODE]): + mtime = pathstat.st_mtime + else: + raise DirectoryNotFound(mypath) + except EnvironmentError as e: + if e.errno == PermissionDenied.errno: + raise PermissionDenied(mypath) + del e + return [], [] + except PortageException: + return [], [] + # Python retuns mtime in seconds, so if it was changed in the last few seconds, it could be invalid + if mtime != cached_mtime or time.time() - mtime < 4: + if mypath in dircache: + cacheStale += 1 + try: + list = os.listdir(mypath) + except EnvironmentError as e: + if e.errno != errno.EACCES: + raise + del e + raise PermissionDenied(mypath) + ftype = [] + for x in list: + try: + if followSymlinks: + pathstat = os.stat(mypath+"/"+x) + else: + pathstat = os.lstat(mypath+"/"+x) + + if stat.S_ISREG(pathstat[stat.ST_MODE]): + ftype.append(0) + elif stat.S_ISDIR(pathstat[stat.ST_MODE]): + ftype.append(1) + elif stat.S_ISLNK(pathstat[stat.ST_MODE]): + ftype.append(2) + else: + ftype.append(3) + except (IOError, OSError): + ftype.append(3) + dircache[mypath] = mtime, list, ftype + + ret_list = [] + ret_ftype = [] + for x in range(0, len(list)): + if list[x] in ignorelist: + pass + elif ignorecvs: + if list[x][:2] != ".#": + ret_list.append(list[x]) + ret_ftype.append(ftype[x]) + else: + ret_list.append(list[x]) + ret_ftype.append(ftype[x]) + + writemsg("cacheddirStats: H:%d/M:%d/S:%d\n" % (cacheHit, cacheMiss, cacheStale),10) + return ret_list, ret_ftype + +_ignorecvs_dirs = ('CVS', 'SCCS', '.svn', '.git') + +def listdir(mypath, recursive=False, filesonly=False, ignorecvs=False, ignorelist=[], followSymlinks=True, + EmptyOnError=False, dirsonly=False): + """ + Portage-specific implementation of os.listdir + + @param mypath: Path whose contents you wish to list + @type mypath: String + @param recursive: Recursively scan directories contained within mypath + @type recursive: Boolean + @param filesonly; Only return files, not more directories + @type filesonly: Boolean + @param ignorecvs: Ignore CVS directories ('CVS','SCCS','.svn','.git') + @type ignorecvs: Boolean + @param ignorelist: List of filenames/directories to exclude + @type ignorelist: List + @param followSymlinks: Follow Symlink'd files and directories + @type followSymlinks: Boolean + @param EmptyOnError: Return [] if an error occurs (deprecated, always True) + @type EmptyOnError: Boolean + @param dirsonly: Only return directories. + @type dirsonly: Boolean + @rtype: List + @returns: A list of files and directories (or just files or just directories) or an empty list. + """ + + list, ftype = cacheddir(mypath, ignorecvs, ignorelist, EmptyOnError, followSymlinks) + + if list is None: + list=[] + if ftype is None: + ftype=[] + + if not (filesonly or dirsonly or recursive): + return list + + if recursive: + x=0 + while x