#! /usr/bin/python # -*- coding: utf-8 -*- # # Copyright 2016 Red Hat, Inc. # License: GPLv2 # Author: Dan HorĂ¡k # # get list of all packages required to build this rpm, recursively # # 1. take binary rpm # 2. get package name and build NVR (build id) from binary rpm # 3. if package name not in builroot list yet, then add # else return back # 4. list buildroot content # 5. do 1. for all rpms in the buildroot # 6. return back # # TODO: # - move the looking for the latest build for package outside of analyze() # and use dictionary to cache the info => less API calls # - switch to analyzing a copy of the koji database directly from using koji API call import argparse import koji # get the list of rpm to analyze from command line parser = argparse.ArgumentParser() parser.add_argument("rpm", nargs="+", help="rpm(s) to analyze") args = parser.parse_args() KOJIHUB = 'http://koji.stg.fedoraproject.org/kojihub' tag = 'f24' latest = True session = koji.ClientSession(KOJIHUB) buildroot = [] rpminfos = {} def analyze(rpm): print("rpm=%s" % (rpm)) # cache the mapping between rpms and packages, resp. the whole build infos # this can save 2 API calls per rpm if rpm in rpminfos: binfo = rpminfos[rpm] else: rinfo = session.getRPM(rpm) binfo = session.getBuild(rinfo['build_id']) rpminfos[rpm] = binfo pkg = binfo['package_name'] if pkg in buildroot: # already included, skipping further analysis return print("processing %s" % (pkg)) buildroot.append(pkg) # we may want to inspect only the buildroot of the latest build for # a particular package, otherwise we would go into the very beginnings # (F-7) and analyzed long time obsoleted builds if latest is True: builds = session.getLatestBuilds(tag, package=pkg) if len(builds) > 0: binfo = builds[0] else: print("ERROR: no builds") return print("latest is %s" % (binfo['nvr'])) if binfo['task_id'] is None: print("ERROR: no task associated, imported maybe?") return tasks = session.getTaskChildren(binfo['task_id']) for t in tasks: # inspect only "same arch" or noarch buildroots if (t['method'] == 'buildArch') and (t['arch'] in ['noarch', rinfo['arch']]): b = session.listBuildroots(taskID=t['id']) if len(b) > 1: print("ERROR: too many buildroots") # hm, maybe we should rather continue, because there is a buildroot return bl = session.getBuildrootListing(b[0]['id']) for bli in bl: nvr = "%s-%s-%s.%s" % (bli['name'], bli['version'], bli['release'], bli['arch']) analyze(nvr) for r in args.rpm: analyze(r) print(buildroot)