Merge ~racb/git-ubuntu:commit-message-spec into git-ubuntu:master

Proposed by Robie Basak
Status: Merged
Approved by: Bryce Harrington
Approved revision: 1c54cd378f08b9d6e28ba5deb3c9612a4114e504
Merged at revision: 1c54cd378f08b9d6e28ba5deb3c9612a4114e504
Proposed branch: ~racb/git-ubuntu:commit-message-spec
Merge into: git-ubuntu:master
Diff against target: 625 lines (+200/-184)
5 files modified
gitubuntu/clone.py (+2/-0)
gitubuntu/git_repository.py (+7/-0)
gitubuntu/importer.py (+103/-126)
gitubuntu/importer_tag_test.py (+4/-0)
gitubuntu/importer_test.py (+84/-58)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Bryce Harrington Needs Fixing
Review via email: mp+381765@code.launchpad.net

Commit message

Make Jenkins happy

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:49d62ab97b7107abfb3dc2a993b50a74cf79215b
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/485/
Executed test runs:
    SUCCESS: VM Setup
    SUCCESS: Build
    SUCCESS: Unit Tests
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/485//rebuild

review: Approve (continuous-integration)
Revision history for this message
Bryce Harrington (bryce) wrote :
Download full text (3.8 KiB)

Looks good, I just ask for a couple comments for the refs fetch and push, and a couple minor inline notes. Otherwise looks solid, some really good refactoring, and I'm looking forward to seeing the new notes feature in practice. I'm still a bit nervous that this will uncover warts in git, but maybe not, and in any case it feels like the right way to go technically.

If you agree with the comment suggestions, please go ahead and land after adding, no need for second round of review.

* Review
  √ python3 setup.py build
  √ python3 setup.py check
  √ ./snap-wrappers/wrappers/git-ubuntu-self-test
    No broken requirements found.
    pip3 found all required dependencies
    pylint passed!
    PASS (syntax) source-package-walker.py
    PASS (compilation) source-package-walker.py
    PASS (syntax) update-repository-alias.py
    PASS (compilation) update-repository-alias.py
    PASS (syntax) import-source-packages.py
    PASS (compilation) import-source-packages.py
    332 passed, 3 xfailed in 187.90 seconds
  ! Per-patch code review
    √ ef26b8a077b6ff3a8c455d38fc838dad4625df00
      + Die wrappers!
      + LGTM
    √ 4bdd58db60bad113b1eb6a87621554f8f8bedef6
      + Pythonic objects FTW
      + LGTM
    √ 69bc94052dbd1793fce7f4f9f32b76cb2c8f3b98
      + Verified the promised skip of test_get_import_commit_msg() is
        indeed dropped in 061371a7 (next patch).
      + LGTM
    √ 061371a77089930b27a261ff0447ba60d517fa82
      + This is the key patch in the set. Moves change info from the
        commit message into the git note.
      + add_changelog_note_to_commit() is added, and has corresponding
        test cases test_add_changelog_note_to_commit() and
        test_double_changelog_note_add_does_not_fail()
      + Uses the new gitubuntu.spec module
      + LGTM
    √ 224684300a41a929492f981c453a3f71d77175d6
      + Largely cleanup/refactor from prior commit. Uses patch_state.
      + LGTM, nice cleanup
    √ 9323899deab7a1d57e3c0ac9f92a47f552602502
      + Verified all call points are updated with correct argument list.
      + LGTM
    √ 37ea80888ea65deaeeb509e3624e2a0f6b92d61c
      + Verified no consumers for _commit_import() other than importer.py, and all
        call points are updated with correct argument list.
      + LGTM
    ! a133d0da5316cedf72c220649ffa8691057a3c2c
      + If I understand the refspecs properly, then the fetch with this
        refspec:
        'refs/notes/commits:refs/notes/usd-import-team/changelog'
        will import the notes from 'refs/notes/commits' in the remote
        repository, into 'refs/notes/usd-import-team/changelog' in the
        local checkout. Then later, there is a repo.git_run() call that
        pushes them back in the opposite direction.
      + The commit message explains this sufficiently, but the
        _main_with_repo() itself is lengthy (250+ lines!) and only
        lightly commented, so this notes pushing/pulling feature may not
        be clear to future readers. This would be a good opportunity to
        add a comment each for the repo.fetch_remote_refspecs() and
        git_run() calls, to define the refspec's being fetched and
        pulled. Hopefully over time this ro...

