]> git.donarmstrong.com Git - dak.git/blobdiff - daklib/checks.py
HashedFile: Raise FileDoesNotExist if referring to a non-existing file
[dak.git] / daklib / checks.py
index ccf7feb4e9e61b4510a32d0d8c17b07f487dc251..c7c4a16f23f03c8b482df3f1ee07792f74008764 100644 (file)
@@ -31,7 +31,7 @@ from daklib.regexes import *
 from daklib.textutils import fix_maintainer, ParseMaintError
 import daklib.lintian as lintian
 import daklib.utils as utils
-from daklib.upload import InvalidHashException
+import daklib.upload
 
 import apt_inst
 import apt_pkg
@@ -109,6 +109,16 @@ class Check(object):
         return False
 
 class SignatureAndHashesCheck(Check):
+    def check_replay(self, upload):
+        # Use private session as we want to remember having seen the .changes
+        # in all cases.
+        session = upload.session
+        history = SignatureHistory.from_signed_file(upload.changes)
+        r = history.query(session)
+        if r is not None:
+            raise Reject('Signature for changes file was already seen at {0}.\nPlease refresh the signature of the changes file if you want to upload it again.'.format(r.seen))
+        return True
+
     """Check signature of changes and dsc file (if included in upload)
 
     Make sure the signature is valid and done by a known user.
@@ -117,6 +127,7 @@ class SignatureAndHashesCheck(Check):
         changes = upload.changes
         if not changes.valid_signature:
             raise Reject("Signature for .changes not valid.")
+        self.check_replay(upload)
         self._check_hashes(upload, changes.filename, changes.files.itervalues())
 
         source = None
@@ -149,13 +160,11 @@ class SignatureAndHashesCheck(Check):
         try:
             for f in files:
                 f.check(upload.directory)
-        except IOError as e:
-            if e.errno == errno.ENOENT:
-                raise Reject('{0} refers to non-existing file: {1}\n'
-                             'Perhaps you need to include it in your upload?'
-                             .format(filename, os.path.basename(e.filename)))
-            raise
-        except InvalidHashException as e:
+        except daklib.upload.FileDoesNotExist as e:
+            raise Reject('{0}: {1}\n'
+                         'Perhaps you need to include the file in your upload?'
+                         .format(filename, unicode(e)))
+        except daklib.upload.UploadException as e:
             raise Reject('{0}: {1}'.format(filename, unicode(e)))
 
 class ChangesCheck(Check):
@@ -612,17 +621,52 @@ transition is done.""".format(transition_source, currentlymsg, expected,t["rm"])
         return None
 
 class NoSourceOnlyCheck(Check):
+    def is_source_only_upload(self, upload):
+        changes = upload.changes
+        if changes.source is not None and len(changes.binaries) == 0:
+            return True
+        return False
+
     """Check for source-only upload
 
     Source-only uploads are only allowed if Dinstall::AllowSourceOnlyUploads is
     set. Otherwise they are rejected.
+
+    Source-only uploads are only accepted for source packages having a
+    Package-List field that also lists architectures per package. This
+    check can be disabled via
+    Dinstall::AllowSourceOnlyUploadsWithoutPackageList.
+
+    Source-only uploads to NEW are only allowed if
+    Dinstall::AllowSourceOnlyNew is set.
+
+    Uploads not including architecture-independent packages are only
+    allowed if Dinstall::AllowNoArchIndepUploads is set.
+
     """
     def check(self, upload):
-        if Config().find_b("Dinstall::AllowSourceOnlyUploads"):
+        if not self.is_source_only_upload(upload):
             return True
+
+        allow_source_only_uploads = Config().find_b('Dinstall::AllowSourceOnlyUploads')
+        allow_source_only_uploads_without_package_list = Config().find_b('Dinstall::AllowSourceOnlyUploadsWithoutPackageList')
+        allow_source_only_new = Config().find_b('Dinstall::AllowSourceOnlyNew')
+        allow_no_arch_indep_uploads = Config().find_b('Dinstall::AllowNoArchIndepUploads')
         changes = upload.changes
-        if changes.source is not None and len(changes.binaries) == 0:
+
+        if not allow_source_only_uploads:
             raise Reject('Source-only uploads are not allowed.')
+        if not allow_source_only_uploads_without_package_list \
+           and changes.source.package_list.fallback:
+            raise Reject('Source-only uploads are only allowed if a Package-List field that also list architectures is included in the source package. dpkg (>= 1.17.7) includes this information.')
+        if not allow_source_only_new and upload.new:
+            raise Reject('Source-only uploads to NEW are not allowed.')
+
+        if not allow_no_arch_indep_uploads \
+           and 'all' not in changes.architectures \
+           and changes.source.package_list.has_arch_indep_packages():
+            raise Reject('Uploads not including architecture-independent packages are not allowed.')
+
         return True
 
 class LintianCheck(Check):