Use json file to define versions to be bundled.
[bitmask_bundler.git] / bundler / main.py
1 # TODO:
2 #  - Check if inside a virtualenv, and warn before doing anything
3 #  - Build everything that we are currently expecting as a binary
4 #  - Create complete bundle changelog
5
6 import argparse
7 import json
8 import os
9 import tempfile
10
11 from contextlib import contextmanager
12 from distutils import dir_util
13
14 from actions import GitCloneAll, GitCheckout, PythonSetupAll
15 from actions import CollectAllDeps, CopyBinaries, PLister, SeededConfig
16 from actions import DarwinLauncher, CopyAssets, CopyMisc, FixDylibs
17 from actions import DmgIt, PycRemover, TarballIt, MtEmAll, ZipIt, SignIt
18 from actions import RemoveUnused, CreateDirStructure
19
20 from utils import IS_MAC, IS_WIN
21
22 sorted_repos = [
23     "leap_assets",
24     "leap_pycommon",
25     "keymanager",
26     "soledad",
27     "leap_mail",
28     "bitmask_client",
29     "bitmask_launcher",
30 ]
31
32
33 @contextmanager
34 def new_build_dir(default=None):
35     bd = default
36     if bd is None:
37         bd = tempfile.mkdtemp(prefix="bundler-")
38     yield bd
39     # Only remove if created a temp dir
40     if default is None:
41         dir_util.remove_tree(bd)
42
43
44 def get_version(versions_file):
45     """
46     Return the "version" data on the json file given as parameter.
47
48     :param versions_file: the file name of the json to parse.
49     :type versions_file: str
50
51     :rtype: str or None
52     """
53     version = None
54     try:
55         versions = None
56         with open(versions_file, 'r') as f:
57             versions = json.load(f)
58
59         version = versions.get("version")
60     except Exception as e:
61         print "Problem getting version: {0!r}".format(e)
62
63     return version
64
65
66 def main():
67     parser = argparse.ArgumentParser(description='Bundle creation tool.')
68     parser.add_argument('--workon', help="")
69     parser.add_argument('--skip', nargs="*", default=[], help="")
70     parser.add_argument('--do', nargs="*", default=[], help="")
71     parser.add_argument('--paths-file', help="")
72     parser.add_argument('--versions-file', help="")
73     parser.add_argument('--binaries', help="")
74     parser.add_argument('--seeded-config', help="")
75     parser.add_argument('--codesign', default="", help="")
76
77     args = parser.parse_args()
78
79     assert args.paths_file is not None, \
80         "We need a paths file, otherwise you'll get " \
81         "problems with distutils and site"
82     paths_file = os.path.realpath(args.paths_file)
83
84     assert args.binaries is not None, \
85         "We don't support building from source, so you'll need to " \
86         "specify a binaries path"
87     binaries_path = os.path.realpath(args.binaries)
88
89     assert args.versions_file is not None, \
90         "You need to specify a versions file with the versions to use " \
91         "for each package."
92     versions_path = os.path.realpath(args.versions_file)
93
94     seeded_config = None
95     if args.seeded_config is not None:
96         seeded_config = os.path.realpath(args.seeded_config)
97
98     with new_build_dir(os.path.realpath(args.workon)) as bd:
99         print "Doing it all in", bd
100
101         def init(t, bd=bd):
102             return t(bd, args.skip, args.do)
103
104         gc = init(GitCloneAll)
105         gc.run(sorted_repos)
106
107         # NOTE: NEW...
108         gco = init(GitCheckout)
109         gco.run(sorted_repos, versions_path)
110
111         ps = init(PythonSetupAll)
112         ps.run(sorted_repos, binaries_path)
113
114         cd = init(CreateDirStructure, os.path.join(bd, "Bitmask"))
115         cd.run()
116
117         dp = init(CollectAllDeps)
118         dp.run(paths_file)
119
120         if binaries_path is not None:
121             cb = init(CopyBinaries)
122             cb.run(binaries_path)
123
124         if IS_MAC:
125             pl = init(PLister)
126             pl.run()
127             dl = init(DarwinLauncher)
128             dl.run()
129             ca = init(CopyAssets)
130             ca.run()
131             fd = init(FixDylibs)
132             fd.run()
133
134         cm = init(CopyMisc)
135         cm.run(binaries_path)
136
137         pyc = init(PycRemover)
138         pyc.run()
139
140         if IS_WIN:
141             mt = init(MtEmAll)
142             mt.run()
143
144         if IS_MAC:
145             si = init(SignIt)
146             si.run(args.codesign)
147
148         if seeded_config is not None:
149             sc = init(SeededConfig)
150             sc.run(seeded_config)
151
152         version = get_version(versions_path)
153
154         if IS_MAC:
155             dm = init(DmgIt)
156             dm.run(sorted_repos, version)
157         elif IS_WIN:
158             zi = init(ZipIt)
159             zi.run(sorted_repos, version)
160         else:
161             ru = init(RemoveUnused)
162             ru.run()
163             ti = init(TarballIt)
164             ti.run(sorted_repos, version)
165
166         # do manifest on windows
167
168 if __name__ == "__main__":
169     main()