summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Pollard <tom.pollard@codethink.co.uk>2018-08-29 12:43:30 +0100
committerTom Pollard <tom.pollard@codethink.co.uk>2018-09-03 09:44:36 +0000
commit2339f0c4fe76fb94c7453cd0a78be47e634681aa (patch)
tree4a4114e1059167893161189ad5dcb1be5fafe10f
parent88460cd26ebe4e0ab3f49648667ec7800f174d5d (diff)
downloadbuildstream-2339f0c4fe76fb94c7453cd0a78be47e634681aa.tar.gz
plugins/git.py: Warn if ref is not in given track
Add a helper function assert_ref_in_track to git.py GitMirror() which is used when staging & initing the source workspace. It checks the element's ref exists in the track (branch/tag) if it has been specified, raising a warning if necessary. The warning makes use of the warning token 'REF_NOT_IN_TRACK' from the configurable CoreWarnings. If the element has been tracked with bst, it is assumed that the value of ref exists in the track as it was generated from it & as such is not asserted.
-rw-r--r--buildstream/plugins/sources/git.py45
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]