X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=daklib%2Fchecks.py;h=63b56da6c0b3c4f771f8070d58e53db4e10d81b4;hb=4156593e3095380f647b68c420b90b1ef8943f77;hp=d05c71fdaf66a51ac2fded6123702d7786a57724;hpb=d066a0848f6c48e0e49d826b5edcf025e5f88957;p=dak.git diff --git a/daklib/checks.py b/daklib/checks.py index d05c71fd..63b56da6 100644 --- a/daklib/checks.py +++ b/daklib/checks.py @@ -20,14 +20,14 @@ """module provided pre-acceptance tests -Please read the documentation for the `Check` class for the interface. +Please read the documentation for the L{Check} class for the interface. """ from daklib.config import Config -from .dbconn import * +from daklib.dbconn import * import daklib.dbconn as dbconn -from .regexes import * -from .textutils import fix_maintainer, ParseMaintError +from daklib.regexes import * +from daklib.textutils import fix_maintainer, ParseMaintError import daklib.lintian as lintian import daklib.utils as utils @@ -48,37 +48,37 @@ class Reject(Exception): class Check(object): """base class for checks - checks are called by daklib.archive.ArchiveUpload. Failing tests should - raise a `daklib.checks.Reject` exception including a human-readable + checks are called by L{daklib.archive.ArchiveUpload}. Failing tests should + raise a L{daklib.checks.Reject} exception including a human-readable description why the upload should be rejected. """ def check(self, upload): """do checks - Args: - upload (daklib.archive.ArchiveUpload): upload to check + @type upload: L{daklib.archive.ArchiveUpload} + @param upload: upload to check - Raises: - daklib.checks.Reject + @raise daklib.checks.Reject: upload should be rejected """ raise NotImplemented def per_suite_check(self, upload, suite): """do per-suite checks - Args: - upload (daklib.archive.ArchiveUpload): upload to check - suite (daklib.dbconn.Suite): suite to check + @type upload: L{daklib.archive.ArchiveUpload} + @param upload: upload to check - Raises: - daklib.checks.Reject + @type suite: L{daklib.dbconn.Suite} + @param suite: suite to check + + @raise daklib.checks.Reject: upload should be rejected """ raise NotImplemented @property def forcable(self): """allow to force ignore failing test - True if it is acceptable to force ignoring a failing test, - False otherwise + C{True} if it is acceptable to force ignoring a failing test, + C{False} otherwise """ return False @@ -338,7 +338,11 @@ class SourceCheck(Check): except Exception as e: raise Reject('{0}: APT could not parse {1} field: {2}'.format(dsc_fn, field, e)) - # TODO: check all expected files for given source format are included + rejects = utils.check_dsc_files(dsc_fn, control, source.files.keys()) + if len(rejects) > 0: + raise Reject("\n".join(rejects)) + + return True class SingleDistributionCheck(Check): """Check that the .changes targets only a single distribution.""" @@ -457,6 +461,73 @@ class UploadBlockCheck(Check): return True +class TransitionCheck(Check): + """check for a transition""" + def check(self, upload): + if 'source' not in upload.changes.architectures: + return True + + transitions = self.get_transitions() + if transitions is None: + return True + + control = upload.changes.changes + source = re_field_source.match(control['Source']).group('package') + + for trans in transitions: + t = transitions[trans] + source = t["source"] + expected = t["new"] + + # Will be None if nothing is in testing. + current = get_source_in_suite(source, "testing", session) + if current is not None: + compare = apt_pkg.version_compare(current.version, expected) + + if current is None or compare < 0: + # This is still valid, the current version in testing is older than + # the new version we wait for, or there is none in testing yet + + # Check if the source we look at is affected by this. + if source in t['packages']: + # The source is affected, lets reject it. + + rejectmsg = "{0}: part of the {1} transition.\n\n".format(source, trans) + + if current is not None: + currentlymsg = "at version {0}".format(current.version) + else: + currentlymsg = "not present in testing" + + rejectmsg += "Transition description: {0}\n\n".format(t["reason"]) + + rejectmsg += "\n".join(textwrap.wrap("""Your package +is part of a testing transition designed to get {0} migrated (it is +currently {1}, we need version {2}). This transition is managed by the +Release Team, and {3} is the Release-Team member responsible for it. +Please mail debian-release@lists.debian.org or contact {3} directly if you +need further assistance. You might want to upload to experimental until this +transition is done.""".format(source, currentlymsg, expected,t["rm"]))) + + raise Reject(rejectmsg) + + return True + + def get_transitions(self): + cnf = Config() + path = cnf.get('Dinstall::ReleaseTransitions', '') + if path == '' or not os.path.exists(path): + return None + + contents = file(path, 'r').read() + try: + transitions = yaml.load(contents) + return transitions + except yaml.YAMLError as msg: + utils.warn('Not checking transitions, the transitions file is broken: {0}'.format(msg)) + + return None + class NoSourceOnlyCheck(Check): """Check for source-only upload