| OLD | NEW |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 from caching_file_system import CachingFileSystem | 5 from caching_file_system import CachingFileSystem |
| 6 from gitiles_file_system import GitilesFileSystem | 6 from gitiles_file_system import GitilesFileSystem |
| 7 from local_file_system import LocalFileSystem | 7 from local_file_system import LocalFileSystem |
| 8 from offline_file_system import OfflineFileSystem | 8 from offline_file_system import OfflineFileSystem |
| 9 from third_party.json_schema_compiler.memoize import memoize | 9 from third_party.json_schema_compiler.memoize import memoize |
| 10 | 10 |
| 11 | 11 |
| 12 class HostFileSystemProvider(object): | 12 class HostFileSystemProvider(object): |
| 13 '''Provides host file systems ("host" meaning the file system that hosts the | 13 '''Provides host file systems ("host" meaning the file system that hosts the |
| 14 server's source code and templates) tracking master, or any branch. | 14 server's source code and templates) tracking master, or any branch. |
| 15 | 15 |
| 16 File system instances are memoized to maintain the in-memory caches across | 16 File system instances are memoized to maintain the in-memory caches across |
| 17 multiple callers. | 17 multiple callers. |
| 18 ''' | 18 ''' |
| 19 def __init__(self, | 19 def __init__(self, |
| 20 object_store_creator, | 20 object_store_creator, |
| 21 pinned_commit=None, | 21 pinned_commit=None, |
| 22 default_master_instance=None, | 22 default_master_instance=None, |
| 23 offline=False, | 23 offline=False, |
| 24 constructor_for_test=None): | 24 constructor_for_test=None, |
| 25 cache_only=False): |
| 25 ''' | 26 ''' |
| 26 |object_store_creator| | 27 |object_store_creator| |
| 27 Provides caches for file systems that need one. | 28 Provides caches for file systems that need one. |
| 28 |pinned_commit| | 29 |pinned_commit| |
| 29 If not None, the commit at which a 'master' file system will be created. | 30 If not None, the commit at which a 'master' file system will be created. |
| 30 If None, 'master' file systems will use HEAD. | 31 If None, 'master' file systems will use HEAD. |
| 31 |default_master_instance| | 32 |default_master_instance| |
| 32 If not None, 'master' file systems provided by this class without a | 33 If not None, 'master' file systems provided by this class without a |
| 33 specific commit will return |default_master_instance| instead. | 34 specific commit will return |default_master_instance| instead. |
| 34 |offline| | 35 |offline| |
| 35 If True all provided file systems will be wrapped in an OfflineFileSystem. | 36 If True all provided file systems will be wrapped in an OfflineFileSystem. |
| 36 |constructor_for_test| | 37 |constructor_for_test| |
| 37 Provides a custom constructor rather than creating GitilesFileSystems. | 38 Provides a custom constructor rather than creating GitilesFileSystems. |
| 39 |cache_only| |
| 40 If True, all provided file systems will be cache-only, meaning that cache |
| 41 misses will result in errors rather than cache updates. |
| 38 ''' | 42 ''' |
| 39 self._object_store_creator = object_store_creator | 43 self._object_store_creator = object_store_creator |
| 40 self._pinned_commit = pinned_commit | 44 self._pinned_commit = pinned_commit |
| 41 self._default_master_instance = default_master_instance | 45 self._default_master_instance = default_master_instance |
| 42 self._offline = offline | 46 self._offline = offline |
| 43 self._constructor_for_test = constructor_for_test | 47 self._constructor_for_test = constructor_for_test |
| 48 self._cache_only = cache_only |
| 44 | 49 |
| 45 @memoize | 50 @memoize |
| 46 def GetMaster(self, commit=None): | 51 def GetMaster(self, commit=None): |
| 47 '''Gets a file system tracking 'master'. Use this method rather than | 52 '''Gets a file system tracking 'master'. Use this method rather than |
| 48 GetBranch('master') because the behaviour is subtly different; 'master' can | 53 GetBranch('master') because the behaviour is subtly different; 'master' can |
| 49 be pinned to a specific commit (|pinned_commit| in constructor) and can have | 54 be pinned to a specific commit (|pinned_commit| in constructor) and can have |
| 50 have its default instance overridden (|default_master_instance| in the | 55 have its default instance overridden (|default_master_instance| in the |
| 51 constructor). | 56 constructor). |
| 52 | 57 |
| 53 |commit| if non-None determines a specific commit to pin the host file | 58 |commit| if non-None determines a specific commit to pin the host file |
| 54 system at, though it will be ignored if it's newer than |pinned_commit|. | 59 system at, though it will be ignored if it's newer than |pinned_commit|. |
| 55 If None then |commit| will track |pinned_commit| if is has been | 60 If None then |commit| will track |pinned_commit| if is has been |
| 56 set, or just HEAD (which might change during server runtime!). | 61 set, or just HEAD (which might change during server runtime!). |
| 57 ''' | 62 ''' |
| 58 if commit is None: | 63 if commit is None: |
| 59 if self._default_master_instance is not None: | 64 if self._default_master_instance is not None: |
| 60 return self._default_master_instance | 65 return self._default_master_instance |
| 61 return self._Create('master', commit=self._pinned_commit) | 66 return self._Create('master', commit=self._pinned_commit) |
| 62 if self._pinned_commit is not None: | |
| 63 # XXX(ahernandez): THIS IS WRONG. Should be | |
| 64 # commit = Oldest(commit, self._pinned_commit). | |
| 65 commit = min(commit, self._pinned_commit) | |
| 66 return self._Create('master', commit=commit) | 67 return self._Create('master', commit=commit) |
| 67 | 68 |
| 68 @memoize | 69 @memoize |
| 69 def GetBranch(self, branch): | 70 def GetBranch(self, branch): |
| 70 '''Gets a file system tracking |branch|, for example '1150' - anything other | 71 '''Gets a file system tracking |branch|, for example '1150' - anything other |
| 71 than 'master', which must be constructed via the GetMaster() method. | 72 than 'master', which must be constructed via the GetMaster() method. |
| 72 | 73 |
| 73 Note: Unlike GetMaster this function doesn't take a |commit| argument | 74 Note: Unlike GetMaster this function doesn't take a |commit| argument |
| 74 since we assume that branches hardly ever change, while master frequently | 75 since we assume that branches hardly ever change, while master frequently |
| 75 changes. | 76 changes. |
| 76 ''' | 77 ''' |
| 77 assert isinstance(branch, basestring), 'Branch %s must be a string' % branch | 78 assert isinstance(branch, basestring), 'Branch %s must be a string' % branch |
| 78 assert branch != 'master', ( | 79 assert branch != 'master', ( |
| 79 'Cannot specify branch=\'master\', use GetMaster()') | 80 'Cannot specify branch=\'master\', use GetMaster()') |
| 80 return self._Create(branch) | 81 return self._Create(branch) |
| 81 | 82 |
| 82 def _Create(self, branch, commit=None): | 83 def _Create(self, branch, commit=None): |
| 83 '''Creates Gitiles file systems (or if in a test, potentially whatever | 84 '''Creates Gitiles file systems (or if in a test, potentially whatever |
| 84 |self._constructor_for_test specifies). Wraps the resulting file system in | 85 |self._constructor_for_test specifies). Wraps the resulting file system in |
| 85 an Offline file system if the offline flag is set, and finally wraps it in | 86 an Offline file system if the offline flag is set, and finally wraps it in |
| 86 a Caching file system. | 87 a Caching file system. |
| 87 ''' | 88 ''' |
| 89 empty_stat_cache = True |
| 88 if self._constructor_for_test is not None: | 90 if self._constructor_for_test is not None: |
| 89 file_system = self._constructor_for_test(branch=branch, commit=commit) | 91 file_system = self._constructor_for_test(branch=branch, commit=commit) |
| 90 else: | 92 else: |
| 91 file_system = GitilesFileSystem.Create(branch=branch, commit=commit) | 93 file_system = GitilesFileSystem.Create(branch=branch, commit=commit) |
| 94 # GitilesFileSystem supports the notion of unstable identity, which means |
| 95 # its CachingFileSystem can use a persistent stat info cache without |
| 96 # breaking everything. |
| 97 empty_stat_cache = False |
| 92 if self._offline: | 98 if self._offline: |
| 93 file_system = OfflineFileSystem(file_system) | 99 file_system = OfflineFileSystem(file_system) |
| 94 return CachingFileSystem(file_system, self._object_store_creator) | 100 return CachingFileSystem(file_system, self._object_store_creator, |
| 101 fail_on_miss=self._cache_only, empty_stat_cache=empty_stat_cache) |
| 95 | 102 |
| 96 @staticmethod | 103 @staticmethod |
| 97 def ForLocal(object_store_creator, **optargs): | 104 def ForLocal(object_store_creator, **optargs): |
| 98 '''Used in creating a server instance on localhost. | 105 '''Used in creating a server instance on localhost. |
| 99 ''' | 106 ''' |
| 100 return HostFileSystemProvider( | 107 return HostFileSystemProvider( |
| 101 object_store_creator, | 108 object_store_creator, |
| 102 constructor_for_test=lambda **_: LocalFileSystem.Create(), | 109 constructor_for_test=lambda **_: LocalFileSystem.Create(), |
| 103 **optargs) | 110 **optargs) |
| 104 | 111 |
| 105 @staticmethod | 112 @staticmethod |
| 106 def ForTest(file_system, object_store_creator, **optargs): | 113 def ForTest(file_system, object_store_creator, **optargs): |
| 107 '''Used in creating a test server instance. The HostFileSystemProvider | 114 '''Used in creating a test server instance. The HostFileSystemProvider |
| 108 returned here will always return |file_system| when its Create() method is | 115 returned here will always return |file_system| when its Create() method is |
| 109 called. | 116 called. |
| 110 ''' | 117 ''' |
| 111 return HostFileSystemProvider( | 118 return HostFileSystemProvider( |
| 112 object_store_creator, | 119 object_store_creator, |
| 113 constructor_for_test=lambda **_: file_system, | 120 constructor_for_test=lambda **_: file_system, |
| 114 **optargs) | 121 **optargs) |
| OLD | NEW |