diff options
Diffstat (limited to 'bitbake/lib/bb/fetch2/gitsm.py')
-rw-r--r-- | bitbake/lib/bb/fetch2/gitsm.py | 159 |
1 files changed, 80 insertions, 79 deletions
diff --git a/bitbake/lib/bb/fetch2/gitsm.py b/bitbake/lib/bb/fetch2/gitsm.py index a4527bf364..5869e1b99b 100644 --- a/bitbake/lib/bb/fetch2/gitsm.py +++ b/bitbake/lib/bb/fetch2/gitsm.py | |||
@@ -62,36 +62,35 @@ class GitSM(Git): | |||
62 | return modules | 62 | return modules |
63 | 63 | ||
64 | # Collect the defined submodules, and their attributes | 64 | # Collect the defined submodules, and their attributes |
65 | for name in ud.names: | 65 | try: |
66 | gitmodules = runfetchcmd("%s show %s:.gitmodules" % (ud.basecmd, ud.revision), d, quiet=True, workdir=workdir) | ||
67 | except: | ||
68 | # No submodules to update | ||
69 | gitmodules = "" | ||
70 | |||
71 | for m, md in parse_gitmodules(gitmodules).items(): | ||
66 | try: | 72 | try: |
67 | gitmodules = runfetchcmd("%s show %s:.gitmodules" % (ud.basecmd, ud.revisions[name]), d, quiet=True, workdir=workdir) | 73 | module_hash = runfetchcmd("%s ls-tree -z -d %s %s" % (ud.basecmd, ud.revision, md['path']), d, quiet=True, workdir=workdir) |
68 | except: | 74 | except: |
69 | # No submodules to update | 75 | # If the command fails, we don't have a valid file to check. If it doesn't |
76 | # fail -- it still might be a failure, see next check... | ||
77 | module_hash = "" | ||
78 | |||
79 | if not module_hash: | ||
80 | logger.debug("submodule %s is defined, but is not initialized in the repository. Skipping", m) | ||
70 | continue | 81 | continue |
71 | 82 | ||
72 | for m, md in parse_gitmodules(gitmodules).items(): | 83 | submodules.append(m) |
73 | try: | 84 | paths[m] = md['path'] |
74 | module_hash = runfetchcmd("%s ls-tree -z -d %s %s" % (ud.basecmd, ud.revisions[name], md['path']), d, quiet=True, workdir=workdir) | 85 | revision[m] = ud.revision |
75 | except: | 86 | uris[m] = md['url'] |
76 | # If the command fails, we don't have a valid file to check. If it doesn't | 87 | subrevision[m] = module_hash.split()[2] |
77 | # fail -- it still might be a failure, see next check... | 88 | |
78 | module_hash = "" | 89 | # Convert relative to absolute uri based on parent uri |
79 | 90 | if uris[m].startswith('..') or uris[m].startswith('./'): | |
80 | if not module_hash: | 91 | newud = copy.copy(ud) |
81 | logger.debug("submodule %s is defined, but is not initialized in the repository. Skipping", m) | 92 | newud.path = os.path.normpath(os.path.join(newud.path, uris[m])) |
82 | continue | 93 | uris[m] = Git._get_repo_url(self, newud) |
83 | |||
84 | submodules.append(m) | ||
85 | paths[m] = md['path'] | ||
86 | revision[m] = ud.revisions[name] | ||
87 | uris[m] = md['url'] | ||
88 | subrevision[m] = module_hash.split()[2] | ||
89 | |||
90 | # Convert relative to absolute uri based on parent uri | ||
91 | if uris[m].startswith('..'): | ||
92 | newud = copy.copy(ud) | ||
93 | newud.path = os.path.realpath(os.path.join(newud.path, uris[m])) | ||
94 | uris[m] = Git._get_repo_url(self, newud) | ||
95 | 94 | ||
96 | for module in submodules: | 95 | for module in submodules: |
97 | # Translate the module url into a SRC_URI | 96 | # Translate the module url into a SRC_URI |
@@ -115,10 +114,21 @@ class GitSM(Git): | |||
115 | # This has to be a file reference | 114 | # This has to be a file reference |
116 | proto = "file" | 115 | proto = "file" |
117 | url = "gitsm://" + uris[module] | 116 | url = "gitsm://" + uris[module] |
117 | if url.endswith("{}{}".format(ud.host, ud.path)): | ||
118 | raise bb.fetch2.FetchError("Submodule refers to the parent repository. This will cause deadlock situation in current version of Bitbake." \ | ||
119 | "Consider using git fetcher instead.") | ||
118 | 120 | ||
119 | url += ';protocol=%s' % proto | 121 | url += ';protocol=%s' % proto |
120 | url += ";name=%s" % module | 122 | url += ";name=%s" % module |
121 | url += ";subpath=%s" % module | 123 | url += ";subpath=%s" % module |
124 | url += ";nobranch=1" | ||
125 | url += ";lfs=%s" % ("1" if self._need_lfs(ud) else "0") | ||
126 | # Note that adding "user=" here to give credentials to the | ||
127 | # submodule is not supported. Since using SRC_URI to give git:// | ||
128 | # URL a password is not supported, one have to use one of the | ||
129 | # recommended way (eg. ~/.netrc or SSH config) which does specify | ||
130 | # the user (See comment in git.py). | ||
131 | # So, we will not take patches adding "user=" support here. | ||
122 | 132 | ||
123 | ld = d.createCopy() | 133 | ld = d.createCopy() |
124 | # Not necessary to set SRC_URI, since we're passing the URI to | 134 | # Not necessary to set SRC_URI, since we're passing the URI to |
@@ -136,20 +146,26 @@ class GitSM(Git): | |||
136 | 146 | ||
137 | return submodules != [] | 147 | return submodules != [] |
138 | 148 | ||
149 | def call_process_submodules(self, ud, d, extra_check, subfunc): | ||
150 | # If we're using a shallow mirror tarball it needs to be | ||
151 | # unpacked temporarily so that we can examine the .gitmodules file | ||
152 | # Unpack even when ud.clonedir is not available, | ||
153 | # which may occur during a fast shallow clone | ||
154 | unpack = extra_check or not os.path.exists(ud.clonedir) | ||
155 | if ud.shallow and os.path.exists(ud.fullshallow) and unpack: | ||
156 | tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR")) | ||
157 | try: | ||
158 | runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=tmpdir) | ||
159 | self.process_submodules(ud, tmpdir, subfunc, d) | ||
160 | finally: | ||
161 | shutil.rmtree(tmpdir) | ||
162 | else: | ||
163 | self.process_submodules(ud, ud.clonedir, subfunc, d) | ||
164 | |||
139 | def need_update(self, ud, d): | 165 | def need_update(self, ud, d): |
140 | if Git.need_update(self, ud, d): | 166 | if Git.need_update(self, ud, d): |
141 | return True | 167 | return True |
142 | 168 | ||
143 | try: | ||
144 | # Check for the nugget dropped by the download operation | ||
145 | known_srcrevs = runfetchcmd("%s config --get-all bitbake.srcrev" % \ | ||
146 | (ud.basecmd), d, workdir=ud.clonedir) | ||
147 | |||
148 | if ud.revisions[ud.names[0]] in known_srcrevs.split(): | ||
149 | return False | ||
150 | except bb.fetch2.FetchError: | ||
151 | pass | ||
152 | |||
153 | need_update_list = [] | 169 | need_update_list = [] |
154 | def need_update_submodule(ud, url, module, modpath, workdir, d): | 170 | def need_update_submodule(ud, url, module, modpath, workdir, d): |
155 | url += ";bareclone=1;nobranch=1" | 171 | url += ";bareclone=1;nobranch=1" |
@@ -163,22 +179,9 @@ class GitSM(Git): | |||
163 | logger.error('gitsm: submodule update check failed: %s %s' % (type(e).__name__, str(e))) | 179 | logger.error('gitsm: submodule update check failed: %s %s' % (type(e).__name__, str(e))) |
164 | need_update_result = True | 180 | need_update_result = True |
165 | 181 | ||
166 | # If we're using a shallow mirror tarball it needs to be unpacked | 182 | self.call_process_submodules(ud, d, not os.path.exists(ud.clonedir), need_update_submodule) |
167 | # temporarily so that we can examine the .gitmodules file | 183 | |
168 | if ud.shallow and os.path.exists(ud.fullshallow) and not os.path.exists(ud.clonedir): | 184 | if need_update_list: |
169 | tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR")) | ||
170 | runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=tmpdir) | ||
171 | self.process_submodules(ud, tmpdir, need_update_submodule, d) | ||
172 | shutil.rmtree(tmpdir) | ||
173 | else: | ||
174 | self.process_submodules(ud, ud.clonedir, need_update_submodule, d) | ||
175 | if len(need_update_list) == 0: | ||
176 | # We already have the required commits of all submodules. Drop | ||
177 | # a nugget so we don't need to check again. | ||
178 | runfetchcmd("%s config --add bitbake.srcrev %s" % \ | ||
179 | (ud.basecmd, ud.revisions[ud.names[0]]), d, workdir=ud.clonedir) | ||
180 | |||
181 | if len(need_update_list) > 0: | ||
182 | logger.debug('gitsm: Submodules requiring update: %s' % (' '.join(need_update_list))) | 185 | logger.debug('gitsm: Submodules requiring update: %s' % (' '.join(need_update_list))) |
183 | return True | 186 | return True |
184 | 187 | ||
@@ -199,19 +202,7 @@ class GitSM(Git): | |||
199 | raise | 202 | raise |
200 | 203 | ||
201 | Git.download(self, ud, d) | 204 | Git.download(self, ud, d) |
202 | 205 | self.call_process_submodules(ud, d, self.need_update(ud, d), download_submodule) | |
203 | # If we're using a shallow mirror tarball it needs to be unpacked | ||
204 | # temporarily so that we can examine the .gitmodules file | ||
205 | if ud.shallow and os.path.exists(ud.fullshallow) and self.need_update(ud, d): | ||
206 | tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR")) | ||
207 | runfetchcmd("tar -xzf %s" % ud.fullshallow, d, workdir=tmpdir) | ||
208 | self.process_submodules(ud, tmpdir, download_submodule, d) | ||
209 | shutil.rmtree(tmpdir) | ||
210 | else: | ||
211 | self.process_submodules(ud, ud.clonedir, download_submodule, d) | ||
212 | # Drop a nugget for the srcrev we've fetched (used by need_update) | ||
213 | runfetchcmd("%s config --add bitbake.srcrev %s" % \ | ||
214 | (ud.basecmd, ud.revisions[ud.names[0]]), d, workdir=ud.clonedir) | ||
215 | 206 | ||
216 | def unpack(self, ud, destdir, d): | 207 | def unpack(self, ud, destdir, d): |
217 | def unpack_submodules(ud, url, module, modpath, workdir, d): | 208 | def unpack_submodules(ud, url, module, modpath, workdir, d): |
@@ -225,6 +216,10 @@ class GitSM(Git): | |||
225 | 216 | ||
226 | try: | 217 | try: |
227 | newfetch = Fetch([url], d, cache=False) | 218 | newfetch = Fetch([url], d, cache=False) |
219 | # modpath is needed by unpack tracer to calculate submodule | ||
220 | # checkout dir | ||
221 | new_ud = newfetch.ud[url] | ||
222 | new_ud.modpath = modpath | ||
228 | newfetch.unpack(root=os.path.dirname(os.path.join(repo_conf, 'modules', module))) | 223 | newfetch.unpack(root=os.path.dirname(os.path.join(repo_conf, 'modules', module))) |
229 | except Exception as e: | 224 | except Exception as e: |
230 | logger.error('gitsm: submodule unpack failed: %s %s' % (type(e).__name__, str(e))) | 225 | logger.error('gitsm: submodule unpack failed: %s %s' % (type(e).__name__, str(e))) |
@@ -250,13 +245,27 @@ class GitSM(Git): | |||
250 | ret = self.process_submodules(ud, ud.destdir, unpack_submodules, d) | 245 | ret = self.process_submodules(ud, ud.destdir, unpack_submodules, d) |
251 | 246 | ||
252 | if not ud.bareclone and ret: | 247 | if not ud.bareclone and ret: |
253 | # All submodules should already be downloaded and configured in the tree. This simply sets | 248 | cmdprefix = "" |
254 | # up the configuration and checks out the files. The main project config should remain | 249 | # Avoid LFS smudging (replacing the LFS pointers with the actual content) when LFS shouldn't be used but git-lfs is installed. |
255 | # unmodified, and no download from the internet should occur. | 250 | if not self._need_lfs(ud): |
256 | runfetchcmd("%s submodule update --recursive --no-fetch" % (ud.basecmd), d, quiet=True, workdir=ud.destdir) | 251 | cmdprefix = "GIT_LFS_SKIP_SMUDGE=1 " |
252 | runfetchcmd("%s%s submodule update --recursive --no-fetch" % (cmdprefix, ud.basecmd), d, quiet=True, workdir=ud.destdir) | ||
253 | def clean(self, ud, d): | ||
254 | def clean_submodule(ud, url, module, modpath, workdir, d): | ||
255 | url += ";bareclone=1;nobranch=1" | ||
256 | try: | ||
257 | newfetch = Fetch([url], d, cache=False) | ||
258 | newfetch.clean() | ||
259 | except Exception as e: | ||
260 | logger.warning('gitsm: submodule clean failed: %s %s' % (type(e).__name__, str(e))) | ||
261 | |||
262 | self.call_process_submodules(ud, d, True, clean_submodule) | ||
263 | |||
264 | # Clean top git dir | ||
265 | Git.clean(self, ud, d) | ||
257 | 266 | ||
258 | def implicit_urldata(self, ud, d): | 267 | def implicit_urldata(self, ud, d): |
259 | import shutil, subprocess, tempfile | 268 | import subprocess |
260 | 269 | ||
261 | urldata = [] | 270 | urldata = [] |
262 | def add_submodule(ud, url, module, modpath, workdir, d): | 271 | def add_submodule(ud, url, module, modpath, workdir, d): |
@@ -264,14 +273,6 @@ class GitSM(Git): | |||
264 | newfetch = Fetch([url], d, cache=False) | 273 | newfetch = Fetch([url], d, cache=False) |
265 | urldata.extend(newfetch.expanded_urldata()) | 274 | urldata.extend(newfetch.expanded_urldata()) |
266 | 275 | ||
267 | # If we're using a shallow mirror tarball it needs to be unpacked | 276 | self.call_process_submodules(ud, d, ud.method.need_update(ud, d), add_submodule) |
268 | # temporarily so that we can examine the .gitmodules file | ||
269 | if ud.shallow and os.path.exists(ud.fullshallow) and ud.method.need_update(ud, d): | ||
270 | tmpdir = tempfile.mkdtemp(dir=d.getVar("DL_DIR")) | ||
271 | subprocess.check_call("tar -xzf %s" % ud.fullshallow, cwd=tmpdir, shell=True) | ||
272 | self.process_submodules(ud, tmpdir, add_submodule, d) | ||
273 | shutil.rmtree(tmpdir) | ||
274 | else: | ||
275 | self.process_submodules(ud, ud.clonedir, add_submodule, d) | ||
276 | 277 | ||
277 | return urldata | 278 | return urldata |