summaryrefslogtreecommitdiffstats
path: root/command.py
diff options
context:
space:
mode:
Diffstat (limited to 'command.py')
-rw-r--r--command.py73
1 files changed, 48 insertions, 25 deletions
diff --git a/command.py b/command.py
index dc6052a7..96d7848f 100644
--- a/command.py
+++ b/command.py
@@ -100,7 +100,33 @@ class Command(object):
100 """ 100 """
101 raise NotImplementedError 101 raise NotImplementedError
102 102
103 def GetProjects(self, args, missing_ok=False): 103 def _ResetPathToProjectMap(self, projects):
104 self._by_path = dict((p.worktree, p) for p in projects)
105
106 def _UpdatePathToProjectMap(self, project):
107 self._by_path[project.worktree] = project
108
109 def _GetProjectByPath(self, path):
110 project = None
111 if os.path.exists(path):
112 oldpath = None
113 while path \
114 and path != oldpath \
115 and path != self.manifest.topdir:
116 try:
117 project = self._by_path[path]
118 break
119 except KeyError:
120 oldpath = path
121 path = os.path.dirname(path)
122 else:
123 try:
124 project = self._by_path[path]
125 except KeyError:
126 pass
127 return project
128
129 def GetProjects(self, args, missing_ok=False, submodules_ok=False):
104 """A list of projects that match the arguments. 130 """A list of projects that match the arguments.
105 """ 131 """
106 all_projects = self.manifest.projects 132 all_projects = self.manifest.projects
@@ -114,40 +140,37 @@ class Command(object):
114 groups = [x for x in re.split(r'[,\s]+', groups) if x] 140 groups = [x for x in re.split(r'[,\s]+', groups) if x]
115 141
116 if not args: 142 if not args:
117 for project in all_projects.values(): 143 all_projects_list = all_projects.values()
144 derived_projects = {}
145 for project in all_projects_list:
146 if submodules_ok or project.sync_s:
147 derived_projects.update((p.name, p)
148 for p in project.GetDerivedSubprojects())
149 all_projects_list.extend(derived_projects.values())
150 for project in all_projects_list:
118 if ((missing_ok or project.Exists) and 151 if ((missing_ok or project.Exists) and
119 project.MatchesGroups(groups)): 152 project.MatchesGroups(groups)):
120 result.append(project) 153 result.append(project)
121 else: 154 else:
122 by_path = None 155 self._ResetPathToProjectMap(all_projects.values())
123 156
124 for arg in args: 157 for arg in args:
125 project = all_projects.get(arg) 158 project = all_projects.get(arg)
126 159
127 if not project: 160 if not project:
128 path = os.path.abspath(arg).replace('\\', '/') 161 path = os.path.abspath(arg).replace('\\', '/')
129 162 project = self._GetProjectByPath(path)
130 if not by_path: 163
131 by_path = dict() 164 # If it's not a derived project, update path->project mapping and
132 for p in all_projects.values(): 165 # search again, as arg might actually point to a derived subproject.
133 by_path[p.worktree] = p 166 if (project and not project.Derived and
134 167 (submodules_ok or project.sync_s)):
135 if os.path.exists(path): 168 search_again = False
136 oldpath = None 169 for subproject in project.GetDerivedSubprojects():
137 while path \ 170 self._UpdatePathToProjectMap(subproject)
138 and path != oldpath \ 171 search_again = True
139 and path != self.manifest.topdir: 172 if search_again:
140 try: 173 project = self._GetProjectByPath(path) or project
141 project = by_path[path]
142 break
143 except KeyError:
144 oldpath = path
145 path = os.path.dirname(path)
146 else:
147 try:
148 project = by_path[path]
149 except KeyError:
150 pass
151 174
152 if not project: 175 if not project:
153 raise NoSuchProjectError(arg) 176 raise NoSuchProjectError(arg)