1*4882a593Smuzhiyun# Copyright (C) 2010-2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 2*4882a593Smuzhiyun# Copyright (C) 2019 Yann E. MORIN <yann.morin.1998@free.fr> 3*4882a593Smuzhiyun 4*4882a593Smuzhiyunimport json 5*4882a593Smuzhiyunimport logging 6*4882a593Smuzhiyunimport os 7*4882a593Smuzhiyunimport subprocess 8*4882a593Smuzhiyunfrom collections import defaultdict 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun# This function returns a tuple of four dictionaries, all using package 12*4882a593Smuzhiyun# names as keys: 13*4882a593Smuzhiyun# - a dictionary which values are the lists of packages that are the 14*4882a593Smuzhiyun# dependencies of the package used as key; 15*4882a593Smuzhiyun# - a dictionary which values are the lists of packages that are the 16*4882a593Smuzhiyun# reverse dependencies of the package used as key; 17*4882a593Smuzhiyun# - a dictionary which values are the type of the package used as key; 18*4882a593Smuzhiyun# - a dictionary which values are the version of the package used as key, 19*4882a593Smuzhiyun# 'virtual' for a virtual package, or the empty string for a rootfs. 20*4882a593Smuzhiyundef get_dependency_tree(): 21*4882a593Smuzhiyun logging.info("Getting dependency tree...") 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun deps = {} 24*4882a593Smuzhiyun rdeps = defaultdict(list) 25*4882a593Smuzhiyun types = {} 26*4882a593Smuzhiyun versions = {} 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun # Special case for the 'all' top-level fake package 29*4882a593Smuzhiyun deps['all'] = [] 30*4882a593Smuzhiyun types['all'] = 'target' 31*4882a593Smuzhiyun versions['all'] = '' 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun cmd = ["make", "-s", "--no-print-directory", "show-info"] 34*4882a593Smuzhiyun with open(os.devnull, 'wb') as devnull: 35*4882a593Smuzhiyun p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=devnull, 36*4882a593Smuzhiyun universal_newlines=True) 37*4882a593Smuzhiyun pkg_list = json.loads(p.communicate()[0]) 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun for pkg in pkg_list: 40*4882a593Smuzhiyun deps['all'].append(pkg) 41*4882a593Smuzhiyun types[pkg] = pkg_list[pkg]["type"] 42*4882a593Smuzhiyun deps[pkg] = pkg_list[pkg].get("dependencies", []) 43*4882a593Smuzhiyun for p in deps[pkg]: 44*4882a593Smuzhiyun rdeps[p].append(pkg) 45*4882a593Smuzhiyun versions[pkg] = \ 46*4882a593Smuzhiyun None if pkg_list[pkg]["type"] == "rootfs" \ 47*4882a593Smuzhiyun else "virtual" if pkg_list[pkg]["virtual"] \ 48*4882a593Smuzhiyun else pkg_list[pkg]["version"] 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun return (deps, rdeps, types, versions) 51