build/pymake/pymake/globrelative.py
author Benjamin Smedberg <benjamin@smedbergs.us>
Wed, 18 May 2011 09:05:24 -0400
changeset 69670 f5ac9367f1e15ca931afebc8b986e32ad11fc21d
parent 38959 c80eb5209859aff20b7ff598a56ccc74740abcc9
child 94475 f4157e8c410708d76703f19e4dfb61859bfe32d8
permissions -rw-r--r--
Bug 644626 - Move plugin tests from modules/plugin/test to dom/plugin/test, r=ted

"""
Filename globbing like the python glob module with minor differences:

* glob relative to an arbitrary directory
* include . and ..
* check that link targets exist, not just links
"""

import os, re, fnmatch
import util

_globcheck = re.compile('[[*?]')

def hasglob(p):
    return _globcheck.search(p) is not None

def glob(fsdir, path):
    """
    Yield paths matching the path glob. Sorts as a bonus. Excludes '.' and '..'
    """

    dir, leaf = os.path.split(path)
    if dir == '':
        return globpattern(fsdir, leaf)

    if hasglob(dir):
        dirsfound = glob(fsdir, dir)
    else:
        dirsfound = [dir]

    r = []

    for dir in dirsfound:
        fspath = util.normaljoin(fsdir, dir)
        if not os.path.isdir(fspath):
            continue

        r.extend((util.normaljoin(dir, found) for found in globpattern(fspath, leaf)))

    return r

def globpattern(dir, pattern):
    """
    Return leaf names in the specified directory which match the pattern.
    """

    if not hasglob(pattern):
        if pattern == '':
            if os.path.isdir(dir):
                return ['']
            return []

        if os.path.exists(util.normaljoin(dir, pattern)):
            return [pattern]
        return []

    leaves = os.listdir(dir) + ['.', '..']

    # "hidden" filenames are a bit special
    if not pattern.startswith('.'):
        leaves = [leaf for leaf in leaves
                  if not leaf.startswith('.')]

    leaves = fnmatch.filter(leaves, pattern)
    leaves = filter(lambda l: os.path.exists(util.normaljoin(dir, l)), leaves)

    leaves.sort()
    return leaves