diff options
author | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2011-11-03 17:35:46 +0000 |
---|---|---|
committer | Lars Wirzenius <lars.wirzenius@codethink.co.uk> | 2011-11-03 17:35:46 +0000 |
commit | 21d333fbff93aeeb086ba05a52c26c56e9d99dc9 (patch) | |
tree | 25ab1890b06b7debad9c721aa6cbbee060d671ea /morphlib/bins.py | |
parent | 222fcd9945e127d15282cd628e2e956500783213 (diff) | |
download | morph-21d333fbff93aeeb086ba05a52c26c56e9d99dc9.tar.gz |
Include only files matching regexps, removes them from after adding them
Diffstat (limited to 'morphlib/bins.py')
-rw-r--r-- | morphlib/bins.py | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/morphlib/bins.py b/morphlib/bins.py index ed2ac555..993ae3ad 100644 --- a/morphlib/bins.py +++ b/morphlib/bins.py @@ -22,18 +22,67 @@ Binaries are chunks, strata, and system images. import logging +import os +import re import tarfile import morphlib -def create_chunk(rootdir, chunk_filename, globs): - '''Create a chunk from the contents of a directory.''' - logging.debug('Creating chunk file %s from %s' % (chunk_filename, rootdir)) +def create_chunk(rootdir, chunk_filename, regexps): + '''Create a chunk from the contents of a directory. + + Only files and directories that match at least one of the regular + expressions are accepted. The regular expressions are implicitly + anchored to the beginning of the string, but not the end. The + filenames are relative to rootdir. + + ''' + + def mkrel(filename): + assert filename.startswith(rootdir) + if filename == rootdir: + return '.' + assert filename.startswith(rootdir + '/') + return filename[len(rootdir + '/'):] + + def matches(filename): + return any(x.match(filename) for x in compiled) + + def names_to_root(filename): + yield filename + while filename != rootdir: + filename = os.path.dirname(filename) + yield filename + + logging.debug('Creating chunk file %s from %s with regexps %s' % + (chunk_filename, rootdir, regexps)) + + compiled = [re.compile(x) for x in regexps] + include = set() + for dirname, subdirs, basenames in os.walk(rootdir): + if matches(dirname): + include.add(dirname) + filenames = [os.path.join(dirname, x) for x in basenames] + for filename in filenames: + if matches(mkrel(filename)): + for name in names_to_root(filename): + include.add(name) + + include = sorted(include) + tar = tarfile.open(name=chunk_filename, mode='w:gz') - tar.add(rootdir, arcname='.') + for filename in include: + tar.add(filename, arcname=mkrel(filename), recursive=False) tar.close() + include.remove(rootdir) + for filename in reversed(include): + if os.path.isdir(filename): + os.rmdir(filename) + else: + os.remove(filename) + def unpack_chunk(chunk_filename, dirname): '''Unpack a chunk into a directory. |