def cycle_check(self, project, repository, arch):
        self.logger.info('cycle check: start %s/%s/%s' %
                         (project, repository, arch))
        comment = []

        depinfo = builddepinfo(self.api.apiurl,
                               project,
                               repository,
                               arch,
                               order=False)
        for cycle in depinfo.findall('cycle'):
            for package in cycle.findall('package'):
                package = package.text
                allowed = False
                for acycle in self.allowed_cycles:
                    if package in acycle:
                        allowed = True
                        break
                if not allowed:
                    cycled = [p.text for p in cycle.findall('package')]
                    comment.append('Package {} appears in cycle {}'.format(
                        package, '/'.join(cycled)))

        if len(comment):
            # New cycles, post comment.
            self.logger.info('cycle check: failed')
            return CheckResult(False, '\n'.join(comment) + '\n')

        self.logger.info('cycle check: passed')
        return CheckResult(True, None)
    def fill_pkgdeps(self, prj, repo, arch):
        root = builddepinfo(self.api.apiurl,  prj, repo, arch)

        for package in root.findall('package'):
            # use main package name for multibuild. We can't just ignore
            # multibuild as eg installation-images has no results for the main
            # package itself
            # https://github.com/openSUSE/open-build-service/issues/4198
            name = package.attrib['name'].split(':')[0]
            if name.startswith('preinstall'):
                continue

            self.sources.add(name)

            for subpkg in package.findall('subpkg'):
                subpkg = subpkg.text
                if subpkg in self.bin2src:
                    if self.bin2src[subpkg] == name:
                        # different archs
                        continue
                    print('# Binary {} is defined twice: {}/{}'.format(subpkg, prj, name))
                self.bin2src[subpkg] = name

        for package in root.findall('package'):
            name = package.attrib['name'].split(':')[0]
            for pkg in package.findall('pkgdep'):
                if pkg.text not in self.bin2src:
                    if not pkg.text.startswith('texlive-'): # XXX: texlive bullshit packaging
                        print('Package {} not found in place'.format(pkg.text))
                    continue
                b = self.bin2src[pkg.text]
                self.pkgdeps[b] = name
    def fill_pkgdeps(self, prj, repo, arch):
        root = builddepinfo(self.api.apiurl, prj, repo, arch)

        for package in root.findall('package'):
            # use main package name for multibuild. We can't just ignore
            # multibuild as eg installation-images has no results for the main
            # package itself
            # https://github.com/openSUSE/open-build-service/issues/4198
            name = package.attrib['name'].split(':')[0]
            if name.startswith('preinstall'):
                continue

            self.sources.add(name)

            for subpkg in package.findall('subpkg'):
                subpkg = subpkg.text
                if subpkg in self.bin2src:
                    if self.bin2src[subpkg] == name:
                        # different archs
                        continue
                    print('# Binary {} is defined twice: {}/{}'.format(
                        subpkg, prj, name))
                self.bin2src[subpkg] = name

        for package in root.findall('package'):
            name = package.attrib['name'].split(':')[0]
            for pkg in package.findall('pkgdep'):
                if pkg.text not in self.bin2src:
                    if not pkg.text.startswith(
                            'texlive-'):  # XXX: texlive bullshit packaging
                        print('Package {} not found in place'.format(pkg.text))
                    continue
                b = self.bin2src[pkg.text]
                self.pkgdeps[b] = name
    def cycle_check(self, project, repository, arch, cycle_packages):
        self.logger.info('cycle check: start %s/%s/%s' % (project, repository, arch))
        comment = []

        allowed_cycles = []
        if cycle_packages:
            for comma_list in cycle_packages.split(';'):
                allowed_cycles.append(comma_list.split(','))

        depinfo = builddepinfo(self.apiurl, project, repository, arch, order = False)
        for cycle in depinfo.findall('cycle'):
            for package in cycle.findall('package'):
                package = package.text
                allowed = False
                for acycle in allowed_cycles:
                    if package in acycle:
                        allowed = True
                        break
                if not allowed:
                    cycled = [p.text for p in cycle.findall('package')]
                    comment.append('Package {} appears in cycle {}'.format(package, '/'.join(cycled)))

        if len(comment):
            # New cycles, post comment.
            self.logger.info('cycle check: failed')
            return CheckResult(False, '\n'.join(comment) + '\n')

        self.logger.info('cycle check: passed')
        return CheckResult(True, None)