diff options
author | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2019-08-04 17:19:26 +0000 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2019-08-04 17:19:26 +0000 |
commit | 6481083503f034e3c38daebbe675433dc5b7818b (patch) | |
tree | 0cad63915cd9773256f6ab165a0957fdcc376315 | |
parent | 20b6e7b455c6445ae966ee585825fbbbc89b1034 (diff) | |
parent | 36e42c7dc6f027ada7bdd72f19ec87d031828e05 (diff) | |
download | buildstream-6481083503f034e3c38daebbe675433dc5b7818b.tar.gz |
Merge branch 'tristan/bst-1/pretty-git-refs' into 'bst-1'
Backport pretty git refs
See merge request BuildStream/buildstream!1516
-rw-r--r-- | buildstream/plugins/sources/git.py | 26 | ||||
-rw-r--r-- | tests/sources/git.py | 47 | ||||
-rw-r--r-- | tests/testutils/repo/git.py | 3 |
3 files changed, 74 insertions, 2 deletions
diff --git a/buildstream/plugins/sources/git.py b/buildstream/plugins/sources/git.py index 542fc8011..a44717a35 100644 --- a/buildstream/plugins/sources/git.py +++ b/buildstream/plugins/sources/git.py @@ -43,6 +43,12 @@ git - stage files from a git repository # will be used to update the 'ref' when refreshing the pipeline. track: master + # Optionally specify the ref format used for tracking. + # The default is 'sha1' for the raw commit hash. + # If you specify 'git-describe', the commit hash will be prefixed + # with the closest tag. + ref-format: sha1 + # Specify the commit ref, this must be specified in order to # checkout sources and build, but can be automatically updated # if the 'track' attribute was specified. @@ -229,7 +235,18 @@ class GitMirror(SourceFetcher): [self.source.host_git, 'rev-parse', tracking], fail="Unable to find commit for specified branch name '{}'".format(tracking), cwd=self.mirror) - return output.rstrip('\n') + ref = output.rstrip('\n') + + if self.source.ref_format == 'git-describe': + # Prefix the ref with the closest tag, if available, + # to make the ref human readable + exit_code, output = self.source.check_output( + [self.source.host_git, 'describe', '--tags', '--abbrev=40', '--long', ref], + cwd=self.mirror) + if exit_code == 0: + ref = output.rstrip('\n') + + return ref def stage(self, directory): fullpath = os.path.join(directory, self.path) @@ -332,13 +349,18 @@ class GitSource(Source): def configure(self, node): ref = self.node_get_member(node, str, 'ref', None) - config_keys = ['url', 'track', 'ref', 'submodules', 'checkout-submodules'] + config_keys = ['url', 'track', 'ref', 'submodules', 'checkout-submodules', 'ref-format'] self.node_validate(node, config_keys + Source.COMMON_CONFIG_KEYS) self.original_url = self.node_get_member(node, str, 'url') self.mirror = GitMirror(self, '', self.original_url, ref, primary=True) self.tracking = self.node_get_member(node, str, 'track', None) + self.ref_format = self.node_get_member(node, str, 'ref-format', 'sha1') + if self.ref_format not in ['sha1', 'git-describe']: + provenance = self.node_provenance(node, member_name='ref-format') + raise SourceError("{}: Unexpected value for ref-format: {}".format(provenance, self.ref_format)) + # At this point we now know if the source has a ref and/or a track. # If it is missing both then we will be unable to track or build. if self.mirror.ref is None and self.tracking is None: diff --git a/tests/sources/git.py b/tests/sources/git.py index e7daa95a7..9b59e30fb 100644 --- a/tests/sources/git.py +++ b/tests/sources/git.py @@ -481,6 +481,53 @@ def test_ref_not_in_track_warn_error(cli, tmpdir, datafiles): @pytest.mark.skipif(HAVE_GIT is False, reason="git is not available") @pytest.mark.datafiles(os.path.join(DATA_DIR, 'template')) +@pytest.mark.parametrize("ref_format", ['sha1', 'git-describe']) +@pytest.mark.parametrize("tag,extra_commit", [(False, False), (True, False), (True, True)]) +def test_track_fetch(cli, tmpdir, datafiles, ref_format, tag, extra_commit): + project = os.path.join(datafiles.dirname, datafiles.basename) + + # Create the repo from 'repofiles' subdir + repo = create_repo('git', str(tmpdir)) + ref = repo.create(os.path.join(project, 'repofiles')) + if tag: + repo.add_tag('tag') + if extra_commit: + repo.add_commit() + + # Write out our test target + element = { + 'kind': 'import', + 'sources': [ + repo.source_config() + ] + } + element['sources'][0]['ref-format'] = ref_format + element_path = os.path.join(project, 'target.bst') + _yaml.dump(element, element_path) + + # Track it + result = cli.run(project=project, args=['track', 'target.bst']) + result.assert_success() + + element = _yaml.load(element_path) + new_ref = element['sources'][0]['ref'] + + if ref_format == 'git-describe' and tag: + # Check and strip prefix + prefix = 'tag-{}-g'.format(0 if not extra_commit else 1) + assert new_ref.startswith(prefix) + new_ref = new_ref[len(prefix):] + + # 40 chars for SHA-1 + assert len(new_ref) == 40 + + # Fetch it + result = cli.run(project=project, args=['fetch', 'target.bst']) + result.assert_success() + + +@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available") +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template')) @pytest.mark.parametrize("fail", ['warn', 'error']) def test_unlisted_submodule(cli, tmpdir, datafiles, fail): project = os.path.join(datafiles.dirname, datafiles.basename) diff --git a/tests/testutils/repo/git.py b/tests/testutils/repo/git.py index 5587baacb..1adc096dd 100644 --- a/tests/testutils/repo/git.py +++ b/tests/testutils/repo/git.py @@ -33,6 +33,9 @@ class Git(Repo): subprocess.call(['git', 'commit', '-m', 'Initial commit'], env=GIT_ENV, cwd=self.repo) return self.latest_commit() + def add_tag(self, tag): + subprocess.call(['git', 'tag', tag], env=GIT_ENV, cwd=self.repo) + def add_commit(self): subprocess.call(['git', 'commit', '--allow-empty', '-m', 'Additional commit'], env=GIT_ENV, cwd=self.repo) |