summaryrefslogtreecommitdiff
path: root/morphlib/bins.py
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2011-11-03 17:35:46 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2011-11-03 17:35:46 +0000
commit21d333fbff93aeeb086ba05a52c26c56e9d99dc9 (patch)
tree25ab1890b06b7debad9c721aa6cbbee060d671ea /morphlib/bins.py
parent222fcd9945e127d15282cd628e2e956500783213 (diff)
downloadmorph-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.py57
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.