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

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

Issue 14602020: Add an AOSP builder recipe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: rebase on top of CL 15270004 Created 7 years, 7 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
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """This module holds utilities which make writing recipes easier.""" 5 """This module holds utilities which make writing recipes easier."""
6 6
7 import contextlib as _contextlib 7 import contextlib as _contextlib
8 import os as _os 8 import os as _os
9 9
10 # These imports are intended to be passed through to recipes 10 # These imports are intended to be passed through to recipes
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 56
57 The actual checkout root is filled in by annotated_run after the recipe 57 The actual checkout root is filled in by annotated_run after the recipe
58 completes, and is dependent on the implementation of 'root()' in 58 completes, and is dependent on the implementation of 'root()' in
59 annotated_checkout for the checkout type that you've selected. 59 annotated_checkout for the checkout type that you've selected.
60 60
61 NOTE: In order for this function to work, your recipe MUST use the 'checkout' 61 NOTE: In order for this function to work, your recipe MUST use the 'checkout'
62 functionality provided by annotated_run. 62 functionality provided by annotated_run.
63 """ # pylint: disable=W0105 63 """ # pylint: disable=W0105
64 checkout_path = _path_method('checkout_path', '%(CheckoutRootPlaceholder)s') 64 checkout_path = _path_method('checkout_path', '%(CheckoutRootPlaceholder)s')
65 65
66 def path_exists(path):
67 return _os.path.exists(path)
66 68
67 @_contextlib.contextmanager 69 @_contextlib.contextmanager
68 def mock_paths(): 70 def mock_paths(mock_path_exists=None):
69 """Used by unittest/recipes_test.py to temporarily override the paths 71 """Used by unittest/recipes_test.py to temporarily override the paths
70 generated by the various path functions in this module. 72 generated by the various path functions in this module.
71 73
72 This is necessary to give equivalent output when running the tests on any 74 This is necessary to give equivalent output when running the tests on any
73 checkout configuration. Instead of real paths, recipes which use these 75 checkout configuration. Instead of real paths, recipes which use these
74 functions will get paths like '[DEPOT_TOOLS_ROOT]'. 76 functions will get paths like '[DEPOT_TOOLS_ROOT]'.
75 """ 77 """
76 path_base_names = ['depot_tools', 'build_internal', 'build', 'slave_build', 78 path_base_names = ['depot_tools', 'build_internal', 'build', 'slave_build',
77 'root'] 79 'root']
78 g = globals() 80 g = globals()
79 tokens = {} 81 tokens = {}
80 path_funcs = {} 82 path_funcs = {}
81 try: 83 try:
82 for name in path_base_names: 84 for name in path_base_names:
83 token_name = (name + '_root').upper() 85 token_name = (name + '_root').upper()
84 token_val = '[%s]' % token_name 86 token_val = '[%s]' % token_name
85 path_func_name = (name + '_path') 87 path_func_name = (name + '_path')
86 88
87 if token_name in g: 89 if token_name in g:
88 tokens[token_name] = g[token_name] 90 tokens[token_name] = g[token_name]
89 g[token_name] = token_val 91 g[token_name] = token_val
90 92
91 if path_func_name in g: 93 if path_func_name in g:
92 path_funcs[path_func_name] = g[path_func_name] 94 path_funcs[path_func_name] = g[path_func_name]
93 g[path_func_name] = _path_method(path_func_name, token_val) 95 g[path_func_name] = _path_method(path_func_name, token_val)
96
97 if mock_path_exists:
iannucci 2013/05/20 19:41:38 Let's replace path_exists no matter what. If not m
mkosiba (inactive) 2013/05/21 10:56:07 Done.
98 path_funcs['path_exists'] = g['path_exists']
99 g['path_exists'] = lambda path: path in mock_path_exists
94 yield 100 yield
95 finally: 101 finally:
96 g.update(tokens) 102 g.update(tokens)
97 g.update(path_funcs) 103 g.update(path_funcs)
98 104
99 105
100 def deep_set(obj, key_vals): 106 def deep_set(obj, key_vals):
101 """Take an object (a dict or list), and a list of key/value pairs to set, 107 """Take an object (a dict or list), and a list of key/value pairs to set,
102 and transform it by replacing items in obj at the key locations with the 108 and transform it by replacing items in obj at the key locations with the
103 respective values. 109 respective values.
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 'recursive': recursive, 365 'recursive': recursive,
360 }, 366 },
361 }), 367 }),
362 self.git('fetch', 'origin', *recursive_args), 368 self.git('fetch', 'origin', *recursive_args),
363 self.git('update-ref', 'refs/heads/'+branch, 'origin/'+branch), 369 self.git('update-ref', 'refs/heads/'+branch, 'origin/'+branch),
364 self.git('clean', '-f', '-d', '-X'), 370 self.git('clean', '-f', '-d', '-X'),
365 self.git('checkout', '-f', branch), 371 self.git('checkout', '-f', branch),
366 self.git('submodule', 'update', '--init', '--recursive'), 372 self.git('submodule', 'update', '--init', '--recursive'),
367 ] 373 ]
368 374
369 def gclient_checkout(self, common_repo_name, git_mode=False): 375 def gclient_checkout(self, common_repo_name_or_spec, git_mode=False,
376 spec_name=None):
370 """Returns a step generator function for gclient checkouts.""" 377 """Returns a step generator function for gclient checkouts."""
371 spec = GCLIENT_COMMON_SPECS[common_repo_name](self) 378 if isinstance(common_repo_name_or_spec, basestring):
379 spec = GCLIENT_COMMON_SPECS[common_repo_name_or_spec](self)
380 else:
381 spec = common_repo_name_or_spec
372 spec_string = '' 382 spec_string = ''
383 if not spec_name:
384 step_name = lambda n: 'gclient ' + n
385 else:
386 step_name = lambda n: '[spec: %s] gclient %s' % (spec_name, n)
373 for key in spec: 387 for key in spec:
374 # We should be using json.dumps here, but gclient directly execs the dict 388 # We should be using json.dumps here, but gclient directly execs the dict
375 # that it receives as the argument to --spec, so we have to have True, 389 # that it receives as the argument to --spec, so we have to have True,
376 # False, and None instead of JSON's true, false, and null. 390 # False, and None instead of JSON's true, false, and null.
377 spec_string += '%s = %s\n' % (key, str(spec[key])) 391 spec_string += '%s = %s\n' % (key, str(spec[key]))
378 gclient = depot_tools_path('gclient') + ('.bat' if IsWindows() else '') 392 gclient = depot_tools_path('gclient') + ('.bat' if IsWindows() else '')
379 393
380 if not git_mode: 394 if not git_mode:
381 clean_step = self.step('gclient clean', [gclient, 'revert', '--nohooks']) 395 clean_step = self.step(step_name('clean'),
382 sync_step = self.step('gclient sync', [gclient, 'sync', '--nohooks']) 396 [gclient, 'revert', '--nohooks'])
397 sync_step = self.step(step_name('sync'), [gclient, 'sync', '--nohooks'])
383 else: 398 else:
384 # clean() isn't used because the gclient sync flags passed in checkout() 399 # clean() isn't used because the gclient sync flags passed in checkout()
385 # do much the same thing, and they're more correct than doing a separate 400 # do much the same thing, and they're more correct than doing a separate
386 # 'gclient revert' because it makes sure the other args are correct when 401 # 'gclient revert' because it makes sure the other args are correct when
387 # a repo was deleted and needs to be re-cloned (notably 402 # a repo was deleted and needs to be re-cloned (notably
388 # --with_branch_heads), whereas 'revert' uses default args for clone 403 # --with_branch_heads), whereas 'revert' uses default args for clone
389 # operations. 404 # operations.
390 # 405 #
391 # TODO(mmoss): To be like current official builders, this step could just 406 # TODO(mmoss): To be like current official builders, this step could just
392 # delete the whole <slave_name>/build/ directory and start each build 407 # delete the whole <slave_name>/build/ directory and start each build
393 # from scratch. That might be the least bad solution, at least until we 408 # from scratch. That might be the least bad solution, at least until we
394 # have a reliable gclient method to produce a pristine working dir for 409 # have a reliable gclient method to produce a pristine working dir for
395 # git-based builds (e.g. maybe some combination of 'git reset/clean -fx' 410 # git-based builds (e.g. maybe some combination of 'git reset/clean -fx'
396 # and removing the 'out' directory). 411 # and removing the 'out' directory).
397 clean_step = None 412 clean_step = None
398 sync_step = self.step('gclient sync', [ 413 sync_step = self.step(step_name('sync'), [
399 gclient, 'sync', '--verbose', '--with_branch_heads', '--nohooks', 414 gclient, 'sync', '--verbose', '--with_branch_heads', '--nohooks',
400 '--reset', '--delete_unversioned_trees', '--force']) 415 '--reset', '--delete_unversioned_trees', '--force'])
401 steps = [ 416 steps = [
402 self.step( 417 self.step(
403 'gclient setup', 418 step_name('setup'),
404 [gclient, 'config', '--spec', spec_string], 419 [gclient, 'config', '--spec', spec_string],
405 static_json_data={ 420 static_json_data={
406 'CheckoutRoot': slave_build_path(spec['solutions'][0]['name']), 421 'CheckoutRoot': slave_build_path(spec['solutions'][0]['name']),
407 'CheckoutSCM': 'gclient', 422 'CheckoutSCM': 'gclient',
408 'CheckoutSpec': spec 423 'CheckoutSpec': spec
409 } 424 }
410 ), 425 ),
411 ] 426 ]
412 if clean_step: 427 if clean_step:
413 steps.append(clean_step) 428 steps.append(clean_step)
414 if sync_step: 429 if sync_step:
415 steps.append(sync_step) 430 steps.append(sync_step)
416 431
417 return steps 432 return steps
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698