| 1 | #!/usr/bin/python -S
 | 
| 2 | from __future__ import print_function
 | 
| 3 | """
 | 
| 4 | runpy_deps.py
 | 
| 5 | 
 | 
| 6 | NOTE: -S above is important.
 | 
| 7 | """
 | 
| 8 | 
 | 
| 9 | import sys  # 15 modules
 | 
| 10 | import runpy  # 34 modules
 | 
| 11 | 
 | 
| 12 | PY_MODULE = 0
 | 
| 13 | C_MODULE = 1
 | 
| 14 | 
 | 
| 15 | 
 | 
| 16 | def FilterModules(modules, stdlib_dir):
 | 
| 17 |   stdlib_dir_len = len(stdlib_dir)
 | 
| 18 | 
 | 
| 19 |   for name in sorted(modules):
 | 
| 20 |     mod = modules[name]
 | 
| 21 |     if name in ('__builtin__', '__main__'):
 | 
| 22 |       continue
 | 
| 23 | 
 | 
| 24 |     try:
 | 
| 25 |       full_path = mod.__file__
 | 
| 26 |     except AttributeError:
 | 
| 27 |       full_path = None
 | 
| 28 | 
 | 
| 29 |     # If it's cached, it will be under .pyc; otherwise under .py.
 | 
| 30 |     if full_path and full_path.endswith('.py'):
 | 
| 31 |       py_path = full_path
 | 
| 32 |       pyc_path = full_path + 'c'
 | 
| 33 |     elif full_path and full_path.endswith('.pyc'):
 | 
| 34 |       pyc_path = full_path
 | 
| 35 |       py_path = full_path[:-1]
 | 
| 36 |     else:
 | 
| 37 |       # Print a different format for C modules.
 | 
| 38 |       yield C_MODULE, name, full_path
 | 
| 39 | 
 | 
| 40 |     if py_path:
 | 
| 41 |       if py_path.startswith(stdlib_dir):
 | 
| 42 |         rel_py_path = py_path[stdlib_dir_len:]
 | 
| 43 |       else:
 | 
| 44 |         rel_py_path = py_path
 | 
| 45 | 
 | 
| 46 |       # .pyc file for execution
 | 
| 47 |       yield PY_MODULE, py_path, rel_py_path
 | 
| 48 | 
 | 
| 49 | 
 | 
| 50 | def main(argv):
 | 
| 51 |   runpy_path = runpy.__file__
 | 
| 52 |   i = runpy_path.rfind('/')
 | 
| 53 |   assert i != -1, runpy_path
 | 
| 54 |   stdlib_dir = runpy_path[: i + 1]  # include trailing slash
 | 
| 55 | 
 | 
| 56 |   action = argv[1]
 | 
| 57 | 
 | 
| 58 |   if action == 'both':
 | 
| 59 |     path_prefix = argv[2]
 | 
| 60 | 
 | 
| 61 |     py_out_path = path_prefix + '/runpy-deps-cpython.txt'
 | 
| 62 |     c_out_path = path_prefix + '/runpy-deps-c.txt'
 | 
| 63 | 
 | 
| 64 |     # NOTE: This is very similar to build/app_deps.py.
 | 
| 65 |     with open(py_out_path, 'w') as py_out, open(c_out_path, 'w') as c_out:
 | 
| 66 |       for mod_type, x, y in FilterModules(sys.modules, stdlib_dir):
 | 
| 67 |         if mod_type == PY_MODULE:
 | 
| 68 |           print(x, y, file=py_out)
 | 
| 69 |           print(x + 'c', y + 'c', file=py_out)  # .pyc goes in bytecode.zip too
 | 
| 70 |           pass
 | 
| 71 | 
 | 
| 72 |         elif mod_type == C_MODULE:
 | 
| 73 |           print(x, y, file=c_out)  # mod_name, full_path
 | 
| 74 | 
 | 
| 75 |         else:
 | 
| 76 |           raise AssertionError(mod_type)
 | 
| 77 | 
 | 
| 78 |     print('-- Wrote %s and %s' % (py_out_path, c_out_path), file=sys.stderr)
 | 
| 79 | 
 | 
| 80 |   elif action == 'py':
 | 
| 81 |     for mod_type, full_path, rel_path in \
 | 
| 82 |         FilterModules(sys.modules, stdlib_dir):
 | 
| 83 |       if mod_type == PY_MODULE:
 | 
| 84 |         opy_input = full_path
 | 
| 85 |         opy_output = rel_path + 'c'  # output is .pyc
 | 
| 86 |         print(opy_input, opy_output)
 | 
| 87 | 
 | 
| 88 |   else:
 | 
| 89 |     raise RuntimeError('Invalid action %r' % action)
 | 
| 90 | 
 | 
| 91 | 
 | 
| 92 | if __name__ == '__main__':
 | 
| 93 |   try:
 | 
| 94 |     main(sys.argv)
 | 
| 95 |   except RuntimeError as e:
 | 
| 96 |     print('%s: %s' % (sys.argv[0], e.args[0]), file=sys.stderr)
 | 
| 97 |     sys.exit(1)
 |