• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import json
6import optparse
7import os
8import pipes
9import subprocess
10import sys
11
12import bb_annotations
13
14sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
15from pylib import constants
16
17
18TESTING = 'BUILDBOT_TESTING' in os.environ
19
20BB_BUILD_DIR = os.path.abspath(
21    os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir,
22    os.pardir, os.pardir, os.pardir, os.pardir))
23
24CHROME_SRC = os.path.abspath(
25    os.path.join(os.path.dirname(__file__), '..', '..', '..'))
26
27# TODO: Figure out how to merge this with pylib.cmd_helper.OutDirectory().
28CHROME_OUT_DIR = os.path.join(CHROME_SRC, 'out')
29
30GOMA_DIR = os.environ.get('GOMA_DIR', os.path.join(BB_BUILD_DIR, 'goma'))
31
32GSUTIL_PATH = os.path.join(BB_BUILD_DIR, 'third_party', 'gsutil', 'gsutil')
33
34def CommandToString(command):
35  """Returns quoted command that can be run in bash shell."""
36  return ' '.join(map(pipes.quote, command))
37
38
39def SpawnCmd(command, stdout=None, cwd=CHROME_SRC):
40  """Spawn a process without waiting for termination."""
41  print '>', CommandToString(command)
42  sys.stdout.flush()
43  if TESTING:
44    class MockPopen(object):
45      @staticmethod
46      def wait():
47        return 0
48      @staticmethod
49      def communicate():
50        return '', ''
51    return MockPopen()
52  return subprocess.Popen(command, cwd=cwd, stdout=stdout)
53
54
55def RunCmd(command, flunk_on_failure=True, halt_on_failure=False,
56           warning_code=constants.WARNING_EXIT_CODE, stdout=None,
57           cwd=CHROME_SRC):
58  """Run a command relative to the chrome source root."""
59  code = SpawnCmd(command, stdout, cwd).wait()
60  print '<', CommandToString(command)
61  if code != 0:
62    print 'ERROR: process exited with code %d' % code
63    if code != warning_code and flunk_on_failure:
64      bb_annotations.PrintError()
65    else:
66      bb_annotations.PrintWarning()
67    # Allow steps to have both halting (i.e. 1) and non-halting exit codes.
68    if code != warning_code and halt_on_failure:
69      print 'FATAL %d != %d' % (code, warning_code)
70      sys.exit(1)
71  return code
72
73
74def GetParser():
75  def ConvertJson(option, _, value, parser):
76    setattr(parser.values, option.dest, json.loads(value))
77  parser = optparse.OptionParser()
78  parser.add_option('--build-properties', action='callback',
79                    callback=ConvertJson, type='string', default={},
80                    help='build properties in JSON format')
81  parser.add_option('--factory-properties', action='callback',
82                    callback=ConvertJson, type='string', default={},
83                    help='factory properties in JSON format')
84  return parser
85
86
87def EncodeProperties(options):
88  return ['--factory-properties=%s' % json.dumps(options.factory_properties),
89          '--build-properties=%s' % json.dumps(options.build_properties)]
90
91
92def RunSteps(steps, step_cmds, options):
93  unknown_steps = set(steps) - set(step for step, _ in step_cmds)
94  if unknown_steps:
95    print >> sys.stderr, 'FATAL: Unknown steps %s' % list(unknown_steps)
96    sys.exit(1)
97
98  for step, cmd in step_cmds:
99    if step in steps:
100      cmd(options)
101