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

Side by Side Diff: tools/telemetry/third_party/rope/rope/base/resources.py

Issue 1132103009: Example of refactoring using rope library. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
OLDNEW
(Empty)
1 """Files and folders in a project are represented as resource objects.
2
3 Files and folders are access through `Resource` objects. `Resource` has
4 two subclasses: `File` and `Folder`. What we care about is that
5 refactorings and `rope.base.change.Change`s use resources.
6
7 There are two options to create a `Resource` for a path in a project.
8 Note that in these examples `path` is the path to a file or folder
9 relative to the project's root. A project's root folder is represented
10 by an empty string.
11
12 1) Use the `rope.base.Project.get_resource()` method. E.g.:
13
14 myresource = myproject.get_resource(path)
15
16
17 2) Use the `rope.base.libutils` module. `libutils` has a function
18 named `path_to_resource()`. It takes a project and a path:
19
20 from rope.base import libutils
21
22 myresource = libutils.path_to_resource(myproject, path)
23
24 Once we have a `Resource`, we can retrieve information from it, like
25 getting the path relative to the project's root (via `path`), reading
26 from and writing to the resource, moving the resource, etc.
27 """
28
29 import os
30 import re
31
32 from rope.base import change
33 from rope.base import exceptions
34 from rope.base import fscommands
35
36
37 class Resource(object):
38 """Represents files and folders in a project"""
39
40 def __init__(self, project, path):
41 self.project = project
42 self._path = path
43
44 def move(self, new_location):
45 """Move resource to `new_location`"""
46 self._perform_change(change.MoveResource(self, new_location),
47 'Moving <%s> to <%s>' % (self.path, new_location))
48
49 def remove(self):
50 """Remove resource from the project"""
51 self._perform_change(change.RemoveResource(self),
52 'Removing <%s>' % self.path)
53
54 def is_folder(self):
55 """Return true if the resource is a folder"""
56
57 def create(self):
58 """Create this resource"""
59
60 def exists(self):
61 return os.path.exists(self.real_path)
62
63 @property
64 def parent(self):
65 parent = '/'.join(self.path.split('/')[0:-1])
66 return self.project.get_folder(parent)
67
68 @property
69 def path(self):
70 """Return the path of this resource relative to the project root
71
72 The path is the list of parent directories separated by '/' followed
73 by the resource name.
74 """
75 return self._path
76
77 @property
78 def name(self):
79 """Return the name of this resource"""
80 return self.path.split('/')[-1]
81
82 @property
83 def real_path(self):
84 """Return the file system path of this resource"""
85 return self.project._get_resource_path(self.path)
86
87 def __eq__(self, obj):
88 return self.__class__ == obj.__class__ and self.path == obj.path
89
90 def __ne__(self, obj):
91 return not self.__eq__(obj)
92
93 def __hash__(self):
94 return hash(self.path)
95
96 def _perform_change(self, change_, description):
97 changes = change.ChangeSet(description)
98 changes.add_change(change_)
99 self.project.do(changes)
100
101
102 class File(Resource):
103 """Represents a file"""
104
105 def __init__(self, project, name):
106 super(File, self).__init__(project, name)
107
108 def read(self):
109 data = self.read_bytes()
110 try:
111 return fscommands.file_data_to_unicode(data)
112 except UnicodeDecodeError as e:
113 raise exceptions.ModuleDecodeError(self.path, e.reason)
114
115 def read_bytes(self):
116 return open(self.real_path, 'rb').read()
117
118 def write(self, contents):
119 try:
120 if contents == self.read():
121 return
122 except IOError:
123 pass
124 self._perform_change(change.ChangeContents(self, contents),
125 'Writing file <%s>' % self.path)
126
127 def is_folder(self):
128 return False
129
130 def create(self):
131 self.parent.create_file(self.name)
132
133
134 class Folder(Resource):
135 """Represents a folder"""
136
137 def __init__(self, project, name):
138 super(Folder, self).__init__(project, name)
139
140 def is_folder(self):
141 return True
142
143 def get_children(self):
144 """Return the children of this folder"""
145 try:
146 children = os.listdir(self.real_path)
147 except OSError:
148 return []
149 result = []
150 for name in children:
151 try:
152 child = self.get_child(name)
153 except exceptions.ResourceNotFoundError:
154 continue
155 if not self.project.is_ignored(child):
156 result.append(self.get_child(name))
157 return result
158
159 def create_file(self, file_name):
160 self._perform_change(
161 change.CreateFile(self, file_name),
162 'Creating file <%s>' % self._get_child_path(file_name))
163 return self.get_child(file_name)
164
165 def create_folder(self, folder_name):
166 self._perform_change(
167 change.CreateFolder(self, folder_name),
168 'Creating folder <%s>' % self._get_child_path(folder_name))
169 return self.get_child(folder_name)
170
171 def _get_child_path(self, name):
172 if self.path:
173 return self.path + '/' + name
174 else:
175 return name
176
177 def get_child(self, name):
178 return self.project.get_resource(self._get_child_path(name))
179
180 def has_child(self, name):
181 try:
182 self.get_child(name)
183 return True
184 except exceptions.ResourceNotFoundError:
185 return False
186
187 def get_files(self):
188 return [resource for resource in self.get_children()
189 if not resource.is_folder()]
190
191 def get_folders(self):
192 return [resource for resource in self.get_children()
193 if resource.is_folder()]
194
195 def contains(self, resource):
196 if self == resource:
197 return False
198 return self.path == '' or resource.path.startswith(self.path + '/')
199
200 def create(self):
201 self.parent.create_folder(self.name)
202
203
204 class _ResourceMatcher(object):
205
206 def __init__(self):
207 self.patterns = []
208 self._compiled_patterns = []
209
210 def set_patterns(self, patterns):
211 """Specify which resources to match
212
213 `patterns` is a `list` of `str`\s that can contain ``*`` and
214 ``?`` signs for matching resource names.
215
216 """
217 self._compiled_patterns = None
218 self.patterns = patterns
219
220 def _add_pattern(self, pattern):
221 re_pattern = pattern.replace('.', '\\.').\
222 replace('*', '[^/]*').replace('?', '[^/]').\
223 replace('//', '/(.*/)?')
224 re_pattern = '^(.*/)?' + re_pattern + '(/.*)?$'
225 self.compiled_patterns.append(re.compile(re_pattern))
226
227 def does_match(self, resource):
228 for pattern in self.compiled_patterns:
229 if pattern.match(resource.path):
230 return True
231 path = os.path.join(resource.project.address,
232 *resource.path.split('/'))
233 if os.path.islink(path):
234 return True
235 return False
236
237 @property
238 def compiled_patterns(self):
239 if self._compiled_patterns is None:
240 self._compiled_patterns = []
241 for pattern in self.patterns:
242 self._add_pattern(pattern)
243 return self._compiled_patterns
OLDNEW
« no previous file with comments | « tools/telemetry/third_party/rope/rope/base/resourceobserver.py ('k') | tools/telemetry/third_party/rope/rope/base/simplify.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698