diff options
Diffstat (limited to 'git_superproject.py')
-rw-r--r-- | git_superproject.py | 100 |
1 files changed, 85 insertions, 15 deletions
diff --git a/git_superproject.py b/git_superproject.py index e2045cfd..465d1f87 100644 --- a/git_superproject.py +++ b/git_superproject.py | |||
@@ -25,8 +25,9 @@ Examples: | |||
25 | import os | 25 | import os |
26 | import sys | 26 | import sys |
27 | 27 | ||
28 | from error import GitError | 28 | from error import BUG_REPORT_URL, GitError |
29 | from git_command import GitCommand | 29 | from git_command import GitCommand |
30 | import platform_utils | ||
30 | 31 | ||
31 | 32 | ||
32 | class Superproject(object): | 33 | class Superproject(object): |
@@ -46,6 +47,9 @@ class Superproject(object): | |||
46 | self._repodir = os.path.abspath(repodir) | 47 | self._repodir = os.path.abspath(repodir) |
47 | self._superproject_dir = superproject_dir | 48 | self._superproject_dir = superproject_dir |
48 | self._superproject_path = os.path.join(self._repodir, superproject_dir) | 49 | self._superproject_path = os.path.join(self._repodir, superproject_dir) |
50 | self._manifest_path = os.path.join(self._superproject_path, | ||
51 | 'superproject_override.xml') | ||
52 | self._work_git = os.path.join(self._superproject_path, 'superproject') | ||
49 | 53 | ||
50 | @property | 54 | @property |
51 | def project_shas(self): | 55 | def project_shas(self): |
@@ -57,7 +61,7 @@ class Superproject(object): | |||
57 | 61 | ||
58 | Args: | 62 | Args: |
59 | url: superproject's url to be passed to git clone. | 63 | url: superproject's url to be passed to git clone. |
60 | branch: the branchname to be passed as argument to git clone. | 64 | branch: The branchname to be passed as argument to git clone. |
61 | 65 | ||
62 | Returns: | 66 | Returns: |
63 | True if 'git clone <url> <branch>' is successful, or False. | 67 | True if 'git clone <url> <branch>' is successful, or False. |
@@ -86,13 +90,12 @@ class Superproject(object): | |||
86 | Returns: | 90 | Returns: |
87 | True if 'git pull <branch>' is successful, or False. | 91 | True if 'git pull <branch>' is successful, or False. |
88 | """ | 92 | """ |
89 | git_dir = os.path.join(self._superproject_path, 'superproject') | 93 | if not os.path.exists(self._work_git): |
90 | if not os.path.exists(git_dir): | 94 | raise GitError('git pull missing drectory: %s' % self._work_git) |
91 | raise GitError('git pull. Missing drectory: %s' % git_dir) | ||
92 | cmd = ['pull'] | 95 | cmd = ['pull'] |
93 | p = GitCommand(None, | 96 | p = GitCommand(None, |
94 | cmd, | 97 | cmd, |
95 | cwd=git_dir, | 98 | cwd=self._work_git, |
96 | capture_stdout=True, | 99 | capture_stdout=True, |
97 | capture_stderr=True) | 100 | capture_stderr=True) |
98 | retval = p.Wait() | 101 | retval = p.Wait() |
@@ -110,14 +113,13 @@ class Superproject(object): | |||
110 | Returns: | 113 | Returns: |
111 | data: data returned from 'git ls-tree -r HEAD' instead of None. | 114 | data: data returned from 'git ls-tree -r HEAD' instead of None. |
112 | """ | 115 | """ |
113 | git_dir = os.path.join(self._superproject_path, 'superproject') | 116 | if not os.path.exists(self._work_git): |
114 | if not os.path.exists(git_dir): | 117 | raise GitError('git ls-tree. Missing drectory: %s' % self._work_git) |
115 | raise GitError('git ls-tree. Missing drectory: %s' % git_dir) | ||
116 | data = None | 118 | data = None |
117 | cmd = ['ls-tree', '-z', '-r', 'HEAD'] | 119 | cmd = ['ls-tree', '-z', '-r', 'HEAD'] |
118 | p = GitCommand(None, | 120 | p = GitCommand(None, |
119 | cmd, | 121 | cmd, |
120 | cwd=git_dir, | 122 | cwd=self._work_git, |
121 | capture_stdout=True, | 123 | capture_stdout=True, |
122 | capture_stderr=True) | 124 | capture_stderr=True) |
123 | retval = p.Wait() | 125 | retval = p.Wait() |
@@ -130,22 +132,26 @@ class Superproject(object): | |||
130 | retval, p.stderr), file=sys.stderr) | 132 | retval, p.stderr), file=sys.stderr) |
131 | return data | 133 | return data |
132 | 134 | ||
133 | def GetAllProjectsSHAs(self, url, branch=None): | 135 | def _GetAllProjectsSHAs(self, url, branch=None): |
134 | """Get SHAs for all projects from superproject and save them in _project_shas. | 136 | """Get SHAs for all projects from superproject and save them in _project_shas. |
135 | 137 | ||
136 | Args: | 138 | Args: |
137 | url: superproject's url to be passed to git clone. | 139 | url: superproject's url to be passed to git clone or pull. |
138 | branch: the branchname to be passed as argument to git clone. | 140 | branch: The branchname to be passed as argument to git clone or pull. |
139 | 141 | ||
140 | Returns: | 142 | Returns: |
141 | A dictionary with the projects/SHAs instead of None. | 143 | A dictionary with the projects/SHAs instead of None. |
142 | """ | 144 | """ |
143 | if not url: | 145 | if not url: |
144 | raise ValueError('url argument is not supplied.') | 146 | raise ValueError('url argument is not supplied.') |
147 | do_clone = True | ||
145 | if os.path.exists(self._superproject_path): | 148 | if os.path.exists(self._superproject_path): |
146 | if not self._Pull(): | 149 | if not self._Pull(): |
147 | raise GitError('git pull failed for url: %s' % url) | 150 | # If pull fails due to a corrupted git directory, then do a git clone. |
148 | else: | 151 | platform_utils.rmtree(self._superproject_path) |
152 | else: | ||
153 | do_clone = False | ||
154 | if do_clone: | ||
149 | if not self._Clone(url, branch): | 155 | if not self._Clone(url, branch): |
150 | raise GitError('git clone failed for url: %s' % url) | 156 | raise GitError('git clone failed for url: %s' % url) |
151 | 157 | ||
@@ -168,3 +174,67 @@ class Superproject(object): | |||
168 | 174 | ||
169 | self._project_shas = shas | 175 | self._project_shas = shas |
170 | return shas | 176 | return shas |
177 | |||
178 | def _WriteManfiestFile(self, manifest): | ||
179 | """Writes manifest to a file. | ||
180 | |||
181 | Args: | ||
182 | manifest: A Manifest object that is to be written to a file. | ||
183 | |||
184 | Returns: | ||
185 | manifest_path: Path name of the file into which manifest is written instead of None. | ||
186 | """ | ||
187 | if not os.path.exists(self._superproject_path): | ||
188 | print('error: missing superproject directory %s' % | ||
189 | self._superproject_path, | ||
190 | file=sys.stderr) | ||
191 | return None | ||
192 | manifest_str = manifest.ToXml().toxml() | ||
193 | manifest_path = self._manifest_path | ||
194 | try: | ||
195 | with open(manifest_path, 'w', encoding='utf-8') as fp: | ||
196 | fp.write(manifest_str) | ||
197 | except IOError as e: | ||
198 | print('error: cannot write manifest to %s:\n%s' | ||
199 | % (manifest_path, e), | ||
200 | file=sys.stderr) | ||
201 | return None | ||
202 | return manifest_path | ||
203 | |||
204 | def UpdateProjectsRevisionId(self, manifest, projects, url, branch=None): | ||
205 | """Update revisionId of every project in projects with the SHA. | ||
206 | |||
207 | Args: | ||
208 | manifest: A Manifest object that is to be written to a file. | ||
209 | projects: List of projects whose revisionId needs to be updated. | ||
210 | url: superproject's url to be passed to git clone or fetch. | ||
211 | branch: The branchname to be passed as argument to git clone or pull. | ||
212 | |||
213 | Returns: | ||
214 | manifest_path: Path name of the overriding manfiest file instead of None. | ||
215 | """ | ||
216 | try: | ||
217 | shas = self._GetAllProjectsSHAs(url=url, branch=branch) | ||
218 | except Exception as e: | ||
219 | print('error: Cannot get project SHAs for %s: %s: %s' % | ||
220 | (url, type(e).__name__, str(e)), | ||
221 | file=sys.stderr) | ||
222 | return None | ||
223 | |||
224 | projects_missing_shas = [] | ||
225 | for project in projects: | ||
226 | path = project.relpath | ||
227 | if not path: | ||
228 | continue | ||
229 | sha = shas.get(path) | ||
230 | if sha: | ||
231 | project.SetRevisionId(sha) | ||
232 | else: | ||
233 | projects_missing_shas.append(path) | ||
234 | if projects_missing_shas: | ||
235 | print('error: please file a bug using %s to report missing shas for: %s' % | ||
236 | (BUG_REPORT_URL, projects_missing_shas), file=sys.stderr) | ||
237 | return None | ||
238 | |||
239 | manifest_path = self._WriteManfiestFile(manifest) | ||
240 | return manifest_path | ||