]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/filewriter.py
Remove files that are (no longer) generated
[dak.git] / daklib / filewriter.py
index 2f080e681b8cc050a0f73f1c317c72e921329db4..6f5da4f0d8314c5aeecc0c5a216b7b37f9b6db23 100644 (file)
@@ -29,8 +29,24 @@ from daklib.config import Config
 
 from daklib.daksubprocess import check_call
 
+import errno
 import os, os.path
 
+class CompressionMethod(object):
+    def __init__(self, keyword, extension, command):
+        self.keyword = keyword
+        self.extension = extension
+        self.command = command
+
+_compression_methods = (
+    CompressionMethod('bzip2', '.bz2', ['bzip2', '-9']),
+    CompressionMethod('gzip', '.gz', ['gzip', '-9cn', '--rsyncable']),
+    CompressionMethod('xz', '.xz', ['xz', '-c']),
+    # 'none' must be the last compression method as BaseFileWriter
+    # handling it will remove the input file for other compressions
+    CompressionMethod('none', '', None),
+)
+
 class BaseFileWriter(object):
     '''
     Base class for compressed and uncompressed file writing.
@@ -43,11 +59,7 @@ class BaseFileWriter(object):
         include strings for suite, component, architecture and booleans
         uncompressed, gzip, bzip2.
         '''
-        compression = keywords.get('compression', ['none'])
-        self.uncompressed = 'none' in compression
-        self.gzip = 'gzip' in compression
-        self.bzip2 = 'bzip2' in compression
-        self.xz = 'xz' in compression
+        self.compression = keywords.get('compression', ['none'])
         self.path = template % keywords
 
     def open(self):
@@ -65,26 +77,34 @@ class BaseFileWriter(object):
     # internal helper function
     def rename(self, filename):
         tempfilename = filename + '.new'
-        os.chmod(tempfilename, 0o664)
+        os.chmod(tempfilename, 0o644)
         os.rename(tempfilename, filename)
 
+    # internal helper function to compress output
+    def compress(self, cmd, suffix, path):
+        in_filename = "{0}.new".format(path)
+        out_filename = "{0}{1}.new".format(path, suffix)
+        if cmd is not None:
+            with open(in_filename, 'r') as in_fh, open(out_filename, 'w') as out_fh:
+                check_call(cmd, stdin=in_fh, stdout=out_fh)
+        self.rename("{0}{1}".format(path, suffix))
+
     def close(self):
         '''
         Closes the file object and does the compression and rename work.
         '''
         self.file.close()
-        if self.gzip:
-            check_call('gzip -9cn --rsyncable <%s.new >%s.gz.new' % (self.path, self.path),
-                shell = True)
-            self.rename('%s.gz' % self.path)
-        if self.bzip2:
-            check_call('bzip2 -9 <%s.new >%s.bz2.new' % (self.path, self.path), shell = True)
-            self.rename('%s.bz2' % self.path)
-        if self.xz:
-            check_call('xz -c <{0}.new >{0}.xz.new'.format(self.path), shell=True)
-            self.rename('{0}.xz'.format(self.path))
-        if self.uncompressed:
-            self.rename(self.path)
+        for method in _compression_methods:
+            if method.keyword in self.compression:
+                self.compress(method.command, method.extension, self.path)
+            else:
+                # Try removing the file that would be generated.
+                # It's not an error if it does not exist.
+                try:
+                    os.unlink("{0}{1}".format(self.path, method.extension))
+                except OSError as e:
+                    if e.errno != errno.ENOENT:
+                        raise
         else:
             os.unlink(self.path + '.new')
 
@@ -125,7 +145,7 @@ class PackagesFileWriter(BaseFileWriter):
         are strings.  Output files are gzip compressed only.
         '''
         flags = {
-            'compression': ['gzip', 'bzip2'],
+            'compression': ['gzip', 'xz'],
         }
         flags.update(keywords)
         if flags['debtype'] == 'deb':
@@ -141,7 +161,7 @@ class SourcesFileWriter(BaseFileWriter):
         files are gzip compressed only.
         '''
         flags = {
-            'compression': ['gzip', 'bzip2'],
+            'compression': ['gzip', 'xz'],
         }
         flags.update(keywords)
         template = "%(archive)s/dists/%(suite)s/%(component)s/source/Sources"