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

Side by Side Diff: scripts/slave/recipes.py

Issue 1241323004: Cross-repo recipe package system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Change to googlesource Created 5 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2
3 # Copyright 2015 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """Bootstrap script to clone and forward to the recipe engine tool."""
8
9 import ast
10 import os
11 import random
12 import re
13 import subprocess
14 import sys
15 import time
16
17 BOOTSTRAP_VERSION = 1
18 RECIPES_CFG = os.path.join(
19 os.pardir, os.pardir, 'infra', 'config', 'recipes.cfg')
20
21
22 def parse_protobuf(fh):
23 """Parse the protobuf text format just well enough to understand recipes.cfg.
24
25 We don't use the protobuf library because we want to be as self-contained
26 as possible in this bootstrap, so it can be simply vendored into a client
27 repo.
28
29 We assume all fields are repeated since we don't have a proto spec to work
30 with.
31
32 Args:
33 fh: a filehandle containing the text format protobuf.
34 Returns:
35 A recursive dictionary of lists.
36 """
37 def parse_atom(text):
38 if text == 'true': return True
39 if text == 'false': return False
40 return ast.literal_eval(text)
41
42 ret = {}
43 for line in fh:
44 line = line.strip()
45 m = re.match(r'(\w+)\s*:\s*(.*)', line)
iannucci 2015/09/15 00:10:48 can this file have comments?
luqui 2015/09/15 19:17:42 It cannot. For once this makes me happy.
46 if m:
47 ret.setdefault(m.group(1), []).append(parse_atom(m.group(2)))
iannucci 2015/09/15 00:10:48 why not inline parse_atom? It's super small and on
luqui 2015/09/15 19:17:41 Because it involves an intermediate variable, and
48 continue
49
50 m = re.match(r'(\w+)\s*{', line)
51 if m:
52 subparse = parse_protobuf(fh)
53 ret.setdefault(m.group(1), []).append(subparse)
54 continue
55
56 if line == '}': return ret
57 if line == '': continue
58
59 raise Exception('Could not understand line: <%s>' % line)
60
61 return ret
62
63
64
65 def main():
66 # Find the repository and config file to operate on.
67 git_dir = os.path.dirname(
68 subprocess.check_output(['git', 'rev-parse', '--git-dir'],
69 cwd=os.path.dirname(__file__)).strip())
70 recipes_cfg_path = os.path.join(os.path.dirname(__file__), RECIPES_CFG)
71
72 with open(recipes_cfg_path, 'rU') as fh:
73 protobuf = parse_protobuf(fh)
74
75 [engine_buf] = [
iannucci 2015/09/15 00:10:48 whoa... how did I not know about this particular a
luqui 2015/09/15 19:17:42 Seems like it is safer to die here instead of choo
76 b for b in protobuf['deps'] if b.get('project_id') == ['recipe_engine'] ]
77 [engine_url] = engine_buf['url']
78 [engine_revision] = engine_buf['revision']
79 [engine_subpath] = engine_buf.get('path_override', [''])
80 engine_subpath = engine_subpath.replace('/', os.path.sep)
81
82 [recipes_path] = protobuf['recipes_path']
83 recipes_path = os.path.join(git_dir, recipes_path.replace('/', os.path.sep))
84 deps_path = os.path.join(recipes_path, '.recipe_deps')
85 engine_path = os.path.join(deps_path, 'recipe_engine')
86
87 # Ensure that we have the recipe engine cloned.
88 def ensure_engine():
89 if not os.path.exists(deps_path):
90 os.makedirs(deps_path)
91 if not os.path.exists(engine_path):
92 subprocess.check_call(['git', 'clone', engine_url, engine_path])
93
94 needs_fetch = subprocess.call(
95 ['git', 'rev-parse', '--verify', '%s^{commit}' % engine_revision],
96 cwd=engine_path, stdout=open(os.devnull, 'w'))
97 if needs_fetch:
98 subprocess.check_call(['git', 'fetch'], cwd=engine_path)
99 subprocess.check_call(
100 ['git', 'checkout', '--quiet', engine_revision], cwd=engine_path)
101
102 try:
103 ensure_engine()
104 except subprocess.CalledProcessError as e:
105 if e.returncode == 128: # Thrown when git gets a lock error.
106 time.sleep(random.uniform(2,5))
107 ensure_engine()
108 else:
109 raise
110
111 args = ([sys.argv[0]] + ['--package', recipes_cfg_path,
112 '--bootstrap-script', __file__] + sys.argv[1:])
113 os.execvp(
114 os.path.join(engine_path, engine_subpath, 'recipes.py'),
115 args)
116
117 if __name__ == '__main__':
118 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698