diff options
Diffstat (limited to 'command.py')
-rw-r--r-- | command.py | 73 |
1 files changed, 48 insertions, 25 deletions
@@ -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) |