Read more...

review: Needs Fixing
Revision history for this message
Robie Basak (racb) wrote :

Thank you for the review! Comments addressed and pushed. Just waiting now for CI before landing.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:1c54cd378f08b9d6e28ba5deb3c9612a4114e504
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/486/
Executed test runs:
    SUCCESS: VM Setup
    SUCCESS: Build
    SUCCESS: Unit Tests
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/486//rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/gitubuntu/clone.py b/gitubuntu/clone.py
2index ea8dee9..0eca56e 100644
3--- a/gitubuntu/clone.py
4+++ b/gitubuntu/clone.py
5@@ -114,6 +114,8 @@ def main(
6 'pkg/ubuntu/devel branch exist?'
7 )
8
9+ local_repo.git_run(['config', 'notes.displayRef', 'refs/notes/changelog'])
10+
11 if os.path.isfile(os.path.join(directory, '.gitignore')):
12 logging.warning('A .gitignore file exists in the source '
13 'package. This will affect the behavior of git. Consider '
14diff --git a/gitubuntu/git_repository.py b/gitubuntu/git_repository.py
15index 49bd9b8..ce7ebe8 100644
16--- a/gitubuntu/git_repository.py
17+++ b/gitubuntu/git_repository.py
18@@ -1305,6 +1305,13 @@ class GitUbuntuRepository:
19 remote_name,
20 '+refs/tags/*:refs/tags/%s/*' % remote_name,
21 )
22+ # The changelog notes are kept at refs/notes/commits on
23+ # Launchpad due to LP: #1871838 even though our standard place for
24+ # them is refs/notes/changelog.
25+ self.raw_repo.remotes.add_fetch(
26+ remote_name,
27+ '+refs/notes/commits:refs/notes/changelog',
28+ )
29 if push_url:
30 self.raw_repo.remotes.set_push_url(
31 remote_name,
32diff --git a/gitubuntu/importer.py b/gitubuntu/importer.py
33index 6d546bc..604b478 100644
34--- a/gitubuntu/importer.py
35+++ b/gitubuntu/importer.py
36@@ -66,6 +66,7 @@ from gitubuntu.source_information import (
37 SourceExtractionException,
38 launchpad_login_auth,
39 )
40+import gitubuntu.spec as spec
41 from gitubuntu.version import VERSION
42 from gitubuntu.versioning import version_compare
43 try:
44@@ -181,8 +182,16 @@ def _main_with_repo(
45
46 if not no_fetch and not reimport:
47 try:
48+ # This is a normal import run. Fetch in to the "namespaced" local
49+ # refs the tags and changelog notes (the branch fetches are handled
50+ # elsewhere). The changelog notes are kept at refs/notes/commits on
51+ # Launchpad due to LP: #1871838 even though our standard place for
52+ # them is refs/notes/changelog.
53 repo.fetch_remote_refspecs('pkg',
54- refspecs=['refs/tags/*:refs/tags/%s/*' % namespace],
55+ refspecs=[
56+ 'refs/tags/*:refs/tags/%s/*' % namespace,
57+ 'refs/notes/commits:refs/notes/%s/changelog' % namespace,
58+ ],
59 )
60 except GitUbuntuRepositoryFetchError:
61 pass
62@@ -365,6 +374,8 @@ def _main_with_repo(
63 'push', '--atomic', 'pkg',
64 '+refs/heads/%s/*:refs/heads/*' % namespace,
65 'refs/tags/%s/*:refs/tags/*' % namespace,
66+ # Changelog notes go to refs/notes/commits due to LP: #1871838
67+ 'refs/notes/%s/changelog:refs/notes/commits' % namespace,
68 ])
69 # update our reference
70 lp_git_repo = lp.git_repositories.getByPath(path=repo_path)
71@@ -530,12 +541,7 @@ def get_changelog_for_commit(
72 def get_import_commit_msg(
73 repo,
74 version,
75- target_head_name,
76- namespace,
77- tree_hash,
78- changelog_parent_commits,
79- upload_parent_commit,
80- unapplied_parent_commit,
81+ patch_state,
82 ):
83 """Compose an appropriate commit message
84
85@@ -546,62 +552,30 @@ def get_import_commit_msg(
86 :param GitUbuntuRepository repo: the repository in which the tree being
87 committed can be found
88 :param str version: the package version string being committed
89- :param str target_head_name: the nominal name of the branch to which the
90- commit is being made
91- :param str namespace: the namespace name to prefix to the nominal branch
92- name to determine the final branch name
93- :param str tree_hash: the hash of the tree object being committed
94- :param list(str) changelog_parent_commits: any changelog parents to use in
95- the commit
96- :param str upload_parent_commit: the upload parent to use in the commit, or
97- None if there isn't one
98- :param str unapplied_parent_commit: the unapplied parent to use in the
99- commit, or None if this is an applied branch commit
100-
101+ :param PatchState patch_state: whether the commit is for an unapplied or
102+ applied import
103+ :rtype: bytes
104+ :returns: the commit message to use
105 """
106- if unapplied_parent_commit:
107- import_type = 'patches-applied'
108- else:
109- import_type = 'patches-unapplied'
110+ import_type = {
111+ PatchState.UNAPPLIED: 'patches unapplied',
112+ PatchState.APPLIED: 'patches applied',
113+ }[patch_state]
114
115- # Do not show importer/ namespace to user
116- _, _, pretty_head_name = target_head_name.partition('%s/' % namespace)
117- changelog_entry = get_changelog_for_commit(
118- repo,
119- tree_hash,
120- changelog_parent_commits
121- )
122-
123- msg = (
124- b'Import %s version %b to %b\n\nImported using git-ubuntu import.' % (
125- import_type.encode(),
126+ return (
127+ b'%b (%b)\n\nImported using git-ubuntu import.' % (
128 version.encode(),
129- pretty_head_name.encode(),
130+ import_type.encode(),
131 )
132 )
133
134- if any([changelog_parent_commits, upload_parent_commit, unapplied_parent_commit]):
135- msg += b'\n'
136-
137- for changelog_parent_commit in changelog_parent_commits:
138- msg += b'\nChangelog parent: %b' % changelog_parent_commit.encode()
139- if upload_parent_commit is not None:
140- msg += b'\nUpload parent: %b' % upload_parent_commit.encode()
141- if unapplied_parent_commit is not None:
142- msg += b'\nUnapplied parent: %b' % unapplied_parent_commit.encode()
143-
144- msg += b'%b' % changelog_entry
145-
146- return msg
147
148 def _commit_import(
149 repo,
150 version,
151- target_head_name,
152 tree_hash,
153 namespace,
154 changelog_parent_commits,
155- upload_parent_commit,
156 unapplied_parent_commit,
157 commit_date,
158 ):
159@@ -617,19 +591,16 @@ def _commit_import(
160 which the source package contents corresponding to @spi should
161 be imported.
162 :param version str Changelog version
163- :param target_head_name str Git branch name to import to
164 :param namespace str Namespace under which relevant refs can be
165 found.
166 :param list(str) changelog_parent_commits Git commit hashes of changelog
167 parents.
168- :param upload_parent_commit str Git commit hash of
169- upload parent. Should be None if patches-applied import.
170 :param unapplied_parent_commit str Git commit hash of unapplied
171 parent. Should be None if patches-unapplied import.
172 :param str commit_date: committer date to use for the git commit metadata
173
174- :rtype str
175- :returns Hash of created commit
176+ :rtype: pygit2.Commit
177+ :returns: created commit object
178 """
179 parents = []
180
181@@ -637,75 +608,27 @@ def _commit_import(
182 pygit2.Oid(hex=changelog_parent_commit)
183 for changelog_parent_commit in changelog_parent_commits
184 )
185- if upload_parent_commit is not None:
186- parents.append(pygit2.Oid(hex=upload_parent_commit))
187 if unapplied_parent_commit is not None:
188 parents.append(pygit2.Oid(hex=unapplied_parent_commit))
189
190+ if unapplied_parent_commit:
191+ patch_state = PatchState.APPLIED
192+ else:
193+ patch_state = PatchState.UNAPPLIED
194+
195 commit_hash = repo.commit_source_tree(
196 tree=pygit2.Oid(hex=tree_hash),
197 parents=parents,
198 log_message=get_import_commit_msg(
199 repo=repo,
200 version=version,
201- target_head_name=target_head_name,
202- namespace=namespace,
203- tree_hash=tree_hash,
204- changelog_parent_commits=changelog_parent_commits,
205- upload_parent_commit=upload_parent_commit,
206- unapplied_parent_commit=unapplied_parent_commit,
207+ patch_state=patch_state,
208 ),
209 commit_date=commit_date,
210 )
211
212- return str(commit_hash)
213+ return repo.raw_repo.get(str(commit_hash))
214
215-def commit_unapplied_patches_import(
216- repo,
217- version,
218- head_name,
219- import_tree_hash,
220- namespace,
221- changelog_parent_commits,
222- upload_parent_commit,
223- commit_date,
224-):
225- return _commit_import(
226- repo,
227- version,
228- head_name,
229- import_tree_hash,
230- namespace,
231- changelog_parent_commits,
232- upload_parent_commit,
233- # unapplied trees do not have a distinct unapplied parent
234- None,
235- commit_date,
236- )
237-
238-def commit_applied_patches_import(
239- repo,
240- version,
241- head_name,
242- import_tree_hash,
243- namespace,
244- changelog_parent_commits,
245- unapplied_parent_commit,
246- commit_date,
247-):
248- return _commit_import(
249- repo,
250- version,
251- head_name,
252- import_tree_hash,
253- namespace,
254- changelog_parent_commits,
255- # uploads will be unapplied trees currently, so applied trees
256- # can not have them as direct parents
257- None,
258- unapplied_parent_commit,
259- commit_date,
260- )
261
262 def import_dsc(repo, dsc, namespace, version, dist):
263 """Imports the dsc file to importer/{debian,ubuntu}/dsc
264@@ -1526,6 +1449,61 @@ def validate_upload_tag(
265 return True
266
267
268+def add_changelog_note_to_commit(
269+ repo,
270+ namespace,
271+ commit,
272+ changelog_parents,
273+):
274+ """Compute and add a changelog note to the given commit.
275+
276+ For user convenience, changelog notes allow for "git log" and similar tools
277+ to display the debian/changelog entry associated with a
278+ importer-synthesized commit. See LP #1633114 for details.
279+
280+ If a changelog note already exists for the given commit, then return
281+ without doing anything.
282+
283+ :param gitubuntu.GitUbuntuRepository repo: the repository that is the
284+ target of this import.
285+ :param str namespace: the namespace under which relevant refs can be found.
286+ :param pygit2.Commit commit: the commit for which the changelog note should
287+ be calculated and added.
288+ :param list(str) changelog_parents: the list of commit hashes that are the
289+ parents of the provided commit, from which the changelog note may be
290+ calculated.
291+ :returns: None
292+ """
293+ # If the note already exists, return without doing anything.
294+ try:
295+ repo.raw_repo.lookup_note(
296+ str(commit.id),
297+ 'refs/notes/%s/changelog' % namespace,
298+ )
299+ except KeyError:
300+ pass
301+ else:
302+ return
303+
304+ # The note doesn't exist, so figure out what it should be and add it.
305+ changelog_summary = get_changelog_for_commit(
306+ repo=repo,
307+ tree_hash=str(commit.peel(pygit2.Tree).id),
308+ changelog_parent_commits=changelog_parents,
309+ )
310+ changelog_signature = pygit2.Signature(
311+ spec.SYNTHESIZED_COMMITTER_NAME,
312+ spec.SYNTHESIZED_COMMITTER_EMAIL,
313+ )
314+ repo.raw_repo.create_note(
315+ changelog_summary.decode(),
316+ changelog_signature,
317+ changelog_signature,
318+ str(commit.id),
319+ 'refs/notes/%s/changelog' % namespace,
320+ )
321+
322+
323 def find_or_create_unapplied_commit(
324 repo,
325 version,
326@@ -1533,7 +1511,6 @@ def find_or_create_unapplied_commit(
327 import_tree,
328 parent_overrides,
329 commit_date,
330- head_name,
331 ):
332 """Return the commit to be used for an unapplied import
333
334@@ -1559,9 +1536,6 @@ def find_or_create_unapplied_commit(
335 :param dict parent_overrides: see parse_parentfile()
336 :param str commit_date: committer date to use for the git commit metadata.
337 If None, use the current date.
338- :param str head_name: git branch name that is the target of this import.
339- This is currently used in the generated commit message, but will go
340- away when the commit messages are overhauled to the new spec.
341 :rtype: tuple(pygit2.Commit, pygit2.Reference or None)
342 :returns: the commit that has been found or created, and the import tag
343 corresponding to an existing import if it had previously existed.
344@@ -1596,21 +1570,26 @@ def find_or_create_unapplied_commit(
345 return upload_tag.peel(), None
346
347 # Create a commit
348- commit = repo.raw_repo.get(commit_unapplied_patches_import(
349+ commit = _commit_import(
350 repo=repo,
351 version=version,
352- head_name=head_name,
353- import_tree_hash=str(import_tree.id),
354+ tree_hash=str(import_tree.id),
355 namespace=namespace,
356 changelog_parent_commits=changelog_parents,
357- upload_parent_commit=None,
358+ # unapplied trees do not have a distinct unapplied parent
359+ unapplied_parent_commit=None,
360 commit_date=commit_date,
361- ))
362+ )
363 logging.debug(
364- "Committed patches-unapplied import of %s as %s in %s",
365+ "Committed patches-unapplied import of %s as %s",
366 version,
367 str(commit.id),
368- head_name.partition('%s/' % namespace)[2],
369+ )
370+ add_changelog_note_to_commit(
371+ repo=repo,
372+ namespace=namespace,
373+ commit=commit,
374+ changelog_parents=changelog_parents,
375 )
376 return commit, None
377
378@@ -1686,7 +1665,6 @@ def import_unapplied_dsc(
379 import_tree=repo.raw_repo.get(unapplied_import_tree_hash),
380 parent_overrides=parent_overrides,
381 commit_date=commit_date,
382- head_name=head_name,
383 )
384 except ParentOverrideError as e:
385 logging.error("%s" % e)
386@@ -1917,16 +1895,15 @@ def import_applied_dsc(
387 return
388 raise
389
390- commit_hash = commit_applied_patches_import(
391+ commit_hash = str(_commit_import(
392 repo=repo,
393 version=version,
394- head_name=head_name,
395- import_tree_hash=applied_import_tree_hash,
396+ tree_hash=applied_import_tree_hash,
397 namespace=namespace,
398 changelog_parent_commits=applied_changelog_parent_commits,
399 unapplied_parent_commit=str(unapplied_parent_commit),
400 commit_date=commit_date,
401- )
402+ ).id)
403 logging.debug(
404 "Committed patches-applied import of %s as %s in %s",
405 version,
406diff --git a/gitubuntu/importer_tag_test.py b/gitubuntu/importer_tag_test.py
407index a216e73..3573d9b 100644
408--- a/gitubuntu/importer_tag_test.py
409+++ b/gitubuntu/importer_tag_test.py
410@@ -205,6 +205,7 @@ from gitubuntu.importer_test import MockSPI, patch_get_commit_environment
411 'refs/tags/importer/upstream/ubuntu/1.gz',
412 'refs/heads/importer/importer/ubuntu/dsc',
413 'refs/heads/importer/importer/ubuntu/pristine-tar',
414+ 'refs/notes/importer/changelog',
415 ],
416 # validation_repo_delta:
417 {
418@@ -255,6 +256,7 @@ from gitubuntu.importer_test import MockSPI, patch_get_commit_environment
419 'refs/tags/importer/upstream/ubuntu/1.gz',
420 'refs/heads/importer/importer/ubuntu/dsc',
421 'refs/heads/importer/importer/ubuntu/pristine-tar',
422+ 'refs/notes/importer/changelog',
423 ],
424 # validation_repo_delta:
425 {
426@@ -335,6 +337,7 @@ from gitubuntu.importer_test import MockSPI, patch_get_commit_environment
427 'refs/tags/importer/upstream/ubuntu/1.gz',
428 'refs/heads/importer/importer/ubuntu/dsc',
429 'refs/heads/importer/importer/ubuntu/pristine-tar',
430+ 'refs/notes/importer/changelog',
431 ],
432 # validation_repo_delta:
433 {
434@@ -372,6 +375,7 @@ from gitubuntu.importer_test import MockSPI, patch_get_commit_environment
435 'refs/tags/importer/upstream/ubuntu/1.gz',
436 'refs/heads/importer/importer/ubuntu/dsc',
437 'refs/heads/importer/importer/ubuntu/pristine-tar',
438+ 'refs/notes/importer/changelog',
439 ],
440 # validation_repo_delta:
441 {
442diff --git a/gitubuntu/importer_test.py b/gitubuntu/importer_test.py
443index 54f1f2b..f94150d 100644
444--- a/gitubuntu/importer_test.py
445+++ b/gitubuntu/importer_test.py
446@@ -73,58 +73,21 @@ def test_get_import_tag_msg():
447
448
449 @pytest.mark.parametrize(
450- 'head_name_value, changelog_parent_commits, upload_parent_commit, unapplied_parent_commit, expected',
451+ 'patch_state, expected',
452 [
453 (
454- 'importer/ubuntu/trusty',
455- [],
456- None,
457- None,
458- b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.',
459- ),
460- (
461- 'importer/ubuntu/trusty',
462- ['123456'],
463- None,
464- None,
465- b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nChangelog parent: 123456',
466- ),
467- (
468- 'importer/ubuntu/trusty',
469- [],
470- '123456',
471- None,
472- b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nUpload parent: 123456',
473- ),
474- (
475- 'importer/ubuntu/trusty',
476- ['123456', '234567'],
477- None,
478- None,
479- b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nChangelog parent: 123456\nChangelog parent: 234567',
480- ),
481- (
482- 'importer/ubuntu/trusty',
483- [],
484- None,
485- '123456',
486- b'Import patches-applied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nUnapplied parent: 123456',
487+ PatchState.UNAPPLIED,
488+ b'1-1 (patches unapplied)\n\nImported using git-ubuntu import.',
489 ),
490 (
491- 'importer/ubuntu/trusty',
492- ['123456'],
493- '789123',
494- '456789',
495- b'Import patches-applied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nChangelog parent: 123456\nUpload parent: 789123\nUnapplied parent: 456789'
496+ PatchState.APPLIED,
497+ b'1-1 (patches applied)\n\nImported using git-ubuntu import.',
498 ),
499 ],
500 )
501 def test_get_import_commit_msg(
502 repo,
503- head_name_value,
504- changelog_parent_commits,
505- upload_parent_commit,
506- unapplied_parent_commit,
507+ patch_state,
508 expected,
509 ):
510 """Test that get_import_commit_msg is generally correct
511@@ -138,17 +101,10 @@ def test_get_import_commit_msg(
512
513 :param GitUbuntuRepository repo: fixture providing a temporary
514 GitUbuntuRepository instance to use
515- :param str head_name_value: passed through to get_import_commit_msg as
516- target_head_name
517- :param list(str) changelog_parent_commits: passed through to
518- get_import_commit_msg
519- :param str upload_parent_commit: passed through to get_import_commit_msg
520- :param str unapplied_parent_commit: passed through to get_import_commit_msg
521+ :param PatchState patch_state: whether the commit is for an unapplied or
522+ applied import, as passed through to the function under test
523 :param bytes expected: the expected return value from get_import_commit_msg
524 """
525- target.get_changelog_for_commit = Mock()
526- target.get_changelog_for_commit.return_value = b''
527-
528 publish_spec = source_builder.SourceSpec()
529 publish_source = source_builder.Source(publish_spec)
530
531@@ -160,12 +116,7 @@ def test_get_import_commit_msg(
532 assert target.get_import_commit_msg(
533 repo,
534 publish_spec.version,
535- head_name_value,
536- 'importer',
537- publish_tree_hash,
538- changelog_parent_commits,
539- upload_parent_commit,
540- unapplied_parent_commit,
541+ patch_state,
542 ) == expected
543
544
545@@ -862,6 +813,81 @@ def test_validate_upload_tag(
546 assert result == expected_result
547
548
549+def test_add_changelog_note_to_commit(repo):
550+ """add_changelog_note_to_commit should add the expected note"""
551+ repo_builder.Repo(
552+ commits=[
553+ repo_builder.Commit.from_spec(name='1-1'),
554+ repo_builder.Commit.from_spec(
555+ name='1-2',
556+ changelog_versions=['1-1', '1-2'],
557+ parents=[Placeholder('1-1')],
558+ ),
559+ ],
560+ tags={'1-1': Placeholder('1-1'), '1-2': Placeholder('1-2')},
561+ ).write(repo.raw_repo)
562+
563+ parent_commit_ref = repo.raw_repo.lookup_reference('refs/tags/1-1')
564+ parent_commit = parent_commit_ref.peel(pygit2.Commit)
565+
566+ child_commit_ref = repo.raw_repo.lookup_reference('refs/tags/1-2')
567+ child_commit = child_commit_ref.peel(pygit2.Commit)
568+
569+ target.add_changelog_note_to_commit(
570+ repo=repo,
571+ namespace='importer',
572+ commit=child_commit,
573+ changelog_parents=[str(parent_commit.id)],
574+ )
575+
576+ note = repo.raw_repo.lookup_note(
577+ str(child_commit.id),
578+ 'refs/notes/importer/changelog',
579+ )
580+ assert note.message == (
581+ "\n\nNew changelog entries:\n"
582+ " * Test build from source_builder.\n"
583+ )
584+
585+
586+def test_double_changelog_note_add_does_not_fail(repo):
587+ """add_changelog_note_to_commit shouldn't fail if a note already exists"""
588+ repo_builder.Repo(
589+ commits=[
590+ repo_builder.Commit.from_spec(name='1-1'),
591+ repo_builder.Commit.from_spec(
592+ name='1-2',
593+ changelog_versions=['1-1', '1-2'],
594+ parents=[Placeholder('1-1')],
595+ ),
596+ ],
597+ tags={'1-1': Placeholder('1-1'), '1-2': Placeholder('1-2')},
598+ ).write(repo.raw_repo)
599+
600+ parent_commit_ref = repo.raw_repo.lookup_reference('refs/tags/1-1')
601+ parent_commit = parent_commit_ref.peel(pygit2.Commit)
602+
603+ child_commit_ref = repo.raw_repo.lookup_reference('refs/tags/1-2')
604+ child_commit = child_commit_ref.peel(pygit2.Commit)
605+
606+ # The first call should create the note (tested elsewhere)
607+ target.add_changelog_note_to_commit(
608+ repo=repo,
609+ namespace='importer',
610+ commit=child_commit,
611+ changelog_parents=[str(parent_commit.id)],
612+ )
613+
614+ # The second call should not fail even though the note already exists (as
615+ # created by the previous call)
616+ target.add_changelog_note_to_commit(
617+ repo=repo,
618+ namespace='importer',
619+ commit=child_commit,
620+ changelog_parents=[str(parent_commit.id)],
621+ )
622+
623+
624 def patch_get_commit_environment(repo):
625 """Patch a repository to use constant metadata
626

Subscribers

People subscribed via source and target branches