| OLD | NEW |
| 1 # Copyright (c) 2014 Google Inc. All rights reserved. | 1 # Copyright (c) 2014 Google Inc. 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 """ | 5 """ |
| 6 This script is intended for use as a GYP_GENERATOR. It takes as input (by way of | 6 This script is intended for use as a GYP_GENERATOR. It takes as input (by way of |
| 7 the generator flag config_path) the path of a json file that dictates the files | 7 the generator flag config_path) the path of a json file that dictates the files |
| 8 and targets to search for. The following keys are supported: | 8 and targets to search for. The following keys are supported: |
| 9 files: list of paths (relative) of the files to search for. | 9 files: list of paths (relative) of the files to search for. |
| 10 targets: list of targets to search for. The target names are unqualified. | 10 targets: list of targets to search for. The target names are unqualified. |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 """Holds information about a particular target: | 160 """Holds information about a particular target: |
| 161 deps: set of the names of direct dependent targets. | 161 deps: set of the names of direct dependent targets. |
| 162 match_staus: one of the MatchStatus values""" | 162 match_staus: one of the MatchStatus values""" |
| 163 def __init__(self): | 163 def __init__(self): |
| 164 self.deps = set() | 164 self.deps = set() |
| 165 self.match_status = MATCH_STATUS_TBD | 165 self.match_status = MATCH_STATUS_TBD |
| 166 | 166 |
| 167 | 167 |
| 168 class Config(object): | 168 class Config(object): |
| 169 """Details what we're looking for | 169 """Details what we're looking for |
| 170 look_for_dependency_only: if true only search for a target listing any of | |
| 171 the files in files. | |
| 172 files: set of files to search for | 170 files: set of files to search for |
| 173 targets: see file description for details""" | 171 targets: see file description for details""" |
| 174 def __init__(self): | 172 def __init__(self): |
| 175 self.look_for_dependency_only = True | |
| 176 self.files = [] | 173 self.files = [] |
| 177 self.targets = [] | 174 self.targets = [] |
| 178 | 175 |
| 179 def Init(self, params): | 176 def Init(self, params): |
| 180 """Initializes Config. This is a separate method as it may raise an | 177 """Initializes Config. This is a separate method as it raises an exception |
| 181 exception if there is a parse error.""" | 178 if there is a parse error.""" |
| 182 generator_flags = params.get('generator_flags', {}) | 179 generator_flags = params.get('generator_flags', {}) |
| 183 # TODO(sky): nuke file_path and look_for_dependency_only once migrate | |
| 184 # recipes. | |
| 185 file_path = generator_flags.get('file_path', None) | |
| 186 if file_path: | |
| 187 self._InitFromFilePath(file_path) | |
| 188 return | |
| 189 | |
| 190 # If |file_path| wasn't specified then we look for config_path. | |
| 191 # TODO(sky): always look for config_path once migrated recipes. | |
| 192 config_path = generator_flags.get('config_path', None) | 180 config_path = generator_flags.get('config_path', None) |
| 193 if not config_path: | 181 if not config_path: |
| 194 return | 182 return |
| 195 self.look_for_dependency_only = False | |
| 196 try: | 183 try: |
| 197 f = open(config_path, 'r') | 184 f = open(config_path, 'r') |
| 198 config = json.load(f) | 185 config = json.load(f) |
| 199 f.close() | 186 f.close() |
| 200 except IOError: | 187 except IOError: |
| 201 raise Exception('Unable to open file ' + config_path) | 188 raise Exception('Unable to open file ' + config_path) |
| 202 except ValueError as e: | 189 except ValueError as e: |
| 203 raise Exception('Unable to parse config file ' + config_path + str(e)) | 190 raise Exception('Unable to parse config file ' + config_path + str(e)) |
| 204 if not isinstance(config, dict): | 191 if not isinstance(config, dict): |
| 205 raise Exception('config_path must be a JSON file containing a dictionary') | 192 raise Exception('config_path must be a JSON file containing a dictionary') |
| 206 self.files = config.get('files', []) | 193 self.files = config.get('files', []) |
| 207 # Coalesce duplicates | 194 # Coalesce duplicates |
| 208 self.targets = list(set(config.get('targets', []))) | 195 self.targets = list(set(config.get('targets', []))) |
| 209 | 196 |
| 210 def _InitFromFilePath(self, file_path): | |
| 211 try: | |
| 212 f = open(file_path, 'r') | |
| 213 for file_name in f: | |
| 214 if file_name.endswith('\n'): | |
| 215 file_name = file_name[0:len(file_name) - 1] | |
| 216 if len(file_name): | |
| 217 self.files.append(file_name) | |
| 218 f.close() | |
| 219 except IOError: | |
| 220 raise Exception('Unable to open file', file_path) | |
| 221 | |
| 222 | 197 |
| 223 def _WasBuildFileModified(build_file, data, files): | 198 def _WasBuildFileModified(build_file, data, files): |
| 224 """Returns true if the build file |build_file| is either in |files| or | 199 """Returns true if the build file |build_file| is either in |files| or |
| 225 one of the files included by |build_file| is in |files|.""" | 200 one of the files included by |build_file| is in |files|.""" |
| 226 if _ToGypPath(build_file) in files: | 201 if _ToGypPath(build_file) in files: |
| 227 if debug: | 202 if debug: |
| 228 print 'gyp file modified', build_file | 203 print 'gyp file modified', build_file |
| 229 return True | 204 return True |
| 230 | 205 |
| 231 # First element of included_files is the file itself. | 206 # First element of included_files is the file itself. |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 operating_system = 'linux' # Keep this legacy behavior for now. | 357 operating_system = 'linux' # Keep this legacy behavior for now. |
| 383 default_variables.setdefault('OS', operating_system) | 358 default_variables.setdefault('OS', operating_system) |
| 384 | 359 |
| 385 | 360 |
| 386 def GenerateOutput(target_list, target_dicts, data, params): | 361 def GenerateOutput(target_list, target_dicts, data, params): |
| 387 """Called by gyp as the final stage. Outputs results.""" | 362 """Called by gyp as the final stage. Outputs results.""" |
| 388 config = Config() | 363 config = Config() |
| 389 try: | 364 try: |
| 390 config.Init(params) | 365 config.Init(params) |
| 391 if not config.files: | 366 if not config.files: |
| 392 if config.look_for_dependency_only: | |
| 393 print 'Must specify files to analyze via file_path generator flag' | |
| 394 return | |
| 395 raise Exception('Must specify files to analyze via config_path generator ' | 367 raise Exception('Must specify files to analyze via config_path generator ' |
| 396 'flag') | 368 'flag') |
| 397 | 369 |
| 398 toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir)) | 370 toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir)) |
| 399 if debug: | 371 if debug: |
| 400 print 'toplevel_dir', toplevel_dir | 372 print 'toplevel_dir', toplevel_dir |
| 401 | 373 |
| 402 matched = False | 374 matched = False |
| 403 matched_include = False | 375 matched_include = False |
| 404 | 376 |
| 405 # If one of the modified files is an include file then everything is | 377 # If one of the modified files is an include file then everything is |
| 406 # affected. | 378 # affected. |
| 407 if params['options'].includes: | 379 if params['options'].includes: |
| 408 for include in params['options'].includes: | 380 for include in params['options'].includes: |
| 409 if _ToGypPath(include) in config.files: | 381 if _ToGypPath(include) in config.files: |
| 410 if debug: | 382 if debug: |
| 411 print 'include path modified', include | 383 print 'include path modified', include |
| 412 matched_include = True | 384 matched_include = True |
| 413 matched = True | 385 matched = True |
| 414 break | 386 break |
| 415 | 387 |
| 416 if not matched: | 388 if not matched: |
| 417 all_targets, matched = _GenerateTargets(data, target_list, target_dicts, | 389 all_targets, matched = _GenerateTargets(data, target_list, target_dicts, |
| 418 toplevel_dir, | 390 toplevel_dir, |
| 419 frozenset(config.files)) | 391 frozenset(config.files)) |
| 420 | 392 |
| 421 # Set of targets that refer to one of the files. | |
| 422 if config.look_for_dependency_only: | |
| 423 print found_dependency_string if matched else no_dependency_string | |
| 424 return | |
| 425 | |
| 426 warning = None | 393 warning = None |
| 427 if matched_include: | 394 if matched_include: |
| 428 output_targets = config.targets | 395 output_targets = config.targets |
| 429 elif matched: | 396 elif matched: |
| 430 unqualified_mapping = _GetUnqualifiedToQualifiedMapping( | 397 unqualified_mapping = _GetUnqualifiedToQualifiedMapping( |
| 431 all_targets, config.targets) | 398 all_targets, config.targets) |
| 432 if len(unqualified_mapping) != len(config.targets): | 399 if len(unqualified_mapping) != len(config.targets): |
| 433 not_found = [] | 400 not_found = [] |
| 434 for target in config.targets: | 401 for target in config.targets: |
| 435 if not target in unqualified_mapping: | 402 if not target in unqualified_mapping: |
| 436 not_found.append(target) | 403 not_found.append(target) |
| 437 warning = 'Unable to find all targets: ' + str(not_found) | 404 warning = 'Unable to find all targets: ' + str(not_found) |
| 438 qualified_targets = [] | 405 qualified_targets = [] |
| 439 for target in config.targets: | 406 for target in config.targets: |
| 440 if target in unqualified_mapping: | 407 if target in unqualified_mapping: |
| 441 qualified_targets.append(unqualified_mapping[target]) | 408 qualified_targets.append(unqualified_mapping[target]) |
| 442 output_targets = _GetTargetsDependingOn(all_targets, qualified_targets) | 409 output_targets = _GetTargetsDependingOn(all_targets, qualified_targets) |
| 443 else: | 410 else: |
| 444 output_targets = [] | 411 output_targets = [] |
| 445 | 412 |
| 446 result_dict = { 'targets': output_targets, | 413 result_dict = { 'targets': output_targets, |
| 447 'status': found_dependency_string if matched else | 414 'status': found_dependency_string if matched else |
| 448 no_dependency_string } | 415 no_dependency_string } |
| 449 if warning: | 416 if warning: |
| 450 result_dict['warning'] = warning | 417 result_dict['warning'] = warning |
| 451 _WriteOutput(params, **result_dict) | 418 _WriteOutput(params, **result_dict) |
| 452 | 419 |
| 453 except Exception as e: | 420 except Exception as e: |
| 454 _WriteOutput(params, error=str(e)) | 421 _WriteOutput(params, error=str(e)) |
| OLD | NEW |