diff options
Diffstat (limited to 'buildstream/plugins/sources/git.py')
-rw-r--r-- | buildstream/plugins/sources/git.py | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/buildstream/plugins/sources/git.py b/buildstream/plugins/sources/git.py index f45a23bfc..cc6d35cd0 100644 --- a/buildstream/plugins/sources/git.py +++ b/buildstream/plugins/sources/git.py @@ -74,6 +74,9 @@ This plugin provides the following configurable warnings: - 'git:inconsistent-submodule' - A submodule was found to be missing from the underlying git repository. +This plugin also utilises the following configurable core plugin warnings: + +- 'ref-not-in-track' - The provided ref was not found in the provided track in the element's git repository. """ import os @@ -87,6 +90,7 @@ from configparser import RawConfigParser from buildstream import Source, SourceError, Consistency, SourceFetcher from buildstream import utils +from buildstream.plugin import CoreWarnings GIT_MODULES = '.gitmodules' @@ -203,7 +207,7 @@ class GitMirror(SourceFetcher): cwd=self.mirror) return output.rstrip('\n') - def stage(self, directory): + def stage(self, directory, track=None): fullpath = os.path.join(directory, self.path) # Using --shared here avoids copying the objects into the checkout, in any @@ -217,10 +221,14 @@ class GitMirror(SourceFetcher): fail="Failed to checkout git ref {}".format(self.ref), cwd=fullpath) + # Check that the user specified ref exists in the track if provided & not already tracked + if track: + self.assert_ref_in_track(fullpath, track) + # Remove .git dir shutil.rmtree(os.path.join(fullpath, ".git")) - def init_workspace(self, directory): + def init_workspace(self, directory, track=None): fullpath = os.path.join(directory, self.path) url = self.source.translate_url(self.url) @@ -236,6 +244,10 @@ class GitMirror(SourceFetcher): fail="Failed to checkout git ref {}".format(self.ref), cwd=fullpath) + # Check that the user specified ref exists in the track if provided & not already tracked + if track: + self.assert_ref_in_track(fullpath, track) + # List the submodules (path/url tuples) present at the given ref of this repo def submodule_list(self): modules = "{}:{}".format(self.ref, GIT_MODULES) @@ -300,6 +312,28 @@ class GitMirror(SourceFetcher): return None + # Assert that ref exists in track, if track has been specified. + def assert_ref_in_track(self, fullpath, track): + _, branch = self.source.check_output([self.source.host_git, 'branch', '--list', track, + '--contains', self.ref], + cwd=fullpath,) + if branch: + return True + else: + _, tag = self.source.check_output([self.source.host_git, 'tag', '--list', track, + '--contains', self.ref], + cwd=fullpath,) + if tag: + return True + + detail = "The ref provided for the element does not exist locally in the provided track branch / tag " + \ + "'{}'.\nYou may wish to track the element to update the ref from '{}' ".format(track, track) + \ + "with `bst track`,\nor examine the upstream at '{}' for the specific ref.".format(self.url) + + self.source.warn("{}: expected ref '{}' was not found in given track '{}' for staged repository: '{}'\n" + .format(self.source, self.ref, track, self.url), + detail=detail, warning_token=CoreWarnings.REF_NOT_IN_TRACK) + class GitSource(Source): # pylint: disable=attribute-defined-outside-init @@ -342,6 +376,7 @@ class GitSource(Source): self.submodule_checkout_overrides[path] = checkout self.mark_download_url(self.original_url) + self.tracked = False def preflight(self): # Check if git is installed, get the binary at the same time @@ -407,6 +442,8 @@ class GitSource(Source): # Update self.mirror.ref and node.ref from the self.tracking branch ret = self.mirror.latest_commit(self.tracking) + # Set tracked attribute, parameter for if self.mirror.assert_ref_in_track is needed + self.tracked = True return ret def init_workspace(self, directory): @@ -414,7 +451,7 @@ class GitSource(Source): self.refresh_submodules() with self.timed_activity('Setting up workspace "{}"'.format(directory), silent_nested=True): - self.mirror.init_workspace(directory) + self.mirror.init_workspace(directory, track=(self.tracking if not self.tracked else None)) for mirror in self.submodules: mirror.init_workspace(directory) @@ -430,7 +467,7 @@ class GitSource(Source): # Stage the main repo in the specified directory # with self.timed_activity("Staging {}".format(self.mirror.url), silent_nested=True): - self.mirror.stage(directory) + self.mirror.stage(directory, track=(self.tracking if not self.tracked else None)) for mirror in self.submodules: if mirror.path in self.submodule_checkout_overrides: checkout = self.submodule_checkout_overrides[mirror.path] |