简体   繁体   中英

How to search upwards through directories? Can I os.walk upwards to the root of the filesystem?

I am trying to search for a specific directory, starting from a given directory but going upwards, rather than down as in os.walk. For example, this function returns whether or not the given directory is the root of an Alire project - which just means it contains alire/*.toml:

''' Check if this directory contains a 'alire/*.toml' file '''
def is_alire_root(dir):
    dir = dir / "alire"
    if dir.is_dir():
        for x in dir.iterdir():
            if x.suffixes == [".toml"]:
                return True
        return False
    else:
        return False

So, given such a predicate that tells us whether we have found the directory we need, how would I search upwards from a given path, so that eg

os_walk_upwards(os.path.abspath("."), is_alire_root)

Will tell us if the current directory or any directories above it contain alire/*.toml? Although os_walk_upwards could be used for various searches, I am specifically looking for something that will work as a plugin in Gnatstudio .

For python version >= 3.4 we can use pathlib :

import os.path
from pathlib import Path

def is_alire_root(dir):
    (... as above ...)

''' Search upwards from path for a directory matching the predicate '''
def os_walk_upwards(directory_predicate, path=Path(os.path.abspath("."))):
    if directory_predicate(path):
        return True
    else:
        parent = path.parent
        if parent == path:
            return False  # reached root of filesystem
        return directory_predicate(parent)

print(os_walk_upwards(is_alire_root))

But Gnatstudio uses python 2.7.16, so that isn't going to work. Instead, use:

import os.path

''' Check if this directory contains a 'alire/*.toml' file '''
def is_alire_root(dir):
    dir = os.path.join(dir, "alire")
    if os.path.isdir(dir):
        for x in os.listdir(dir):
            if os.path.splitext(x)[1] == ".toml":  # will also match e.g. *.tar.gz.toml
                return True
        return False
    else:
        return False

''' Check if this or any parent directories are alire_root directories '''
def os_walk_upwards(directory_predicate, path=os.path.abspath(".")):
    if directory_predicate(path):
        return True
    else:
        parent = os.path.dirname(path)
        if parent == path:
            return False  # reached root of filesystem
        return directory_predicate(parent)

print(os_walk_upwards(is_alire_root))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM