Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: chrome/common/extensions/docs/server2/subversion_file_system.py

Issue 14247024: Devserver: allow SubversionFileSystem to be pinned to a specific rev on construction (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 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 import logging 5 import logging
6 import re 6 import re
7 import posixpath 7 import posixpath
8 import xml.dom.minidom as xml 8 import xml.dom.minidom as xml
9 from xml.parsers.expat import ExpatError 9 from xml.parsers.expat import ExpatError
10 10
11 from appengine_url_fetcher import AppEngineUrlFetcher 11 from appengine_url_fetcher import AppEngineUrlFetcher
12 from docs_server_utils import StringIdentity 12 from docs_server_utils import StringIdentity
13 from file_system import FileSystem, FileNotFoundError, StatInfo, ToUnicode 13 from file_system import FileSystem, FileNotFoundError, StatInfo, ToUnicode
14 from future import Future 14 from future import Future
15 import svn_constants 15 import svn_constants
16 import url_constants 16 import url_constants
17 17
18 class _AsyncFetchFuture(object): 18 class _AsyncFetchFuture(object):
19 def __init__(self, paths, fetcher, binary): 19 def __init__(self, paths, fetcher, binary, args=None):
20 def apply_args(path):
21 return path if args is None else '%s?%s' % (path, args)
20 # A list of tuples of the form (path, Future). 22 # A list of tuples of the form (path, Future).
21 self._fetches = [(path, fetcher.FetchAsync(path)) 23 self._fetches = [(path, fetcher.FetchAsync(apply_args(path)))
22 for path in paths] 24 for path in paths]
23 self._value = {} 25 self._value = {}
24 self._error = None 26 self._error = None
25 self._binary = binary 27 self._binary = binary
26 28
27 def _ListDir(self, directory): 29 def _ListDir(self, directory):
28 dom = xml.parseString(directory) 30 dom = xml.parseString(directory)
29 files = [elem.childNodes[0].data for elem in dom.getElementsByTagName('a')] 31 files = [elem.childNodes[0].data for elem in dom.getElementsByTagName('a')]
30 if '..' in files: 32 if '..' in files:
31 files.remove('..') 33 files.remove('..')
(...skipping 15 matching lines...) Expand all
47 else: 49 else:
48 self._value[path] = result.content 50 self._value[path] = result.content
49 if self._error is not None: 51 if self._error is not None:
50 raise self._error 52 raise self._error
51 return self._value 53 return self._value
52 54
53 class SubversionFileSystem(FileSystem): 55 class SubversionFileSystem(FileSystem):
54 '''Class to fetch resources from src.chromium.org. 56 '''Class to fetch resources from src.chromium.org.
55 ''' 57 '''
56 @staticmethod 58 @staticmethod
57 def Create(branch): 59 def Create(branch, revision=None):
58 if branch == 'trunk': 60 if branch == 'trunk':
59 svn_path = 'trunk/src/%s' % svn_constants.EXTENSIONS_PATH 61 svn_path = 'trunk/src/%s' % svn_constants.EXTENSIONS_PATH
60 else: 62 else:
61 svn_path = 'branches/%s/src/%s' % (branch, 63 svn_path = 'branches/%s/src/%s' % (branch,
62 svn_constants.EXTENSIONS_PATH) 64 svn_constants.EXTENSIONS_PATH)
63 return SubversionFileSystem( 65 return SubversionFileSystem(
64 AppEngineUrlFetcher('%s/%s' % (url_constants.SVN_URL, svn_path)), 66 AppEngineUrlFetcher('%s/%s' % (url_constants.SVN_URL, svn_path)),
65 AppEngineUrlFetcher('%s/%s' % (url_constants.VIEWVC_URL, svn_path)), 67 AppEngineUrlFetcher('%s/%s' % (url_constants.VIEWVC_URL, svn_path)),
66 svn_path) 68 svn_path,
69 revision=revision)
67 70
68 def __init__(self, file_fetcher, stat_fetcher, svn_path): 71 def __init__(self, file_fetcher, stat_fetcher, svn_path, revision=None):
69 self._file_fetcher = file_fetcher 72 self._file_fetcher = file_fetcher
70 self._stat_fetcher = stat_fetcher 73 self._stat_fetcher = stat_fetcher
71 self._svn_path = svn_path 74 self._svn_path = svn_path
75 self._revision = revision
72 76
73 def Read(self, paths, binary=False): 77 def Read(self, paths, binary=False):
78 args = None
79 if self._revision is not None:
80 # |fetcher| gets from svn.chromium.org which uses p= for version.
81 args = 'p=%s' % self._revision
74 return Future(delegate=_AsyncFetchFuture(paths, 82 return Future(delegate=_AsyncFetchFuture(paths,
75 self._file_fetcher, 83 self._file_fetcher,
76 binary)) 84 binary,
85 args=args))
77 86
78 def _ParseHTML(self, html): 87 def _ParseHTML(self, html):
79 '''Unfortunately, the viewvc page has a stray </div> tag, so this takes care 88 '''Unfortunately, the viewvc page has a stray </div> tag, so this takes care
80 of all mismatched tags. 89 of all mismatched tags.
81 ''' 90 '''
82 try: 91 try:
83 return xml.parseString(html) 92 return xml.parseString(html)
84 except ExpatError as e: 93 except ExpatError as e:
85 return self._ParseHTML('\n'.join( 94 return self._ParseHTML('\n'.join(
86 line for (i, line) in enumerate(html.split('\n')) 95 line for (i, line) in enumerate(html.split('\n'))
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 dict((path, str(version)) 144 dict((path, str(version))
136 for path, version in child_versions.iteritems())) 145 for path, version in child_versions.iteritems()))
137 146
138 # Bleh, but, this data is so unreliable. There are actually some empty file 147 # Bleh, but, this data is so unreliable. There are actually some empty file
139 # listings caused by git/svn/something not cleaning up empty dirs. 148 # listings caused by git/svn/something not cleaning up empty dirs.
140 return StatInfo('0', {}) 149 return StatInfo('0', {})
141 150
142 def Stat(self, path): 151 def Stat(self, path):
143 directory, filename = posixpath.split(path) 152 directory, filename = posixpath.split(path)
144 directory += '/' 153 directory += '/'
154 if self._revision is not None:
155 # |stat_fetch| uses viewvc which uses pathrev= for version.
156 directory += '?pathrev=%s' % self._revision
145 result = self._stat_fetcher.Fetch(directory) 157 result = self._stat_fetcher.Fetch(directory)
146 if result.status_code == 404: 158 if result.status_code == 404:
147 raise FileNotFoundError( 159 raise FileNotFoundError(
148 'Got 404 when fetching %s from %s for Stat' % (path, directory)) 160 'Got 404 when fetching %s from %s for Stat' % (path, directory))
149 stat_info = self._CreateStatInfo(result.content) 161 stat_info = self._CreateStatInfo(result.content)
150 if path.endswith('/'): 162 if path.endswith('/'):
151 return stat_info 163 return stat_info
152 if filename not in stat_info.child_versions: 164 if filename not in stat_info.child_versions:
153 raise FileNotFoundError('%s was not in child versions' % filename) 165 raise FileNotFoundError('%s was not in child versions' % filename)
154 return StatInfo(stat_info.child_versions[filename]) 166 return StatInfo(stat_info.child_versions[filename])
155 167
156 def GetIdentity(self): 168 def GetIdentity(self):
169 # NOTE: no revision here, consider it just an implementation detail of the
170 # file version that is handled by Stat.
157 return '@'.join((self.__class__.__name__, StringIdentity(self._svn_path))) 171 return '@'.join((self.__class__.__name__, StringIdentity(self._svn_path)))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698