diff options
Diffstat (limited to 'command.py')
-rw-r--r-- | command.py | 72 |
1 files changed, 48 insertions, 24 deletions
@@ -60,6 +60,32 @@ class Command(object): | |||
60 | """ | 60 | """ |
61 | raise NotImplementedError | 61 | raise NotImplementedError |
62 | 62 | ||
63 | def _ResetPathToProjectMap(self, projects): | ||
64 | self._by_path = dict((p.worktree, p) for p in projects) | ||
65 | |||
66 | def _UpdatePathToProjectMap(self, project): | ||
67 | self._by_path[project.worktree] = project | ||
68 | |||
69 | def _GetProjectByPath(self, path): | ||
70 | project = None | ||
71 | if os.path.exists(path): | ||
72 | oldpath = None | ||
73 | while path \ | ||
74 | and path != oldpath \ | ||
75 | and path != self.manifest.topdir: | ||
76 | try: | ||
77 | project = self._by_path[path] | ||
78 | break | ||
79 | except KeyError: | ||
80 | oldpath = path | ||
81 | path = os.path.dirname(path) | ||
82 | else: | ||
83 | try: | ||
84 | project = self._by_path[path] | ||
85 | except KeyError: | ||
86 | pass | ||
87 | return project | ||
88 | |||
63 | def GetProjects(self, args, missing_ok=False): | 89 | def GetProjects(self, args, missing_ok=False): |
64 | """A list of projects that match the arguments. | 90 | """A list of projects that match the arguments. |
65 | """ | 91 | """ |
@@ -74,40 +100,38 @@ class Command(object): | |||
74 | groups = [x for x in re.split('[,\s]+', groups) if x] | 100 | groups = [x for x in re.split('[,\s]+', groups) if x] |
75 | 101 | ||
76 | if not args: | 102 | if not args: |
77 | for project in all_projects.values(): | 103 | all_projects_list = all_projects.values() |
104 | derived_projects = [] | ||
105 | for project in all_projects_list: | ||
106 | if project.Registered: | ||
107 | # Do not search registered subproject for derived projects | ||
108 | # since its parent has been searched already | ||
109 | continue | ||
110 | derived_projects.extend(project.GetDerivedSubprojects()) | ||
111 | all_projects_list.extend(derived_projects) | ||
112 | for project in all_projects_list: | ||
78 | if ((missing_ok or project.Exists) and | 113 | if ((missing_ok or project.Exists) and |
79 | project.MatchesGroups(groups)): | 114 | project.MatchesGroups(groups)): |
80 | result.append(project) | 115 | result.append(project) |
81 | else: | 116 | else: |
82 | by_path = None | 117 | self._ResetPathToProjectMap(all_projects.values()) |
83 | 118 | ||
84 | for arg in args: | 119 | for arg in args: |
85 | project = all_projects.get(arg) | 120 | project = all_projects.get(arg) |
86 | 121 | ||
87 | if not project: | 122 | if not project: |
88 | path = os.path.abspath(arg).replace('\\', '/') | 123 | path = os.path.abspath(arg).replace('\\', '/') |
89 | 124 | project = self._GetProjectByPath(path) | |
90 | if not by_path: | 125 | |
91 | by_path = dict() | 126 | # If it's not a derived project, update path->project mapping and |
92 | for p in all_projects.values(): | 127 | # search again, as arg might actually point to a derived subproject. |
93 | by_path[p.worktree] = p | 128 | if project and not project.Derived: |
94 | 129 | search_again = False | |
95 | if os.path.exists(path): | 130 | for subproject in project.GetDerivedSubprojects(): |
96 | oldpath = None | 131 | self._UpdatePathToProjectMap(subproject) |
97 | while path \ | 132 | search_again = True |
98 | and path != oldpath \ | 133 | if search_again: |
99 | and path != self.manifest.topdir: | 134 | project = self._GetProjectByPath(path) or project |
100 | try: | ||
101 | project = by_path[path] | ||
102 | break | ||
103 | except KeyError: | ||
104 | oldpath = path | ||
105 | path = os.path.dirname(path) | ||
106 | else: | ||
107 | try: | ||
108 | project = by_path[path] | ||
109 | except KeyError: | ||
110 | pass | ||
111 | 135 | ||
112 | if not project: | 136 | if not project: |
113 | raise NoSuchProjectError(arg) | 137 | raise NoSuchProjectError(arg) |