X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/41a6d8591d5962dbfe8e372fff10c60e06718083..681f805ef4688c7ea450f5e72a15dad818809734:/stgit/utils.py diff --git a/stgit/utils.py b/stgit/utils.py index 9465fe0..67431ec 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,45 +20,135 @@ 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 """ f = file(filename, 'r') if multiline: - string = f.read() + result = f.read() else: - string = f.readline().strip() + result = f.readline().strip() f.close() - return string + return result -def write_string(filename, string, multiline = False): - """Writes string to file and truncates it +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(string) + f.write(line) else: - print >> f, string + print >> f, line f.close() -def append_string(filename, string): - """Appends string to file +def append_strings(filename, lines): + """Appends 'lines' sequence to file """ - f = file(filename, 'a+') - print >> f, string + f = mkdir_file(filename, 'a+') + for line in lines: + print >> f, line f.close() -def insert_string(filename, string): - """Inserts a string at the beginning of the file +def append_string(filename, line): + """Appends 'line' to file """ - f = file(filename, 'r+') + f = mkdir_file(filename, 'a+') + print >> f, line + f.close() + +def insert_string(filename, line): + """Inserts 'line' at the beginning of the file + """ + f = mkdir_file(filename, 'r+') lines = f.readlines() f.seek(0); f.truncate() - print >> f, string + print >> f, line f.writelines(lines) f.close() 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 strip_suffix(suffix, string): + """Return string, without the suffix. Blow up if string doesn't + end with suffix.""" + assert string.endswith(suffix) + return string[:-len(suffix)] + +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 and not os.path.isdir(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))