Jürg Billeter pushed to branch juerg/git-describe at BuildStream / buildstream
Commits:
-
900e8900
by Jürg Billeter at 2018-09-27T13:12:34Z
-
107269c1
by Jürg Billeter at 2018-09-27T13:12:34Z
-
8060ad8c
by Jürg Billeter at 2018-09-27T13:12:34Z
3 changed files:
Changes:
| ... | ... | @@ -43,6 +43,12 @@ git - stage files from a git repository |
| 43 | 43 |
# will be used to update the 'ref' when refreshing the pipeline.
|
| 44 | 44 |
track: master
|
| 45 | 45 |
|
| 46 |
+ # Optionally specify the ref format used for tracking.
|
|
| 47 |
+ # The default is 'sha1' for the raw commit hash.
|
|
| 48 |
+ # If you specify 'git-describe', the commit hash will be prefixed
|
|
| 49 |
+ # with the closest tag.
|
|
| 50 |
+ ref-format: sha1
|
|
| 51 |
+ |
|
| 46 | 52 |
# Specify the commit ref, this must be specified in order to
|
| 47 | 53 |
# checkout sources and build, but can be automatically updated
|
| 48 | 54 |
# if the 'track' attribute was specified.
|
| ... | ... | @@ -205,7 +211,18 @@ class GitMirror(SourceFetcher): |
| 205 | 211 |
[self.source.host_git, 'rev-parse', tracking],
|
| 206 | 212 |
fail="Unable to find commit for specified branch name '{}'".format(tracking),
|
| 207 | 213 |
cwd=self.mirror)
|
| 208 |
- return output.rstrip('\n')
|
|
| 214 |
+ ref = output.rstrip('\n')
|
|
| 215 |
+ |
|
| 216 |
+ if self.source.ref_format == 'git-describe':
|
|
| 217 |
+ # Prefix the ref with the closest tag, if available,
|
|
| 218 |
+ # to make the ref human readable
|
|
| 219 |
+ exit_code, output = self.source.check_output(
|
|
| 220 |
+ [self.source.host_git, 'describe', '--tags', '--abbrev=40', '--long', ref],
|
|
| 221 |
+ cwd=self.mirror)
|
|
| 222 |
+ if exit_code == 0:
|
|
| 223 |
+ ref = output.rstrip('\n')
|
|
| 224 |
+ |
|
| 225 |
+ return ref
|
|
| 209 | 226 |
|
| 210 | 227 |
def stage(self, directory, track=None):
|
| 211 | 228 |
fullpath = os.path.join(directory, self.path)
|
| ... | ... | @@ -341,13 +358,18 @@ class GitSource(Source): |
| 341 | 358 |
def configure(self, node):
|
| 342 | 359 |
ref = self.node_get_member(node, str, 'ref', None)
|
| 343 | 360 |
|
| 344 |
- config_keys = ['url', 'track', 'ref', 'submodules', 'checkout-submodules']
|
|
| 361 |
+ config_keys = ['url', 'track', 'ref', 'submodules', 'checkout-submodules', 'ref-format']
|
|
| 345 | 362 |
self.node_validate(node, config_keys + Source.COMMON_CONFIG_KEYS)
|
| 346 | 363 |
|
| 347 | 364 |
self.original_url = self.node_get_member(node, str, 'url')
|
| 348 | 365 |
self.mirror = GitMirror(self, '', self.original_url, ref, primary=True)
|
| 349 | 366 |
self.tracking = self.node_get_member(node, str, 'track', None)
|
| 350 | 367 |
|
| 368 |
+ self.ref_format = self.node_get_member(node, str, 'ref-format', 'sha1')
|
|
| 369 |
+ if self.ref_format not in ['sha1', 'git-describe']:
|
|
| 370 |
+ provenance = self.node_provenance(node, member_name='ref-format')
|
|
| 371 |
+ raise SourceError("{}: Unexpected value for ref-format: {}".format(provenance, self.ref_format))
|
|
| 372 |
+ |
|
| 351 | 373 |
# At this point we now know if the source has a ref and/or a track.
|
| 352 | 374 |
# If it is missing both then we will be unable to track or build.
|
| 353 | 375 |
if self.mirror.ref is None and self.tracking is None:
|
| ... | ... | @@ -476,3 +476,50 @@ def test_ref_not_in_track_warn_error(cli, tmpdir, datafiles): |
| 476 | 476 |
result = cli.run(project=project, args=['build', 'target.bst'])
|
| 477 | 477 |
result.assert_main_error(ErrorDomain.STREAM, None)
|
| 478 | 478 |
result.assert_task_error(ErrorDomain.PLUGIN, CoreWarnings.REF_NOT_IN_TRACK)
|
| 479 |
+ |
|
| 480 |
+ |
|
| 481 |
+@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
|
|
| 482 |
+@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
|
|
| 483 |
+@pytest.mark.parametrize("ref_format", ['sha1', 'git-describe'])
|
|
| 484 |
+@pytest.mark.parametrize("tag,extra_commit", [(False, False), (True, False), (True, True)])
|
|
| 485 |
+def test_track_fetch(cli, tmpdir, datafiles, ref_format, tag, extra_commit):
|
|
| 486 |
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
| 487 |
+ |
|
| 488 |
+ # Create the repo from 'repofiles' subdir
|
|
| 489 |
+ repo = create_repo('git', str(tmpdir))
|
|
| 490 |
+ ref = repo.create(os.path.join(project, 'repofiles'))
|
|
| 491 |
+ if tag:
|
|
| 492 |
+ repo.add_tag('tag')
|
|
| 493 |
+ if extra_commit:
|
|
| 494 |
+ repo.add_commit()
|
|
| 495 |
+ |
|
| 496 |
+ # Write out our test target
|
|
| 497 |
+ element = {
|
|
| 498 |
+ 'kind': 'import',
|
|
| 499 |
+ 'sources': [
|
|
| 500 |
+ repo.source_config()
|
|
| 501 |
+ ]
|
|
| 502 |
+ }
|
|
| 503 |
+ element['sources'][0]['ref-format'] = ref_format
|
|
| 504 |
+ element_path = os.path.join(project, 'target.bst')
|
|
| 505 |
+ _yaml.dump(element, element_path)
|
|
| 506 |
+ |
|
| 507 |
+ # Track it
|
|
| 508 |
+ result = cli.run(project=project, args=['track', 'target.bst'])
|
|
| 509 |
+ result.assert_success()
|
|
| 510 |
+ |
|
| 511 |
+ element = _yaml.load(element_path)
|
|
| 512 |
+ new_ref = element['sources'][0]['ref']
|
|
| 513 |
+ |
|
| 514 |
+ if ref_format == 'git-describe' and tag:
|
|
| 515 |
+ # Check and strip prefix
|
|
| 516 |
+ prefix = 'tag-{}-g'.format(0 if not extra_commit else 1)
|
|
| 517 |
+ assert new_ref.startswith(prefix)
|
|
| 518 |
+ new_ref = new_ref[len(prefix):]
|
|
| 519 |
+ |
|
| 520 |
+ # 40 chars for SHA-1
|
|
| 521 |
+ assert len(new_ref) == 40
|
|
| 522 |
+ |
|
| 523 |
+ # Fetch it
|
|
| 524 |
+ result = cli.run(project=project, args=['fetch', 'target.bst'])
|
|
| 525 |
+ result.assert_success()
|
| ... | ... | @@ -42,6 +42,9 @@ class Git(Repo): |
| 42 | 42 |
self._run_git('commit', '-m', 'Initial commit')
|
| 43 | 43 |
return self.latest_commit()
|
| 44 | 44 |
|
| 45 |
+ def add_tag(self, tag):
|
|
| 46 |
+ self._run_git('tag', tag)
|
|
| 47 |
+ |
|
| 45 | 48 |
def add_commit(self):
|
| 46 | 49 |
self._run_git('commit', '--allow-empty', '-m', 'Additional commit')
|
| 47 | 50 |
return self.latest_commit()
|
