diff options
Diffstat (limited to 'command.py')
-rw-r--r-- | command.py | 65 |
1 files changed, 44 insertions, 21 deletions
@@ -31,7 +31,7 @@ class Command(object): | |||
31 | manifest = None | 31 | manifest = None |
32 | _optparse = None | 32 | _optparse = None |
33 | 33 | ||
34 | def WantPager(self, opt): | 34 | def WantPager(self, _opt): |
35 | return False | 35 | return False |
36 | 36 | ||
37 | def ReadEnvironmentOptions(self, opts): | 37 | def ReadEnvironmentOptions(self, opts): |
@@ -63,7 +63,7 @@ class Command(object): | |||
63 | usage = self.helpUsage.strip().replace('%prog', me) | 63 | usage = self.helpUsage.strip().replace('%prog', me) |
64 | except AttributeError: | 64 | except AttributeError: |
65 | usage = 'repo %s' % self.NAME | 65 | usage = 'repo %s' % self.NAME |
66 | self._optparse = optparse.OptionParser(usage = usage) | 66 | self._optparse = optparse.OptionParser(usage=usage) |
67 | self._Options(self._optparse) | 67 | self._Options(self._optparse) |
68 | return self._optparse | 68 | return self._optparse |
69 | 69 | ||
@@ -106,13 +106,13 @@ class Command(object): | |||
106 | def _UpdatePathToProjectMap(self, project): | 106 | def _UpdatePathToProjectMap(self, project): |
107 | self._by_path[project.worktree] = project | 107 | self._by_path[project.worktree] = project |
108 | 108 | ||
109 | def _GetProjectByPath(self, path): | 109 | def _GetProjectByPath(self, manifest, path): |
110 | project = None | 110 | project = None |
111 | if os.path.exists(path): | 111 | if os.path.exists(path): |
112 | oldpath = None | 112 | oldpath = None |
113 | while path \ | 113 | while path and \ |
114 | and path != oldpath \ | 114 | path != oldpath and \ |
115 | and path != self.manifest.topdir: | 115 | path != manifest.topdir: |
116 | try: | 116 | try: |
117 | project = self._by_path[path] | 117 | project = self._by_path[path] |
118 | break | 118 | break |
@@ -126,16 +126,19 @@ class Command(object): | |||
126 | pass | 126 | pass |
127 | return project | 127 | return project |
128 | 128 | ||
129 | def GetProjects(self, args, groups='', missing_ok=False, submodules_ok=False): | 129 | def GetProjects(self, args, manifest=None, groups='', missing_ok=False, |
130 | submodules_ok=False): | ||
130 | """A list of projects that match the arguments. | 131 | """A list of projects that match the arguments. |
131 | """ | 132 | """ |
132 | all_projects_list = self.manifest.projects | 133 | if not manifest: |
134 | manifest = self.manifest | ||
135 | all_projects_list = manifest.projects | ||
133 | result = [] | 136 | result = [] |
134 | 137 | ||
135 | mp = self.manifest.manifestProject | 138 | mp = manifest.manifestProject |
136 | 139 | ||
137 | if not groups: | 140 | if not groups: |
138 | groups = mp.config.GetString('manifest.groups') | 141 | groups = mp.config.GetString('manifest.groups') |
139 | if not groups: | 142 | if not groups: |
140 | groups = 'default,platform-' + platform.system().lower() | 143 | groups = 'default,platform-' + platform.system().lower() |
141 | groups = [x for x in re.split(r'[,\s]+', groups) if x] | 144 | groups = [x for x in re.split(r'[,\s]+', groups) if x] |
@@ -148,29 +151,28 @@ class Command(object): | |||
148 | for p in project.GetDerivedSubprojects()) | 151 | for p in project.GetDerivedSubprojects()) |
149 | all_projects_list.extend(derived_projects.values()) | 152 | all_projects_list.extend(derived_projects.values()) |
150 | for project in all_projects_list: | 153 | for project in all_projects_list: |
151 | if ((missing_ok or project.Exists) and | 154 | if (missing_ok or project.Exists) and project.MatchesGroups(groups): |
152 | project.MatchesGroups(groups)): | ||
153 | result.append(project) | 155 | result.append(project) |
154 | else: | 156 | else: |
155 | self._ResetPathToProjectMap(all_projects_list) | 157 | self._ResetPathToProjectMap(all_projects_list) |
156 | 158 | ||
157 | for arg in args: | 159 | for arg in args: |
158 | projects = self.manifest.GetProjectsWithName(arg) | 160 | projects = manifest.GetProjectsWithName(arg) |
159 | 161 | ||
160 | if not projects: | 162 | if not projects: |
161 | path = os.path.abspath(arg).replace('\\', '/') | 163 | path = os.path.abspath(arg).replace('\\', '/') |
162 | project = self._GetProjectByPath(path) | 164 | project = self._GetProjectByPath(manifest, path) |
163 | 165 | ||
164 | # If it's not a derived project, update path->project mapping and | 166 | # If it's not a derived project, update path->project mapping and |
165 | # search again, as arg might actually point to a derived subproject. | 167 | # search again, as arg might actually point to a derived subproject. |
166 | if (project and not project.Derived and | 168 | if (project and not project.Derived and (submodules_ok or |
167 | (submodules_ok or project.sync_s)): | 169 | project.sync_s)): |
168 | search_again = False | 170 | search_again = False |
169 | for subproject in project.GetDerivedSubprojects(): | 171 | for subproject in project.GetDerivedSubprojects(): |
170 | self._UpdatePathToProjectMap(subproject) | 172 | self._UpdatePathToProjectMap(subproject) |
171 | search_again = True | 173 | search_again = True |
172 | if search_again: | 174 | if search_again: |
173 | project = self._GetProjectByPath(path) or project | 175 | project = self._GetProjectByPath(manifest, path) or project |
174 | 176 | ||
175 | if project: | 177 | if project: |
176 | projects = [project] | 178 | projects = [project] |
@@ -191,17 +193,24 @@ class Command(object): | |||
191 | result.sort(key=_getpath) | 193 | result.sort(key=_getpath) |
192 | return result | 194 | return result |
193 | 195 | ||
194 | def FindProjects(self, args): | 196 | def FindProjects(self, args, inverse=False): |
195 | result = [] | 197 | result = [] |
196 | patterns = [re.compile(r'%s' % a, re.IGNORECASE) for a in args] | 198 | patterns = [re.compile(r'%s' % a, re.IGNORECASE) for a in args] |
197 | for project in self.GetProjects(''): | 199 | for project in self.GetProjects(''): |
198 | for pattern in patterns: | 200 | for pattern in patterns: |
199 | if pattern.search(project.name) or pattern.search(project.relpath): | 201 | match = pattern.search(project.name) or pattern.search(project.relpath) |
202 | if not inverse and match: | ||
200 | result.append(project) | 203 | result.append(project) |
201 | break | 204 | break |
205 | if inverse and match: | ||
206 | break | ||
207 | else: | ||
208 | if inverse: | ||
209 | result.append(project) | ||
202 | result.sort(key=lambda project: project.relpath) | 210 | result.sort(key=lambda project: project.relpath) |
203 | return result | 211 | return result |
204 | 212 | ||
213 | |||
205 | # pylint: disable=W0223 | 214 | # pylint: disable=W0223 |
206 | # Pylint warns that the `InteractiveCommand` and `PagedCommand` classes do not | 215 | # Pylint warns that the `InteractiveCommand` and `PagedCommand` classes do not |
207 | # override method `Execute` which is abstract in `Command`. Since that method | 216 | # override method `Execute` which is abstract in `Command`. Since that method |
@@ -211,19 +220,33 @@ class InteractiveCommand(Command): | |||
211 | """Command which requires user interaction on the tty and | 220 | """Command which requires user interaction on the tty and |
212 | must not run within a pager, even if the user asks to. | 221 | must not run within a pager, even if the user asks to. |
213 | """ | 222 | """ |
214 | def WantPager(self, opt): | 223 | def WantPager(self, _opt): |
215 | return False | 224 | return False |
216 | 225 | ||
226 | |||
217 | class PagedCommand(Command): | 227 | class PagedCommand(Command): |
218 | """Command which defaults to output in a pager, as its | 228 | """Command which defaults to output in a pager, as its |
219 | display tends to be larger than one screen full. | 229 | display tends to be larger than one screen full. |
220 | """ | 230 | """ |
221 | def WantPager(self, opt): | 231 | def WantPager(self, _opt): |
222 | return True | 232 | return True |
223 | 233 | ||
224 | # pylint: enable=W0223 | 234 | # pylint: enable=W0223 |
225 | 235 | ||
236 | |||
226 | class MirrorSafeCommand(object): | 237 | class MirrorSafeCommand(object): |
227 | """Command permits itself to run within a mirror, | 238 | """Command permits itself to run within a mirror, |
228 | and does not require a working directory. | 239 | and does not require a working directory. |
229 | """ | 240 | """ |
241 | |||
242 | |||
243 | class GitcAvailableCommand(object): | ||
244 | """Command that requires GITC to be available, but does | ||
245 | not require the local client to be a GITC client. | ||
246 | """ | ||
247 | |||
248 | |||
249 | class GitcClientCommand(object): | ||
250 | """Command that requires the local client to be a GITC | ||
251 | client. | ||
252 | """ | ||