blob: 572afc6a1f623645cee77e5f987ed26d667df9dd [file] [log] [blame]
Mike Frysinger9f7e4ee2013-03-13 15:43:03 -04001#!/usr/bin/python
Jim Hebert91c052c2011-03-11 11:00:53 -08002# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import json
7import portage
8import sys
9from parallel_emerge import DepGraphGenerator
10
David James1b363582012-12-17 11:53:11 -080011def FlattenDepTree(deptree, pkgtable=None, parentcpv=None):
Jim Hebert91c052c2011-03-11 11:00:53 -080012 """
13 Turn something like this (the parallel_emerge DepsTree format):
14{
15 "app-admin/eselect-1.2.9": {
16 "action": "merge",
17 "deps": {
18 "sys-apps/coreutils-7.5-r1": {
19 "action": "merge",
20 "deps": {},
21 "deptype": "runtime"
22 },
23 ...
24 }
25 }
26}
27 ...into something like this (the cros_extract_deps format):
28{
29 "app-admin/eselect-1.2.9": {
30 "deps": ["coreutils-7.5-r1"],
31 "rev_deps": [],
32 "name": "eselect",
33 "category": "app-admin",
34 "version": "1.2.9",
35 "full_name": "app-admin/eselect-1.2.9",
36 "action": "merge"
37 },
38 "sys-apps/coreutils-7.5-r1": {
39 "deps": [],
40 "rev_deps": ["app-admin/eselect-1.2.9"],
41 "name": "coreutils",
42 "category": "sys-apps",
43 "version": "7.5-r1",
44 "full_name": "sys-apps/coreutils-7.5-r1",
45 "action": "merge"
46 }
47}
48 """
David James1b363582012-12-17 11:53:11 -080049 if pkgtable is None:
50 pkgtable = {}
Jim Hebert91c052c2011-03-11 11:00:53 -080051 for cpv, record in deptree.items():
52 if cpv not in pkgtable:
David James1b363582012-12-17 11:53:11 -080053 cat, nam, ver, rev = portage.versions.catpkgsplit(cpv)
Jim Hebert91c052c2011-03-11 11:00:53 -080054 pkgtable[cpv] = {"deps": [],
55 "rev_deps": [],
56 "name": nam,
57 "category": cat,
58 "version": "%s-%s" % (ver, rev),
59 "full_name": cpv,
60 "action": record["action"]}
61 # If we have a parent, that is a rev_dep for the current package.
62 if parentcpv:
63 pkgtable[cpv]["rev_deps"].append(parentcpv)
64 # If current package has any deps, record those.
65 for childcpv in record["deps"]:
66 pkgtable[cpv]["deps"].append(childcpv)
67 # Visit the subtree recursively as well.
68 FlattenDepTree(record["deps"], pkgtable=pkgtable, parentcpv=cpv)
69 return pkgtable
70
71
72def Usage():
73 """Print usage."""
74 print """Usage:
75cros_extract_deps [--board=BOARD] [emerge args] package
76
77This extracts the dependency tree for the specified package, and outputs it
78to stdout, in a serialized JSON format. Emerge flags such as --root-deps
79can be used to influence what sort of dependency tree is extracted.
80"""
81
82
Brian Harring30675052012-02-29 12:18:22 -080083def main(argv):
84 if len(argv) == 1:
Jim Hebert91c052c2011-03-11 11:00:53 -080085 Usage()
86 sys.exit(1)
87
88 # We want the toolchain to be quiet because we are going to output
89 # a well-formed json payload.
David James0bdc5de2011-05-12 16:22:26 -070090 argv = ['--quiet', '--pretend']
Jim Hebert91c052c2011-03-11 11:00:53 -080091
92 # cros_extract_deps defaults to rdeps. However, only use this if
93 # there was no explicit --root-deps command line switch.
94 default_rootdeps_arg = ['--root-deps=rdeps']
Brian Harring30675052012-02-29 12:18:22 -080095 for arg in argv:
Jim Hebert91c052c2011-03-11 11:00:53 -080096 if arg.startswith('--root-deps'):
97 default_rootdeps_arg = []
98
99 # Now, assemble the overall argv as the concatenation of the
100 # default list + possible rootdeps-default + actual command line.
101 argv.extend(default_rootdeps_arg)
102 argv.extend(sys.argv[1:])
103
104 deps = DepGraphGenerator()
105 deps.Initialize(argv)
David James1b363582012-12-17 11:53:11 -0800106 deps_tree, _deps_info = deps.GenDependencyTree()
Jim Hebert91c052c2011-03-11 11:00:53 -0800107 print json.dumps(FlattenDepTree(deps_tree), sort_keys=True, indent=2)