summaryrefslogtreecommitdiff
path: root/tests/sources/git.py
diff options
context:
space:
mode:
authorValentin David <valentin.david@codethink.co.uk>2018-10-26 16:38:53 +0200
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-12-05 18:47:52 +0900
commit8251310950e72f18c2d171de375051fb0e126655 (patch)
treef76c349c7c06825a0813ccb3cdc54861262db7e0 /tests/sources/git.py
parent5d77b871a343c8a196569ab17fd5e4f04bb6baec (diff)
downloadbuildstream-8251310950e72f18c2d171de375051fb0e126655.tar.gz
git source plugin: Track git tags and save them to reproduce a minimum shallow repository
Instead of tag information being fetched which can change with time, they are tracked and saved in the projects.refs/.bst. Then we re-tag automatically the closest tag so that `git describe` works and is reproducible. This new feature is opt-in with the new `track-tags` configuration, and must be used to fix modules which are broken by our new policy of omitting the `.git/` repository when staging git sources. This fixes issue #487
Diffstat (limited to 'tests/sources/git.py')
-rw-r--r--tests/sources/git.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/tests/sources/git.py b/tests/sources/git.py
index 7ab32a6b5..462200f97 100644
--- a/tests/sources/git.py
+++ b/tests/sources/git.py
@@ -22,6 +22,7 @@
import os
import pytest
+import subprocess
from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
@@ -523,3 +524,155 @@ def test_track_fetch(cli, tmpdir, datafiles, ref_format, tag, extra_commit):
# 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("ref_storage", [('inline'), ('project.refs')])
+@pytest.mark.parametrize("tag_type", [('annotated'), ('lightweight')])
+def test_git_describe(cli, tmpdir, datafiles, ref_storage, tag_type):
+ project = str(datafiles)
+
+ project_config = _yaml.load(os.path.join(project, 'project.conf'))
+ project_config['ref-storage'] = ref_storage
+ _yaml.dump(_yaml.node_sanitize(project_config), os.path.join(project, 'project.conf'))
+
+ repofiles = os.path.join(str(tmpdir), 'repofiles')
+ os.makedirs(repofiles, exist_ok=True)
+ file0 = os.path.join(repofiles, 'file0')
+ with open(file0, 'w') as f:
+ f.write('test\n')
+
+ repo = create_repo('git', str(tmpdir))
+
+ def tag(name):
+ if tag_type == 'annotated':
+ repo.add_annotated_tag(name, name)
+ else:
+ repo.add_tag(name)
+
+ ref = repo.create(repofiles)
+ tag('uselesstag')
+
+ file1 = os.path.join(str(tmpdir), 'file1')
+ with open(file1, 'w') as f:
+ f.write('test\n')
+ repo.add_file(file1)
+ tag('tag1')
+
+ file2 = os.path.join(str(tmpdir), 'file2')
+ with open(file2, 'w') as f:
+ f.write('test\n')
+ repo.branch('branch2')
+ repo.add_file(file2)
+ tag('tag2')
+
+ repo.checkout('master')
+ file3 = os.path.join(str(tmpdir), 'file3')
+ with open(file3, 'w') as f:
+ f.write('test\n')
+ repo.add_file(file3)
+
+ repo.merge('branch2')
+
+ config = repo.source_config()
+ config['track'] = repo.latest_commit()
+ config['track-tags'] = True
+
+ # Write out our test target
+ element = {
+ 'kind': 'import',
+ 'sources': [
+ config
+ ],
+ }
+ element_path = os.path.join(project, 'target.bst')
+ _yaml.dump(element, element_path)
+
+ if ref_storage == 'inline':
+ result = cli.run(project=project, args=['track', 'target.bst'])
+ result.assert_success()
+ else:
+ result = cli.run(project=project, args=['track', 'target.bst', '--deps', 'all'])
+ result.assert_success()
+
+ if ref_storage == 'inline':
+ element = _yaml.load(element_path)
+ tags = _yaml.node_sanitize(element['sources'][0]['tags'])
+ assert len(tags) == 2
+ for tag in tags:
+ assert 'tag' in tag
+ assert 'commit' in tag
+ assert 'annotated' in tag
+ assert tag['annotated'] == (tag_type == 'annotated')
+
+ assert set([(tag['tag'], tag['commit']) for tag in tags]) == set([('tag1', repo.rev_parse('tag1^{commit}')),
+ ('tag2', repo.rev_parse('tag2^{commit}'))])
+
+ checkout = os.path.join(str(tmpdir), 'checkout')
+
+ result = cli.run(project=project, args=['build', 'target.bst'])
+ result.assert_success()
+ result = cli.run(project=project, args=['checkout', 'target.bst', checkout])
+ result.assert_success()
+
+ if tag_type == 'annotated':
+ options = []
+ else:
+ options = ['--tags']
+ describe = subprocess.check_output(['git', 'describe'] + options,
+ cwd=checkout).decode('ascii')
+ assert describe.startswith('tag2-2-')
+
+ describe_fp = subprocess.check_output(['git', 'describe', '--first-parent'] + options,
+ cwd=checkout).decode('ascii')
+ assert describe_fp.startswith('tag1-2-')
+
+ tags = subprocess.check_output(['git', 'tag'],
+ cwd=checkout).decode('ascii')
+ tags = set(tags.splitlines())
+ assert tags == set(['tag1', 'tag2'])
+
+ p = subprocess.run(['git', 'log', repo.rev_parse('uselesstag')],
+ cwd=checkout)
+ assert p.returncode != 0
+
+
+@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
+@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
+def test_default_do_not_track_tags(cli, tmpdir, datafiles):
+ project = str(datafiles)
+
+ project_config = _yaml.load(os.path.join(project, 'project.conf'))
+ project_config['ref-storage'] = 'inline'
+ _yaml.dump(_yaml.node_sanitize(project_config), os.path.join(project, 'project.conf'))
+
+ repofiles = os.path.join(str(tmpdir), 'repofiles')
+ os.makedirs(repofiles, exist_ok=True)
+ file0 = os.path.join(repofiles, 'file0')
+ with open(file0, 'w') as f:
+ f.write('test\n')
+
+ repo = create_repo('git', str(tmpdir))
+
+ ref = repo.create(repofiles)
+ repo.add_tag('tag')
+
+ config = repo.source_config()
+ config['track'] = repo.latest_commit()
+
+ # Write out our test target
+ element = {
+ 'kind': 'import',
+ 'sources': [
+ config
+ ],
+ }
+ element_path = os.path.join(project, 'target.bst')
+ _yaml.dump(element, element_path)
+
+ result = cli.run(project=project, args=['track', 'target.bst'])
+ result.assert_success()
+
+ element = _yaml.load(element_path)
+ assert 'tags' not in element['sources'][0]