Create bundler for OSX
[bitmask_bundler.git] / bundler / depcollector.py
1 import sys
2 import os
3 import errno
4
5 from distutils import dir_util, file_util
6 from modulegraph import modulegraph
7
8
9 def mkdir_p(path):
10     try:
11         os.makedirs(path)
12     except OSError as exc:
13         if exc.errno == errno.EEXIST and os.path.isdir(path):
14             pass
15         else: raise
16
17 def collect_deps(root, dest_lib_dir, path_file):
18     mg = modulegraph.ModuleGraph([sys.path[0]] + [x.strip() for x in open(path_file, 'r').readlines()] + sys.path[1:])#, debug=3)
19
20     mg.import_hook("distutils")
21     mg.import_hook("site")
22     mg.import_hook("jsonschema")
23     mg.import_hook("scrypt")
24     mg.import_hook("_scrypt")
25     mg.import_hook("ConfigParser")
26     mg.import_hook("Crypto")
27     mg.import_hook("encodings.idna")
28     mg.import_hook("leap.soledad.client")
29     mg.import_hook("leap.mail")
30     mg.import_hook("leap.keymanager")
31     mg.import_hook("argparse")
32     mg.import_hook("srp")
33     mg.import_hook("pkgutil")
34     mg.import_hook("pkg_resources")
35     mg.import_hook("_sre")
36     mg.import_hook("zope.proxy")
37     mg.run_script(root)
38
39     packages = [mg.findNode(i) for i in ["leap.common", "leap.keymanager", "leap.mail", "leap.soledad.client", "leap.soledad.common", "jsonschema"]]
40     other = []
41
42     sorted_pkg = [(os.path.basename(mod.identifier), mod) for mod in mg.flatten()]
43     sorted_pkg.sort()
44     for (name, pkg) in sorted_pkg:
45         # skip namespace packages
46         if name == "leap" or name == "leap.soledad" or name == "google" or name == "zope" or name.endswith("leap/bitmask/app.py"):
47             continue
48         # print pkg
49         if isinstance(pkg, modulegraph.MissingModule):
50             # print "ignoring", pkg.identifier
51             continue
52         elif isinstance(pkg, modulegraph.Package):
53             foundpackage = False
54             for i in packages:
55                 if pkg.identifier.startswith(i.identifier):
56                     # print "skipping", pkg.identifier, "member of", i.identifier
57                     # print "  found in", i.filename
58                     foundpackage = True
59                     break
60             if foundpackage:
61                 continue
62             if pkg.filename is None:
63                 continue
64             if pkg not in packages:
65                 packages.append(pkg)
66         else: #if isinstance(pkg, modulegraph.Extension):
67             foundpackage = False
68             for i in packages:
69                 if pkg.identifier.startswith(i.identifier):
70                     # print "skipping", pkg.identifier, "member of", i.identifier
71                     # print "  found in", i.filename
72                     foundpackage = True
73                     break
74             if foundpackage:
75                 continue
76             if pkg.filename is None:
77                 continue
78             other.append(pkg)
79             # print pkg.identifier
80     #import pdb; pdb.set_trace()
81
82     print "Packages", len(packages)
83     for i in sorted(packages):
84         # if i.identifier == "distutils":
85         #     i.filename = distutils.__file__
86         print i.identifier, i.filename
87         parts = i.identifier.split(".")
88         destdir = os.path.join(*([dest_lib_dir]+parts))
89         mkdir_p(destdir)
90         dir_util.copy_tree(os.path.dirname(i.filename), destdir)
91         before = []
92         for part in parts:
93             before.append(part)
94             current = before + ["__init__.py"]
95             try:
96                 with open(os.path.join(dest_lib_dir, *current), 'a'):
97                     pass
98             except Exception:
99                 pass
100
101     print "Other", len(other)
102     for i in sorted(other):
103         # if i.identifier == "site":
104         #     i.filename = site.__file__
105         print i.identifier, i.filename
106         file_util.copy_file(i.filename, dest_lib_dir)
107
108     # TODO: remove everything in dest_lib_dir/PySide that is not QtCore, QtGui and __init__
109
110     # ON OSX ONLY:
111     # TODO: remove dest_lib_dir/sre* and PYTHONHOME from the launcher script
112     # remove dest_lib_dir/_socket.so