Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import json | |
| 6 import os | |
| 7 | |
| 8 from appengine_url_fetcher import AppEngineUrlFetcher | |
| 9 from caching_file_system import CachingFileSystem | |
| 10 from compiled_file_system import CompiledFileSystem | |
| 11 from object_store_creator import ObjectStoreCreator | |
| 12 from subversion_file_system import SubversionFileSystem | |
| 13 import svn_constants | |
| 14 import third_party.json_schema_compiler.model as model | |
| 15 import url_constants | |
| 16 | |
|
epeterson
2013/04/17 03:38:50
Removed the [huge] dependency on api_data_source f
| |
| 17 class AvailabilityDataSource(object): | |
| 18 '''Uses API data sources generated by a ChromeVersionDataSource in order to | |
| 19 search the filesystem for the earliest existence of a specified API throughout | |
| 20 the different versions of Chrome; this constitutes an API's availability. | |
| 21 ''' | |
| 22 class Factory(object): | |
| 23 def __init__(self, chrome_version_utility, svn_file_system=None): | |
| 24 self._chrome_version_utility = chrome_version_utility | |
| 25 self._object_store = ObjectStoreCreator(AvailabilityDataSource).Create() | |
| 26 | |
| 27 # The |svn_file_system| will only be none for testing. | |
| 28 if svn_file_system is not None: | |
| 29 json_string = svn_file_system.ReadSingle('%s/api_availabilities.json' | |
| 30 % svn_constants.JSON_PATH) | |
| 31 self._existing_availabilities = json.loads(json_string) | |
| 32 | |
|
epeterson
2013/04/17 03:38:50
This hasn't been tested on the appengine, because
| |
| 33 def Create(self): | |
| 34 return AvailabilityDataSource(self._chrome_version_utility, | |
| 35 self._object_store, | |
| 36 self._existing_availabilities) | |
| 37 | |
| 38 def __init__(self, | |
| 39 chrome_version_utility, | |
| 40 object_store, | |
| 41 existing_availabilities): | |
| 42 self._chrome_version_utility = chrome_version_utility | |
| 43 self._object_store = object_store | |
| 44 self._existing_availabilities = existing_availabilities | |
| 45 | |
| 46 def _CreateSvnFileSystemForBranch(self, branch): | |
| 47 '''Creates a file system tied to a a specific branch of the svn repository. | |
| 48 ''' | |
| 49 if branch == 'trunk': | |
| 50 svn_url = '/'.join((url_constants.SVN_TRUNK_URL, | |
| 51 'src', | |
| 52 svn_constants.EXTENSIONS_PATH)) | |
| 53 else: | |
| 54 svn_url = '/'.join((url_constants.SVN_BRANCH_URL, | |
| 55 branch, | |
| 56 'src', | |
| 57 svn_constants.EXTENSIONS_PATH)) | |
| 58 viewvc_url = svn_url.replace(url_constants.SVN_URL, | |
| 59 url_constants.VIEWVC_URL) | |
| 60 | |
| 61 svn_file_system = CachingFileSystem( | |
| 62 SubversionFileSystem(AppEngineUrlFetcher(svn_url), | |
| 63 AppEngineUrlFetcher(viewvc_url)), | |
| 64 ObjectStoreCreator.Factory(branch)) | |
| 65 return svn_file_system | |
| 66 | |
| 67 def _GetAllNames(self, base_dir, apis): | |
| 68 '''Returns unix_hacker_style names for all APIs currently available. | |
| 69 ''' | |
| 70 return [ | |
| 71 model.UnixName(os.path.splitext(api)[0]) | |
| 72 for api in apis | |
| 73 ] | |
| 74 | |
| 75 def _GetAsSubdirectory(self, name): | |
| 76 if name.startswith('experimental_'): | |
| 77 parts = name[len('experimental_'):].split('_', 1) | |
| 78 if len(parts) > 1: | |
| 79 parts[1] = 'experimental_%s' % parts[1] | |
| 80 return '/'.join(parts) | |
| 81 else: | |
| 82 return '%s/%s' % (parts[0], name) | |
| 83 return name.replace('_', '/', 1) | |
| 84 | |
| 85 def _CheckApiExistence(self, api_name, version): | |
| 86 '''Finds a list of APIs that are present in the given |version|, and checks | |
| 87 to see whether or not |api_name| exists in that list. | |
| 88 ''' | |
| 89 names = self._object_store.Get(version).Get() | |
| 90 | |
| 91 if names is None: | |
| 92 svn_file_system = self._CreateSvnFileSystemForBranch( | |
| 93 self._chrome_version_utility.GetBranchNumberForVersion(version)) | |
| 94 compiled_fs_factory = CompiledFileSystem.Factory( | |
| 95 svn_file_system, | |
| 96 ObjectStoreCreator.Factory()) | |
| 97 names_cache = compiled_fs_factory.Create(self._GetAllNames, | |
| 98 AvailabilityDataSource) | |
| 99 names = names_cache.GetFromFileListing(svn_constants.API_PATH) | |
|
epeterson
2013/04/17 03:38:50
Instead of trying to load every file and check for
| |
| 100 self._object_store.Set(version, names) | |
| 101 api_name = model.UnixName(api_name) | |
| 102 return api_name in names or self._GetAsSubdirectory(api_name) in names | |
| 103 | |
| 104 def FindEarliestAvailability(self, api_name): | |
| 105 '''Searches in descending order through filesystem caches tied to specific | |
| 106 chrome version numbers and looks for the existence of a specified api, | |
| 107 |api_name|. When an api is not found, returns the previous version number | |
| 108 (the last known version where the api was found). | |
| 109 ''' | |
| 110 availability = self._object_store.Get(api_name).Get() | |
| 111 if availability is not None: | |
| 112 return availability | |
| 113 elif availability is False: | |
| 114 return None | |
| 115 | |
| 116 # Check for a predetermined availability for this API. | |
| 117 availability = self._existing_availabilities.get(api_name, None) | |
| 118 if availability is not None: | |
| 119 self._object_store.Set(api_name, availability) | |
| 120 return availability | |
| 121 | |
| 122 # If the API isn't found in trunk, then it isn't currently available. | |
| 123 if not self._CheckApiExistence(api_name, 'trunk'): | |
| 124 self._object_store.Set(api_name, False) | |
| 125 return None | |
| 126 | |
| 127 latest_version = int(self._chrome_version_utility.GetLatestVersionNumber()) | |
| 128 version_int = latest_version | |
| 129 # Extension APIs are not present in the filesystem before version 18. | |
| 130 while version_int >= 18: | |
| 131 if not self._CheckApiExistence(api_name, str(version_int)): | |
| 132 break | |
| 133 version_int -= 1 | |
| 134 | |
| 135 version_int += 1 | |
| 136 if version_int > latest_version: | |
| 137 availability = 'trunk' | |
| 138 else: | |
| 139 availability = str(version_int) | |
| 140 | |
| 141 self._object_store.Set(api_name, availability) | |
| 142 return availability | |
| OLD | NEW |