Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: bootstrap/build_deps.py

Issue 381043002: Add a virtualenv-based python bootstrapping service to infra. (Closed) Base URL: https://chromium.googlesource.com/infra/infra@master
Patch Set: Make it work on linux! Also... PyYAML... grumble Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium 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 argparse
7 import hashlib
8 import os
9 import shutil
10 import subprocess
11 import sys
12
13 import bootstrap
14
15 from util import GIT_REPO, ROOT, WHEELHOUSE, WHEELS_URL, SOURCE_URL
16
17 from util import tempdir, tempname, read_deps, print_deps, platform_tag
18
19
20 def has_custom_build(name):
21 return os.path.exists(os.path.join(ROOT, 'custom_builds', name + '.py'))
22
23
24 def pip(*args, **kwargs):
25 subprocess.check_call(
26 (os.path.join(sys.prefix, 'bin', 'pip'),) + args, **kwargs)
27
28
29 def wheel(arg, source_sha, build, build_options):
30 with tempdir() as tdir:
31 args = ['wheel', '--no-index', '--no-deps', '--wheel-dir', tdir]
32 for op in build_options:
33 args += ['--global-option', op]
34 args += [arg]
35 pip(*args)
36 grab_wheel(tdir, WHEELHOUSE, source_sha, build)
37
38
39 def grab_wheel(src, dst, source_sha, build):
40 # late import lets us grab the virtualenv pip
41 from pip.wheel import Wheel
42
43 items = os.listdir(src)
44 assert len(items) == 1, 'Wrong number of files in wheel directory: %r' % items
45
46 wheelfile = items[0]
47 wheel_info = Wheel.wheel_file_re.match(wheelfile)
48
49 assert wheel_info is not None, 'Not a wheel file? %r' % wheelfile
50
51 plat_tag = ''
52 if not wheelfile.endswith('none-any.whl'):
53 plat_tag = platform_tag()
54
55 os.rename(os.path.join(src, wheelfile),
56 os.path.join(dst, '{}-{}_{}{}{}'.format(
57 wheel_info.group('namever'),
58 build,
59 source_sha,
60 plat_tag,
61 wheel_info.group(4),
62 )))
63
64
65 def run_custom_build(name, link, sha, build):
66 from pip.index import Link
67 from pip.download import unpack_file_url, unpack_vcs_link, is_vcs_url
68
69 assert has_custom_build(name)
70
71 link = Link(link, trusted=True)
72 unpack = unpack_vcs_link if is_vcs_url(link) else unpack_file_url
73
74 with tempdir() as tmpd, tempdir() as wheeld: # pylint: disable=C0321
75 unpack(link, tmpd)
76 m = getattr(__import__('custom_builds.%s' % (name,)), name)
77 m.Build(tmpd, wheeld)
78 grab_wheel(wheeld, WHEELHOUSE, sha, build)
79
80
81 def process_git(name, rev, build, build_options):
82 print
83 print 'Processing (git)', name, rev
84
85 url = GIT_REPO.format(name) + '@' + rev
86
87 if not has_custom_build(name):
88 wheel(url, rev, build, build_options)
89 else:
90 run_custom_build(name, url, rev, build)
91
92
93 def process_gs(name, sha_ext, build, build_options):
94 print
95 print 'Processing (gs)', name, sha_ext
96
97 sha, ext = sha_ext.split('.', 1)
98 with tempname(ext) as tmp:
99 link = 'file://' + tmp
100 subprocess.check_call(['gsutil', 'cp', SOURCE_URL.format(sha_ext), tmp])
101 with open(tmp, 'rb') as f:
102 assert hashlib.sha1(f.read()).hexdigest() == sha
103 if not has_custom_build(name):
104 wheel(link, sha, build, build_options)
105 else:
106 run_custom_build(name, link, sha, build)
107
108
109 def clear_wheelhouse():
110 shutil.rmtree(WHEELHOUSE, ignore_errors=True)
111 try:
112 os.makedirs(WHEELHOUSE)
113 except OSError:
114 pass
115
116
117 def push_wheelhouse():
118 return subprocess.call(['gsutil', '-m', 'cp', WHEELHOUSE + '/*', WHEELS_URL])
119
120
121 def main(args):
122 parser = argparse.ArgumentParser()
123 parser.add_argument(
124 'to_build', nargs='*',
125 help='Names of packages to build. Defaults to all packages.')
126 opts = parser.parse_args(args)
127 to_build = set(opts.to_build)
128
129 build_env = os.path.join(ROOT, 'BUILD_ENV')
130
131 print 'Parsing deps.pyl'
132 deps = read_deps(os.path.join(ROOT, 'deps.pyl'))
133 bootstrap.activate_env(build_env, {'wheel': deps.pop('wheel')})
134
135 print 'Finding missing deps'
136 missing_deps = {}
137 for name, entry in deps.iteritems():
138 if to_build and name not in to_build:
139 continue
140 try:
141 bootstrap.get_links({name: entry})
142 except bootstrap.NoWheelException:
143 missing_deps[name] = entry
144
145 if not missing_deps:
146 print 'Nothing to process'
147 return
148
149 print 'Processing deps:'
150 print_deps(missing_deps)
151
152 for name, options in missing_deps.iteritems():
153 clear_wheelhouse()
154 # TODO(iannucci): skip entries which already exist in gs
155 if 'rev' in options:
156 process_git(name, options['rev'], options['build'],
157 options.get('build_options', ()))
158 elif 'gs' in options:
159 process_gs(name, options['gs'], options['build'],
160 options.get('build_options', ()))
161 else:
162 raise Exception('Invalid options %r for %r' % (options, name))
163 push_wheelhouse()
164
165
166 if __name__ == '__main__':
167 sys.exit(main(sys.argv[1:]))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698