Mike Frysinger | 9f7e4ee | 2013-03-13 15:43:03 -0400 | [diff] [blame^] | 1 | #!/usr/bin/python |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 2 | # 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 | |
| 6 | import json |
| 7 | import portage |
| 8 | import sys |
| 9 | from parallel_emerge import DepGraphGenerator |
| 10 | |
David James | 1b36358 | 2012-12-17 11:53:11 -0800 | [diff] [blame] | 11 | def FlattenDepTree(deptree, pkgtable=None, parentcpv=None): |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 12 | """ |
| 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 James | 1b36358 | 2012-12-17 11:53:11 -0800 | [diff] [blame] | 49 | if pkgtable is None: |
| 50 | pkgtable = {} |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 51 | for cpv, record in deptree.items(): |
| 52 | if cpv not in pkgtable: |
David James | 1b36358 | 2012-12-17 11:53:11 -0800 | [diff] [blame] | 53 | cat, nam, ver, rev = portage.versions.catpkgsplit(cpv) |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 54 | 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 | |
| 72 | def Usage(): |
| 73 | """Print usage.""" |
| 74 | print """Usage: |
| 75 | cros_extract_deps [--board=BOARD] [emerge args] package |
| 76 | |
| 77 | This extracts the dependency tree for the specified package, and outputs it |
| 78 | to stdout, in a serialized JSON format. Emerge flags such as --root-deps |
| 79 | can be used to influence what sort of dependency tree is extracted. |
| 80 | """ |
| 81 | |
| 82 | |
Brian Harring | 3067505 | 2012-02-29 12:18:22 -0800 | [diff] [blame] | 83 | def main(argv): |
| 84 | if len(argv) == 1: |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 85 | 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 James | 0bdc5de | 2011-05-12 16:22:26 -0700 | [diff] [blame] | 90 | argv = ['--quiet', '--pretend'] |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 91 | |
| 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 Harring | 3067505 | 2012-02-29 12:18:22 -0800 | [diff] [blame] | 95 | for arg in argv: |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 96 | 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 James | 1b36358 | 2012-12-17 11:53:11 -0800 | [diff] [blame] | 106 | deps_tree, _deps_info = deps.GenDependencyTree() |
Jim Hebert | 91c052c | 2011-03-11 11:00:53 -0800 | [diff] [blame] | 107 | print json.dumps(FlattenDepTree(deps_tree), sort_keys=True, indent=2) |