[M120 Migration][Gamepad]Add gamepad event latency Test code
[platform/framework/web/chromium-efl.git] / build / landmines.py
1 #!/usr/bin/env python3
2 # Copyright 2012 The Chromium Authors
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """
7 This script runs every gclient runhooks as the first hook (See DEPS). If it
8 detects that the build should be clobbered, it will delete the contents of the
9 build directory.
10
11 A landmine is tripped when a builder checks out a different revision, and the
12 diff between the new landmines and the old ones is non-null. At this point, the
13 build is clobbered.
14
15 Before adding or changing a landmine consider the consequences of doing so.
16 Doing so will wipe out every output directory on every Chrome developer's
17 machine. This can be particularly problematic on Windows where the directory
18 deletion may well fail (locked files, command prompt in the directory, etc.),
19 and generated .sln and .vcxproj files will be deleted.
20
21 This output directory deletion will be repeated when going back and forth across
22 the change that added the landmine, adding to the cost. There are usually less
23 troublesome alternatives.
24 """
25
26 import difflib
27 import errno
28 import logging
29 import optparse
30 import os
31 import sys
32 import subprocess
33 import time
34
35 import clobber
36 import landmine_utils
37
38
39 def get_build_dir(src_dir):
40   r"""
41   Returns the absolute path to the directory containing the build directories.
42   Examples:
43     'C:\src\out'
44     '/b/s/w/ir/cache/builder/src/out'
45   """
46   if 'CHROMIUM_OUT_DIR' in os.environ:
47     output_dir = os.environ.get('CHROMIUM_OUT_DIR').strip()
48     if not output_dir:
49       raise Error('CHROMIUM_OUT_DIR environment variable is set but blank!')
50   else:
51     output_dir = 'out'
52   return os.path.abspath(os.path.join(src_dir, output_dir))
53
54
55 def clobber_if_necessary(new_landmines, src_dir, landmines_path):
56   """Does the work of setting, planting, and triggering landmines."""
57   out_dir = get_build_dir(src_dir)
58   try:
59     os.makedirs(out_dir)
60   except OSError as e:
61     if e.errno == errno.EEXIST:
62       pass
63
64   if os.path.exists(landmines_path):
65     with open(landmines_path, 'r') as f:
66       old_landmines = f.readlines()
67     if old_landmines != new_landmines:
68       old_date = time.ctime(os.stat(landmines_path).st_ctime)
69       diff = difflib.unified_diff(old_landmines, new_landmines,
70           fromfile='old_landmines', tofile='new_landmines',
71           fromfiledate=old_date, tofiledate=time.ctime(), n=0)
72       sys.stdout.write('Clobbering due to:\n')
73       sys.stdout.writelines(diff)
74       sys.stdout.flush()
75
76       clobber.clobber(out_dir)
77
78   # Save current set of landmines for next time.
79   with open(landmines_path, 'w') as f:
80     f.writelines(new_landmines)
81
82
83 def process_options():
84   """Returns an options object containing the configuration for this script."""
85   parser = optparse.OptionParser()
86   parser.add_option(
87       '-s', '--landmine-scripts', action='append',
88       help='Path to the script which emits landmines to stdout. The target '
89            'is passed to this script via option -t. Note that an extra '
90            'script can be specified via an env var EXTRA_LANDMINES_SCRIPT.')
91   parser.add_option('-d', '--src-dir',
92       help='Path of the source root dir. Overrides the default location of the '
93            'source root dir when calculating the build directory.')
94   parser.add_option(
95       '-l',
96       '--landmines-path',
97       help='Path to the landmines file to use (defaults to .landmines)')
98   parser.add_option('-v', '--verbose', action='store_true',
99       default=('LANDMINES_VERBOSE' in os.environ),
100       help=('Emit some extra debugging information (default off). This option '
101           'is also enabled by the presence of a LANDMINES_VERBOSE environment '
102           'variable.'))
103
104   options, args = parser.parse_args()
105
106   if args:
107     parser.error('Unknown arguments %s' % args)
108
109   logging.basicConfig(
110       level=logging.DEBUG if options.verbose else logging.ERROR)
111
112   if options.src_dir:
113     if not os.path.isdir(options.src_dir):
114       parser.error('Cannot find source root dir at %s' % options.src_dir)
115     logging.debug('Overriding source root dir. Using: %s', options.src_dir)
116   else:
117     options.src_dir = \
118         os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
119
120   if not options.landmine_scripts:
121     options.landmine_scripts = [os.path.join(options.src_dir, 'build',
122                                              'get_landmines.py')]
123
124   extra_script = os.environ.get('EXTRA_LANDMINES_SCRIPT')
125   if extra_script:
126     options.landmine_scripts += [extra_script]
127
128   return options
129
130
131 def main():
132   options = process_options()
133
134   landmines = []
135   for s in options.landmine_scripts:
136     proc = subprocess.Popen([sys.executable, s], stdout=subprocess.PIPE,
137                             universal_newlines=True)
138     output, _ = proc.communicate()
139     landmines.extend([('%s\n' % l.strip()) for l in output.splitlines()])
140   if options.landmines_path:
141     landmines_path = options.landmines_path
142   else:
143     landmines_path = os.path.join(options.src_dir, '.landmines')
144   clobber_if_necessary(landmines, options.src_dir,
145                        os.path.normpath(landmines_path))
146
147   return 0
148
149
150 if __name__ == '__main__':
151   sys.exit(main())