| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """Runs Android's lint tool.""" | 7 """Runs Android's lint tool.""" |
| 8 | 8 |
| 9 | 9 |
| 10 import argparse | 10 import argparse |
| 11 import os | 11 import os |
| 12 import re |
| 12 import sys | 13 import sys |
| 13 import traceback | 14 import traceback |
| 14 from xml.dom import minidom | 15 from xml.dom import minidom |
| 15 | 16 |
| 16 from util import build_utils | 17 from util import build_utils |
| 17 | 18 |
| 18 | 19 |
| 19 _SRC_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), | 20 _SRC_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), |
| 20 '..', '..', '..')) | 21 '..', '..', '..')) |
| 21 | 22 |
| 22 | 23 |
| 23 def _OnStaleMd5(changes, lint_path, config_path, processed_config_path, | 24 def _OnStaleMd5(changes, lint_path, config_path, processed_config_path, |
| 24 manifest_path, result_path, product_dir, sources, jar_path, | 25 manifest_path, result_path, product_dir, sources, jar_path, |
| 25 cache_dir, resource_dir=None, classpath=None, | 26 cache_dir, android_sdk_version, resource_dir=None, |
| 26 can_fail_build=False, silent=False): | 27 classpath=None, can_fail_build=False, silent=False): |
| 27 | |
| 28 def _RelativizePath(path): | 28 def _RelativizePath(path): |
| 29 """Returns relative path to top-level src dir. | 29 """Returns relative path to top-level src dir. |
| 30 | 30 |
| 31 Args: | 31 Args: |
| 32 path: A path relative to cwd. | 32 path: A path relative to cwd. |
| 33 """ | 33 """ |
| 34 return os.path.relpath(os.path.abspath(path), _SRC_ROOT) | 34 return os.path.relpath(os.path.abspath(path), _SRC_ROOT) |
| 35 | 35 |
| 36 def _ProcessConfigFile(): | 36 def _ProcessConfigFile(): |
| 37 if not config_path or not processed_config_path: | 37 if not config_path or not processed_config_path: |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 src_dir = None | 122 src_dir = None |
| 123 for d in src_dirs: | 123 for d in src_dirs: |
| 124 if not os.path.exists(PathInDir(d, src)): | 124 if not os.path.exists(PathInDir(d, src)): |
| 125 src_dir = d | 125 src_dir = d |
| 126 break | 126 break |
| 127 if not src_dir: | 127 if not src_dir: |
| 128 src_dir = NewSourceDir() | 128 src_dir = NewSourceDir() |
| 129 cmd.extend(['--sources', _RelativizePath(src_dir)]) | 129 cmd.extend(['--sources', _RelativizePath(src_dir)]) |
| 130 os.symlink(os.path.abspath(src), PathInDir(src_dir, src)) | 130 os.symlink(os.path.abspath(src), PathInDir(src_dir, src)) |
| 131 | 131 |
| 132 project_dir = NewSourceDir() |
| 133 if android_sdk_version: |
| 134 # Create dummy project.properies file in a temporary "project" directory. |
| 135 # It is the only way to add Android SDK to the Lint's classpath. Proper |
| 136 # classpath is necessary for most source-level checks. |
| 137 with open(os.path.join(project_dir, 'project.properties'), 'w') \ |
| 138 as propfile: |
| 139 print >> propfile, 'target=android-{}'.format(android_sdk_version) |
| 140 |
| 132 # Put the manifest in a temporary directory in order to avoid lint detecting | 141 # Put the manifest in a temporary directory in order to avoid lint detecting |
| 133 # sibling res/ and src/ directories (which should be pass explicitly if they | 142 # sibling res/ and src/ directories (which should be pass explicitly if they |
| 134 # are to be included). | 143 # are to be included). |
| 135 if manifest_path: | 144 if manifest_path: |
| 136 src_dir = NewSourceDir() | |
| 137 os.symlink(os.path.abspath(manifest_path), | 145 os.symlink(os.path.abspath(manifest_path), |
| 138 PathInDir(src_dir, manifest_path)) | 146 PathInDir(project_dir, manifest_path)) |
| 139 cmd.append(src_dir) | 147 cmd.append(project_dir) |
| 140 | 148 |
| 141 if os.path.exists(result_path): | 149 if os.path.exists(result_path): |
| 142 os.remove(result_path) | 150 os.remove(result_path) |
| 143 | 151 |
| 144 env = {} | 152 env = {} |
| 145 stderr_filter = None | 153 stderr_filter = None |
| 146 if cache_dir: | 154 if cache_dir: |
| 155 env['_JAVA_OPTIONS'] = '-Duser.home=%s' % _RelativizePath(cache_dir) |
| 147 # When _JAVA_OPTIONS is set, java prints to stderr: | 156 # When _JAVA_OPTIONS is set, java prints to stderr: |
| 148 # Picked up _JAVA_OPTIONS: ... | 157 # Picked up _JAVA_OPTIONS: ... |
| 149 env['_JAVA_OPTIONS'] = '-Duser.home=%s' % _RelativizePath(cache_dir) | 158 # |
| 150 stderr_filter = lambda l: '' if '_JAVA_OPTIONS' in l else l | 159 # We drop all lines that contain _JAVA_OPTIONS from the output |
| 160 stderr_filter = lambda l: re.sub(r'.*_JAVA_OPTIONS.*\n?', '', l) |
| 151 | 161 |
| 152 try: | 162 try: |
| 153 build_utils.CheckOutput(cmd, cwd=_SRC_ROOT, env=env or None, | 163 build_utils.CheckOutput(cmd, cwd=_SRC_ROOT, env=env or None, |
| 154 stderr_filter=stderr_filter) | 164 stderr_filter=stderr_filter) |
| 155 except build_utils.CalledProcessError: | 165 except build_utils.CalledProcessError: |
| 156 # There is a problem with lint usage | 166 # There is a problem with lint usage |
| 157 if not os.path.exists(result_path): | 167 if not os.path.exists(result_path): |
| 158 raise | 168 raise |
| 159 | 169 |
| 160 # Sometimes produces empty (almost) files: | 170 # Sometimes produces empty (almost) files: |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 help='Path to lint executable.') | 228 help='Path to lint executable.') |
| 219 parser.add_argument('--product-dir', required=True, | 229 parser.add_argument('--product-dir', required=True, |
| 220 help='Path to product dir.') | 230 help='Path to product dir.') |
| 221 parser.add_argument('--result-path', required=True, | 231 parser.add_argument('--result-path', required=True, |
| 222 help='Path to XML lint result file.') | 232 help='Path to XML lint result file.') |
| 223 parser.add_argument('--cache-dir', required=True, | 233 parser.add_argument('--cache-dir', required=True, |
| 224 help='Path to the directory in which the android cache ' | 234 help='Path to the directory in which the android cache ' |
| 225 'directory tree should be stored.') | 235 'directory tree should be stored.') |
| 226 parser.add_argument('--platform-xml-path', required=True, | 236 parser.add_argument('--platform-xml-path', required=True, |
| 227 help='Path to api-platforms.xml') | 237 help='Path to api-platforms.xml') |
| 238 parser.add_argument('--android-sdk-version', |
| 239 help='Version (API level) of the Android SDK used for ' |
| 240 'building.') |
| 228 parser.add_argument('--create-cache', action='store_true', | 241 parser.add_argument('--create-cache', action='store_true', |
| 229 help='Mark the lint cache file as an output rather than ' | 242 help='Mark the lint cache file as an output rather than ' |
| 230 'an input.') | 243 'an input.') |
| 231 parser.add_argument('--can-fail-build', action='store_true', | 244 parser.add_argument('--can-fail-build', action='store_true', |
| 232 help='If set, script will exit with nonzero exit status' | 245 help='If set, script will exit with nonzero exit status' |
| 233 ' if lint errors are present') | 246 ' if lint errors are present') |
| 234 parser.add_argument('--config-path', | 247 parser.add_argument('--config-path', |
| 235 help='Path to lint suppressions file.') | 248 help='Path to lint suppressions file.') |
| 236 parser.add_argument('--enable', action='store_true', | 249 parser.add_argument('--enable', action='store_true', |
| 237 help='Run lint instead of just touching stamp.') | 250 help='Run lint instead of just touching stamp.') |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 if args.resource_dir: | 295 if args.resource_dir: |
| 283 input_paths.extend(build_utils.FindInDirectory(args.resource_dir, '*')) | 296 input_paths.extend(build_utils.FindInDirectory(args.resource_dir, '*')) |
| 284 if sources: | 297 if sources: |
| 285 input_paths.extend(sources) | 298 input_paths.extend(sources) |
| 286 classpath = [] | 299 classpath = [] |
| 287 for gyp_list in args.classpath: | 300 for gyp_list in args.classpath: |
| 288 classpath.extend(build_utils.ParseGypList(gyp_list)) | 301 classpath.extend(build_utils.ParseGypList(gyp_list)) |
| 289 input_paths.extend(classpath) | 302 input_paths.extend(classpath) |
| 290 | 303 |
| 291 input_strings = [] | 304 input_strings = [] |
| 305 if args.android_sdk_version: |
| 306 input_strings.append(args.android_sdk_version) |
| 292 if args.processed_config_path: | 307 if args.processed_config_path: |
| 293 input_strings.append(args.processed_config_path) | 308 input_strings.append(args.processed_config_path) |
| 294 | 309 |
| 295 output_paths = [ args.result_path ] | 310 output_paths = [ args.result_path ] |
| 296 | 311 |
| 297 build_utils.CallAndWriteDepfileIfStale( | 312 build_utils.CallAndWriteDepfileIfStale( |
| 298 lambda changes: _OnStaleMd5(changes, args.lint_path, | 313 lambda changes: _OnStaleMd5(changes, args.lint_path, |
| 299 args.config_path, | 314 args.config_path, |
| 300 args.processed_config_path, | 315 args.processed_config_path, |
| 301 args.manifest_path, args.result_path, | 316 args.manifest_path, args.result_path, |
| 302 args.product_dir, sources, | 317 args.product_dir, sources, |
| 303 args.jar_path, | 318 args.jar_path, |
| 304 args.cache_dir, | 319 args.cache_dir, |
| 320 args.android_sdk_version, |
| 305 resource_dir=args.resource_dir, | 321 resource_dir=args.resource_dir, |
| 306 classpath=classpath, | 322 classpath=classpath, |
| 307 can_fail_build=args.can_fail_build, | 323 can_fail_build=args.can_fail_build, |
| 308 silent=args.silent), | 324 silent=args.silent), |
| 309 args, | 325 args, |
| 310 input_paths=input_paths, | 326 input_paths=input_paths, |
| 311 input_strings=input_strings, | 327 input_strings=input_strings, |
| 312 output_paths=output_paths, | 328 output_paths=output_paths, |
| 313 pass_changes=True, | 329 pass_changes=True, |
| 314 depfile_deps=classpath) | 330 depfile_deps=classpath) |
| 315 | 331 |
| 316 | 332 |
| 317 if __name__ == '__main__': | 333 if __name__ == '__main__': |
| 318 sys.exit(main()) | 334 sys.exit(main()) |
| OLD | NEW |