X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/7217efbf26d7ec757ac72fdadf247a932e56244a..6e83f4d7c39b981146f57aad8049c5622799dd00:/stgit/utils.py diff --git a/stgit/utils.py b/stgit/utils.py index 5749b3b..68b8f58 100644 --- a/stgit/utils.py +++ b/stgit/utils.py @@ -1,6 +1,8 @@ """Common utility functions """ +import errno, os, os.path + __copyright__ = """ Copyright (C) 2005, Catalin Marinas @@ -18,6 +20,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ +def mkdir_file(filename, mode): + """Opens filename with the given mode, creating the directory it's + in if it doesn't already exist.""" + create_dirs(os.path.dirname(filename)) + return file(filename, mode) + def read_string(filename, multiline = False): """Reads the first line from a file """ @@ -32,7 +40,7 @@ def read_string(filename, multiline = False): def write_string(filename, line, multiline = False): """Writes 'line' to file and truncates it """ - f = file(filename, 'w+') + f = mkdir_file(filename, 'w+') if multiline: f.write(line) else: @@ -42,7 +50,7 @@ def write_string(filename, line, multiline = False): def append_strings(filename, lines): """Appends 'lines' sequence to file """ - f = file(filename, 'a+') + f = mkdir_file(filename, 'a+') for line in lines: print >> f, line f.close() @@ -50,14 +58,14 @@ def append_strings(filename, lines): def append_string(filename, line): """Appends 'line' to file """ - f = file(filename, 'a+') + f = mkdir_file(filename, 'a+') print >> f, line f.close() def insert_string(filename, line): """Inserts 'line' at the beginning of the file """ - f = file(filename, 'r+') + f = mkdir_file(filename, 'r+') lines = f.readlines() f.seek(0); f.truncate() print >> f, line @@ -67,4 +75,74 @@ def insert_string(filename, line): def create_empty_file(name): """Creates an empty file """ - file(name, 'w+').close() + mkdir_file(name, 'w+').close() + +def list_files_and_dirs(path): + """Return the sets of filenames and directory names in a + directory.""" + files, dirs = [], [] + for fd in os.listdir(path): + full_fd = os.path.join(path, fd) + if os.path.isfile(full_fd): + files.append(fd) + elif os.path.isdir(full_fd): + dirs.append(fd) + return files, dirs + +def walk_tree(basedir): + """Starting in the given directory, iterate through all its + subdirectories. For each subdirectory, yield the name of the + subdirectory (relative to the base directory), the list of + filenames in the subdirectory, and the list of directory names in + the subdirectory.""" + subdirs = [''] + while subdirs: + subdir = subdirs.pop() + files, dirs = list_files_and_dirs(os.path.join(basedir, subdir)) + for d in dirs: + subdirs.append(os.path.join(subdir, d)) + yield subdir, files, dirs + +def strip_prefix(prefix, string): + """Return string, without the prefix. Blow up if string doesn't + start with prefix.""" + assert string.startswith(prefix) + return string[len(prefix):] + +def remove_dirs(basedir, dirs): + """Starting at join(basedir, dirs), remove the directory if empty, + and try the same with its parent, until we find a nonempty + directory or reach basedir.""" + path = dirs + while path: + try: + os.rmdir(os.path.join(basedir, path)) + except OSError: + return # can't remove nonempty directory + path = os.path.dirname(path) + +def remove_file_and_dirs(basedir, file): + """Remove join(basedir, file), and then remove the directory it + was in if empty, and try the same with its parent, until we find a + nonempty directory or reach basedir.""" + os.remove(os.path.join(basedir, file)) + remove_dirs(basedir, os.path.dirname(file)) + +def create_dirs(directory): + """Create the given directory, if the path doesn't already exist.""" + if directory: + create_dirs(os.path.dirname(directory)) + try: + os.mkdir(directory) + except OSError, e: + if e.errno != errno.EEXIST: + raise e + +def rename(basedir, file1, file2): + """Rename join(basedir, file1) to join(basedir, file2), not + leaving any empty directories behind and creating any directories + necessary.""" + full_file2 = os.path.join(basedir, file2) + create_dirs(os.path.dirname(full_file2)) + os.rename(os.path.join(basedir, file1), full_file2) + remove_dirs(basedir, os.path.dirname(file1))