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

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

Issue 14125010: Docserver: Add support for viewing docs with a codereview patch applied (Closed) Base URL: https://src.chromium.org/svn/trunk/src/
Patch Set: 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 from copy import deepcopy
6 import logging
7
8 from file_system import FileSystem, StatInfo, FileNotFoundError
9 from future import Future
10
11 class _AsyncFetchFuture(object):
12 def __init__(self,
13 svn_files_future,
14 patched_files_future,
15 svn_dirs_future,
16 dir_paths,
17 patched_file_system,
18 patcher):
19 self._svn_files_future = svn_files_future
20 self._patched_files_future = patched_files_future
21 self._svn_dirs_future = svn_dirs_future
22 self._dir_paths = dir_paths
23 self._patched_file_system = patched_file_system
24 self._patcher = patcher
not at google - send to devlin 2013/05/03 19:12:22 don't seem to be using this
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
25
26 def Get(self):
27 files = self._svn_files_future.Get()
28 files.update(self._patched_files_future.Get())
29 dirs = self._svn_dirs_future.Get()
30 files.update({path: self._PatchDirectoryListing(path,
31 dirs[path])
not at google - send to devlin 2013/05/03 19:12:22 why is this on a line by itself?
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
32 for path in self._dir_paths})
33 return files
34
35 def _PatchDirectoryListing(self, path, original_listing):
36 added, deleted, modified = (
37 self._patched_file_system._GetDirectoryListingFromPatch(path))
38 return list(set(original_listing) | set(added) - set(deleted))
39
40 class Patcher(object):
41 def GetPatchedFiles(self):
42 ''' Returns (added_files, deleted_files, modified_files).
43 '''
44 raise NotImplementedError()
45
46 def GetVersion(self):
47 ''' Returns patch version. Returns None when nothing is patched by the
48 pathcer.
49 '''
50 raise NotImplementedError()
51
52 def Apply(self, paths, file_system, binary):
53 ''' Apply the patch to added/modified files. Returns Future with patched
54 data. Throws FileNotFoundError if |paths| contains deleted files.
55 '''
56 raise NotImplementedError()
not at google - send to devlin 2013/05/03 19:12:22 pls put this in a different file.
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
57
58 class PatchedFileSystem(FileSystem):
59 ''' Class to fetch resources with a patch applied.
60 '''
61 def __init__(self, svn_file_system, patcher):
not at google - send to devlin 2013/05/03 19:12:22 I'm going to start calling svn_file_system 'host_f
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
62 self._svn_file_system = svn_file_system
63 self._patcher = patcher
64
65 def Read(self, paths, binary=False):
66 patched_files = set()
67 for files in self._patcher.GetPatchedFiles():
68 patched_files |= set(files)
69 dir_paths = {path for path in paths if path.endswith('/')}
70 file_paths = set(paths) - dir_paths
71 patched_paths = file_paths & patched_files
72 unpatched_paths = file_paths - patched_files
73 return Future(delegate=_AsyncFetchFuture(
74 self._svn_file_system.Read(unpatched_paths, binary),
75 self._patcher.Apply(patched_paths, self._svn_file_system, binary),
76 self._svn_file_system.Read(dir_paths, binary),
77 dir_paths,
78 self,
79 self._patcher))
80
81 def _GetDirectoryListingFromPatch(self, path):
82 assert path.endswith('/')
83 def _FindChildrenInPath(files, path):
84 result = []
85 for f in files:
86 if f.startswith(path):
87 child_path = f[len(path):]
88 if '/' in child_path:
89 child_name = child_path[0:child_path.find('/') + 1]
90 else:
91 child_name = child_path
92 result.append(child_name)
93 return result
94
95 return (tuple(_FindChildrenInPath(files, path)
96 for files in self._patcher.GetPatchedFiles()))
97
98 def _PatchStat(self, stat_info, version, added, deleted, modified):
99 assert len(added) + len(deleted) + len(modified) > 0
100
101 # Deep copy before patching to make sure it doesn't interfere with values
102 # cached in memory.
103 stat_info = deepcopy(stat_info)
not at google - send to devlin 2013/05/03 19:12:22 yep, thanks
104
105 stat_info.version = version
106 if stat_info.child_versions is not None:
107 for child in added + modified:
108 stat_info.child_versions[child] = version
109 for child in deleted:
110 if stat_info.child_versions.get(child):
111 del stat_info.child_versions[child]
112
113 return stat_info
114
115 def Stat(self, path):
116 version = self._patcher.GetVersion()
117 if version is None:
118 return self._svn_file_system.Stat(path)
119 version = 'patched_%s' % version
120
121 directory, filename = path.rsplit('/', 1)
122 added, deleted, modified = self._GetDirectoryListingFromPatch(
123 directory + '/')
124
125 if len(added) > 0:
126 # There are new files added. It's possible (if |directory| is new) that
127 # self._svn_file_system.Stat will throw an exception.
128 try:
129 stat_info = self._PatchStat(self._svn_file_system.Stat(directory + '/'),
130 version,
131 added,
132 deleted,
133 modified)
134 except FileNotFoundError:
135 stat_info = StatInfo(version, {child: version
136 for child in added + modified})
137 elif len(deleted) + len(modified) > 0:
138 # No files were added.
139 stat_info = self._PatchStat(self._svn_file_system.Stat(path),
140 version,
141 added,
142 deleted,
143 modified)
144 else:
145 # No changes are made in this directory.
146 return self._svn_file_system.Stat(path)
147
148 if stat_info.child_versions is not None:
149 if filename:
150 if filename in stat_info.child_versions:
151 stat_info.version = stat_info.child_versions[filename]
152 else:
153 raise FileNotFoundError('%s was not in child versions' % filename)
154 return stat_info
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698