Merge ~racb/git-ubuntu:changelog-parents into git-ubuntu:master
- Git
- lp:~racb/git-ubuntu
- changelog-parents
- Merge into master
Status: | Merged |
---|---|
Merged at revision: | fd197c345d0230cb721e62f62dbf01f0569a4003 |
Proposed branch: | ~racb/git-ubuntu:changelog-parents |
Merge into: | git-ubuntu:master |
Diff against target: |
972 lines (+357/-156) 2 files modified
gitubuntu/importer.py (+155/-106) gitubuntu/importer_test.py (+202/-50) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Bryce Harrington | Approve | ||
Server Team CI bot | continuous-integration | Approve | |
Review via email:
|
Commit message
Make Jenkins happy
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:7e2fc4a379c
https:/
Executed test runs:
SUCCESS: VM Setup
SUCCESS: Build
SUCCESS: Unit Tests
IN_PROGRESS: Declarative: Post Actions
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Bryce Harrington (bryce) wrote : | # |
I have a few very minor suggestions, but looks ok overall.
While this is a big patch, most of the code changes were straightforward to review; there were a few pytest mechanisms I wasn't familiar with, and there were a couple chunks of code that took me some time to untangle, but in the end I didn't spot any logical errors.
Since it's nicely broken up into conceptually distinct patches, I reviewed the code sequentially by patch, so am giving feedback thusly organized, hopefully it'll be clear what lines I'm referring to.
1. importer: drop unused variable
√ LGTM. Simple cleanup
2. Add test: test_get_
- 'repo' parameter could use a doc, e.g.:
":param gitubuntu.
- Add comment to explain "repo_builder.
"# Construct a synthetic git repository containing tags"
- Rename 'mock' variable to 'mock_repo'
3. Sort reimport tags before using them
√ LGTM. Interesting illustration of splitting the test from the fix via xfail.
4. Allow for multiple changelog parents
√ Previously the code checked that changelog_
now it checks len(changelog_
works fine, the one caveat being that this now implies an assumption
that changelog_
in then things will break. I did not spot any places where this is
likely to happen, though.
- Given that changelog_
there is a check around line 607 in _commit_import() that is probably
unnecessary. It used to be a None check, and now is effectively a
len()>0 check, however l.extend([]) will be a no-op so no need for a check.
5. test_get_
√ LGTM. I wondered if this could be done as an xfail test case, but it's fine as is.
6. Generalise test_get_
- Param docs for test_get_
√ Otherwise, LGTM
7. Add multiple changelog parent tests
√ LGTM
8. Support multiple changelog parents
√ The list comprehension for calculating changelog_
dense pythonically but on further review it's just using idioms already
common in importer.py.
As mentioned in #6, some of the test cases in importer_test.py are documented but not all; would be nice to ensure each of the 3 or 4 test cases added or changed in this patchset also gain docs while we're at it.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robie Basak (racb) wrote : | # |
> 2. Add test: test_get_
> - 'repo' parameter could use a doc, e.g.:
> ":param gitubuntu.
> repository to use."
Done, but note that importantly it's a fixture, so I noted that also.
> - Add comment to explain "repo_builder.
> "# Construct a synthetic git repository containing tags"
Done.
> - Rename 'mock' variable to 'mock_repo'
Actually it's not a mock Repo; it's a mocked method on the Repo class.
But I take your point, so I called it mock_get_
this is quite long, it busted the line length limit so I also had to
introduce mock_get_
too.
> 4. Allow for multiple changelog parents
> √ Previously the code checked that changelog_
> None, but now it checks len(changelog_
> Logically this works fine, the one caveat being that this now
> implies an assumption that changelog_
> list; if None ever got passed in then things will break. I did
> not spot any places where this is likely to happen, though.
Yes - that's the intention. changelog_
now, and we use an empty list instead of None now, in all cases, to
represent that there aren't any.
> - Given that changelog_
> there is a check around line 607 in _commit_import() that is probably
> unnecessary. It used to be a None check, and now is effectively a
> len()>0 check, however l.extend([]) will be a no-op so no need
> for a check.
Good point. Check removed.
> 5. test_get_
> √ LGTM. I wondered if this could be done as an xfail test case,
> but it's fine as is.
This was a case that the code was already correct but it lacked a test,
so the xfail process didn't apply. I'm not sure if you already said
that.
> 6. Generalise test_get_
> - Param docs for test_get_
Done.
> √ Otherwise, LGTM
> As mentioned in #6, some of the test cases in importer_test.py are
> documented but not all; would be nice to ensure each of the 3 or 4
> test cases added or changed in this patchset also gain docs while
> we're at it.
Done. I've ensured that every test case touched has a docstring. I did
this in a new commit at the end of the patchset. Some of this new
documentation exposes some shortcomings in the implementation, but in
the interest of making progress I documented the code as-is, leaving
improvements to the code for the future.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Robie Basak (racb) wrote : | # |
Here's the range-diff for your reference: http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:fd197c345d0
https:/
Executed test runs:
SUCCESS: VM Setup
SUCCESS: Build
SUCCESS: Unit Tests
IN_PROGRESS: Declarative: Post Actions
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Bryce Harrington (bryce) wrote : | # |
Thanks for the range-diff, all looks good, +1.
Preview Diff
1 | diff --git a/gitubuntu/importer.py b/gitubuntu/importer.py | |||
2 | index 98a0997..495a22d 100644 | |||
3 | --- a/gitubuntu/importer.py | |||
4 | +++ b/gitubuntu/importer.py | |||
5 | @@ -488,15 +488,19 @@ def main( | |||
6 | 488 | def get_changelog_for_commit( | 488 | def get_changelog_for_commit( |
7 | 489 | repo, | 489 | repo, |
8 | 490 | tree_hash, | 490 | tree_hash, |
10 | 491 | changelog_parent_commit, | 491 | changelog_parent_commits, |
11 | 492 | ): | 492 | ): |
12 | 493 | """Extract changes to debian/changelog in this publish | 493 | """Extract changes to debian/changelog in this publish |
13 | 494 | 494 | ||
14 | 495 | LP: #1633114 -- favor the changelog parent's diff | 495 | LP: #1633114 -- favor the changelog parent's diff |
15 | 496 | """ | 496 | """ |
16 | 497 | raw_clog_entry = b'' | 497 | raw_clog_entry = b'' |
19 | 498 | if changelog_parent_commit is not None: | 498 | # If there is more than one changelog parent then don't attempt to combine |
20 | 499 | cmd = ['diff-tree', '-p', changelog_parent_commit, | 499 | # their entries, and instead return nothing (raw_clog_entry will remain |
21 | 500 | # b''). This can be addressed later when the specification better defines | ||
22 | 501 | # what the commit message should say in this case, but will do for now. | ||
23 | 502 | if len(changelog_parent_commits) == 1: | ||
24 | 503 | cmd = ['diff-tree', '-p', changelog_parent_commits[0], | ||
25 | 500 | tree_hash, '--', 'debian/changelog'] | 504 | tree_hash, '--', 'debian/changelog'] |
26 | 501 | raw_clog_entry, _ = repo.git_run(cmd, decode=False) | 505 | raw_clog_entry, _ = repo.git_run(cmd, decode=False) |
27 | 502 | 506 | ||
28 | @@ -529,10 +533,32 @@ def get_import_commit_msg( | |||
29 | 529 | target_head_name, | 533 | target_head_name, |
30 | 530 | namespace, | 534 | namespace, |
31 | 531 | tree_hash, | 535 | tree_hash, |
33 | 532 | changelog_parent_commit, | 536 | changelog_parent_commits, |
34 | 533 | upload_parent_commit, | 537 | upload_parent_commit, |
35 | 534 | unapplied_parent_commit, | 538 | unapplied_parent_commit, |
36 | 535 | ): | 539 | ): |
37 | 540 | """Compose an appropriate commit message | ||
38 | 541 | |||
39 | 542 | When the importer synthesizes a commit, it needs to provide an appropriate | ||
40 | 543 | commit message. This function centralizes the generation of that message | ||
41 | 544 | based on the parameters given. | ||
42 | 545 | |||
43 | 546 | :param GitUbuntuRepository repo: the repository in which the tree being | ||
44 | 547 | committed can be found | ||
45 | 548 | :param str version: the package version string being committed | ||
46 | 549 | :param str target_head_name: the nominal name of the branch to which the | ||
47 | 550 | commit is being made | ||
48 | 551 | :param str namespace: the namespace name to prefix to the nominal branch | ||
49 | 552 | name to determine the final branch name | ||
50 | 553 | :param str tree_hash: the hash of the tree object being committed | ||
51 | 554 | :param list(str) changelog_parent_commits: any changelog parents to use in | ||
52 | 555 | the commit | ||
53 | 556 | :param str upload_parent_commit: the upload parent to use in the commit, or | ||
54 | 557 | None if there isn't one | ||
55 | 558 | :param str unapplied_parent_commit: the unapplied parent to use in the | ||
56 | 559 | commit, or None if this is an applied branch commit | ||
57 | 560 | |||
58 | 561 | """ | ||
59 | 536 | if unapplied_parent_commit: | 562 | if unapplied_parent_commit: |
60 | 537 | import_type = 'patches-applied' | 563 | import_type = 'patches-applied' |
61 | 538 | else: | 564 | else: |
62 | @@ -543,7 +569,7 @@ def get_import_commit_msg( | |||
63 | 543 | changelog_entry = get_changelog_for_commit( | 569 | changelog_entry = get_changelog_for_commit( |
64 | 544 | repo, | 570 | repo, |
65 | 545 | tree_hash, | 571 | tree_hash, |
67 | 546 | changelog_parent_commit | 572 | changelog_parent_commits |
68 | 547 | ) | 573 | ) |
69 | 548 | 574 | ||
70 | 549 | msg = ( | 575 | msg = ( |
71 | @@ -554,10 +580,10 @@ def get_import_commit_msg( | |||
72 | 554 | ) | 580 | ) |
73 | 555 | ) | 581 | ) |
74 | 556 | 582 | ||
76 | 557 | if any([changelog_parent_commit, upload_parent_commit, unapplied_parent_commit]): | 583 | if any([changelog_parent_commits, upload_parent_commit, unapplied_parent_commit]): |
77 | 558 | msg += b'\n' | 584 | msg += b'\n' |
78 | 559 | 585 | ||
80 | 560 | if changelog_parent_commit is not None: | 586 | for changelog_parent_commit in changelog_parent_commits: |
81 | 561 | msg += b'\nChangelog parent: %b' % changelog_parent_commit.encode() | 587 | msg += b'\nChangelog parent: %b' % changelog_parent_commit.encode() |
82 | 562 | if upload_parent_commit is not None: | 588 | if upload_parent_commit is not None: |
83 | 563 | msg += b'\nUpload parent: %b' % upload_parent_commit.encode() | 589 | msg += b'\nUpload parent: %b' % upload_parent_commit.encode() |
84 | @@ -574,7 +600,7 @@ def _commit_import( | |||
85 | 574 | target_head_name, | 600 | target_head_name, |
86 | 575 | tree_hash, | 601 | tree_hash, |
87 | 576 | namespace, | 602 | namespace, |
89 | 577 | changelog_parent_commit, | 603 | changelog_parent_commits, |
90 | 578 | upload_parent_commit, | 604 | upload_parent_commit, |
91 | 579 | unapplied_parent_commit, | 605 | unapplied_parent_commit, |
92 | 580 | commit_date, | 606 | commit_date, |
93 | @@ -594,8 +620,8 @@ def _commit_import( | |||
94 | 594 | :param target_head_name str Git branch name to import to | 620 | :param target_head_name str Git branch name to import to |
95 | 595 | :param namespace str Namespace under which relevant refs can be | 621 | :param namespace str Namespace under which relevant refs can be |
96 | 596 | found. | 622 | found. |
99 | 597 | :param changelog_parent_commit str Git commit hash of | 623 | :param list(str) changelog_parent_commits Git commit hashes of changelog |
100 | 598 | changelog parent. | 624 | parents. |
101 | 599 | :param upload_parent_commit str Git commit hash of | 625 | :param upload_parent_commit str Git commit hash of |
102 | 600 | upload parent. Should be None if patches-applied import. | 626 | upload parent. Should be None if patches-applied import. |
103 | 601 | :param unapplied_parent_commit str Git commit hash of unapplied | 627 | :param unapplied_parent_commit str Git commit hash of unapplied |
104 | @@ -605,16 +631,12 @@ def _commit_import( | |||
105 | 605 | :rtype str | 631 | :rtype str |
106 | 606 | :returns Hash of created commit | 632 | :returns Hash of created commit |
107 | 607 | """ | 633 | """ |
108 | 608 | changelog_entry = get_changelog_for_commit( | ||
109 | 609 | repo, | ||
110 | 610 | tree_hash, | ||
111 | 611 | changelog_parent_commit | ||
112 | 612 | ) | ||
113 | 613 | |||
114 | 614 | parents = [] | 634 | parents = [] |
115 | 615 | 635 | ||
118 | 616 | if changelog_parent_commit is not None: | 636 | parents.extend( |
119 | 617 | parents.append(pygit2.Oid(hex=changelog_parent_commit)) | 637 | pygit2.Oid(hex=changelog_parent_commit) |
120 | 638 | for changelog_parent_commit in changelog_parent_commits | ||
121 | 639 | ) | ||
122 | 618 | if upload_parent_commit is not None: | 640 | if upload_parent_commit is not None: |
123 | 619 | parents.append(pygit2.Oid(hex=upload_parent_commit)) | 641 | parents.append(pygit2.Oid(hex=upload_parent_commit)) |
124 | 620 | if unapplied_parent_commit is not None: | 642 | if unapplied_parent_commit is not None: |
125 | @@ -629,7 +651,7 @@ def _commit_import( | |||
126 | 629 | target_head_name=target_head_name, | 651 | target_head_name=target_head_name, |
127 | 630 | namespace=namespace, | 652 | namespace=namespace, |
128 | 631 | tree_hash=tree_hash, | 653 | tree_hash=tree_hash, |
130 | 632 | changelog_parent_commit=changelog_parent_commit, | 654 | changelog_parent_commits=changelog_parent_commits, |
131 | 633 | upload_parent_commit=upload_parent_commit, | 655 | upload_parent_commit=upload_parent_commit, |
132 | 634 | unapplied_parent_commit=unapplied_parent_commit, | 656 | unapplied_parent_commit=unapplied_parent_commit, |
133 | 635 | ), | 657 | ), |
134 | @@ -644,7 +666,7 @@ def commit_unapplied_patches_import( | |||
135 | 644 | head_name, | 666 | head_name, |
136 | 645 | import_tree_hash, | 667 | import_tree_hash, |
137 | 646 | namespace, | 668 | namespace, |
139 | 647 | changelog_parent_commit, | 669 | changelog_parent_commits, |
140 | 648 | upload_parent_commit, | 670 | upload_parent_commit, |
141 | 649 | commit_date, | 671 | commit_date, |
142 | 650 | ): | 672 | ): |
143 | @@ -654,7 +676,7 @@ def commit_unapplied_patches_import( | |||
144 | 654 | head_name, | 676 | head_name, |
145 | 655 | import_tree_hash, | 677 | import_tree_hash, |
146 | 656 | namespace, | 678 | namespace, |
148 | 657 | changelog_parent_commit, | 679 | changelog_parent_commits, |
149 | 658 | upload_parent_commit, | 680 | upload_parent_commit, |
150 | 659 | # unapplied trees do not have a distinct unapplied parent | 681 | # unapplied trees do not have a distinct unapplied parent |
151 | 660 | None, | 682 | None, |
152 | @@ -667,7 +689,7 @@ def commit_applied_patches_import( | |||
153 | 667 | head_name, | 689 | head_name, |
154 | 668 | import_tree_hash, | 690 | import_tree_hash, |
155 | 669 | namespace, | 691 | namespace, |
157 | 670 | changelog_parent_commit, | 692 | changelog_parent_commits, |
158 | 671 | unapplied_parent_commit, | 693 | unapplied_parent_commit, |
159 | 672 | commit_date, | 694 | commit_date, |
160 | 673 | ): | 695 | ): |
161 | @@ -677,7 +699,7 @@ def commit_applied_patches_import( | |||
162 | 677 | head_name, | 699 | head_name, |
163 | 678 | import_tree_hash, | 700 | import_tree_hash, |
164 | 679 | namespace, | 701 | namespace, |
166 | 680 | changelog_parent_commit, | 702 | changelog_parent_commits, |
167 | 681 | # uploads will be unapplied trees currently, so applied trees | 703 | # uploads will be unapplied trees currently, so applied trees |
168 | 682 | # can not have them as direct parents | 704 | # can not have them as direct parents |
169 | 683 | None, | 705 | None, |
170 | @@ -985,16 +1007,35 @@ def get_existing_import_tags( | |||
171 | 985 | namespace, | 1007 | namespace, |
172 | 986 | patch_state=PatchState.UNAPPLIED, | 1008 | patch_state=PatchState.UNAPPLIED, |
173 | 987 | ): | 1009 | ): |
174 | 1010 | """Find and return any import tags that already exist for the given version | ||
175 | 1011 | |||
176 | 1012 | :param GitUbuntuRepository repo: repository to search for import tags | ||
177 | 1013 | :param str version: the package version string to find | ||
178 | 1014 | :param str namespace: the name to prefix to the import tag names searched | ||
179 | 1015 | :param PatchState patch_state: whether to look for unapplied or applied | ||
180 | 1016 | tags | ||
181 | 1017 | :rtype: list(pygit2.Reference) | ||
182 | 1018 | :returns: a list of import tags found. If reimport tags exist, this is the | ||
183 | 1019 | list of matching reimport tags in order; the original import tag is not | ||
184 | 1020 | included as it is already represented by the first reimport tag. If | ||
185 | 1021 | reimport tags do not exist, just the sole import tag is returned. If | ||
186 | 1022 | none of these are found, the empty list is returned. | ||
187 | 1023 | """ | ||
188 | 988 | existing_import_tag = repo.get_import_tag(version, namespace, patch_state) | 1024 | existing_import_tag = repo.get_import_tag(version, namespace, patch_state) |
189 | 989 | if existing_import_tag: | 1025 | if existing_import_tag: |
191 | 990 | # check if there are reimports | 1026 | # check if there are reimports; if no import tag exists, then by the |
192 | 1027 | # specification there can be no reimports | ||
193 | 991 | existing_reimport_tags = repo.get_all_reimport_tags( | 1028 | existing_reimport_tags = repo.get_all_reimport_tags( |
194 | 992 | version, | 1029 | version, |
195 | 993 | namespace, | 1030 | namespace, |
196 | 994 | patch_state, | 1031 | patch_state, |
197 | 995 | ) | 1032 | ) |
198 | 996 | if existing_reimport_tags: | 1033 | if existing_reimport_tags: |
200 | 997 | return existing_reimport_tags | 1034 | return sorted( |
201 | 1035 | existing_reimport_tags, | ||
202 | 1036 | # Sort on the integer of the last '/'-separated component | ||
203 | 1037 | key=lambda tag: int(tag.name.split('/')[-1]), | ||
204 | 1038 | ) | ||
205 | 998 | else: | 1039 | else: |
206 | 999 | return [existing_import_tag] | 1040 | return [existing_import_tag] |
207 | 1000 | return [] | 1041 | return [] |
208 | @@ -1002,10 +1043,10 @@ def get_existing_import_tags( | |||
209 | 1002 | 1043 | ||
210 | 1003 | def override_parents(parent_overrides, repo, version, namespace): | 1044 | def override_parents(parent_overrides, repo, version, namespace): |
211 | 1004 | """ | 1045 | """ |
216 | 1005 | returns: (unapplied, applied) where both elements of the tuple are commit | 1046 | returns: (unapplied, applied) where both elements of the tuple are lists of |
217 | 1006 | hash strings of the changelog parent to use, incorporating any defined | 1047 | commit hash strings of the changelog parents to use, incorporating any |
218 | 1007 | overrides. | 1048 | defined overrides. |
219 | 1008 | rtype: tuple(str, str) | 1049 | rtype: tuple(list(str), list(str)) |
220 | 1009 | """ | 1050 | """ |
221 | 1010 | unapplied_changelog_parent_commit = None | 1051 | unapplied_changelog_parent_commit = None |
222 | 1011 | applied_changelog_parent_commit = None | 1052 | applied_changelog_parent_commit = None |
223 | @@ -1057,8 +1098,8 @@ def override_parents(parent_overrides, repo, version, namespace): | |||
224 | 1057 | ) | 1098 | ) |
225 | 1058 | ) | 1099 | ) |
226 | 1059 | return ( | 1100 | return ( |
229 | 1060 | unapplied_changelog_parent_commit, | 1101 | [unapplied_changelog_parent_commit], |
230 | 1061 | applied_changelog_parent_commit, | 1102 | [applied_changelog_parent_commit], |
231 | 1062 | ) | 1103 | ) |
232 | 1063 | 1104 | ||
233 | 1064 | def _devel_branch_updates( | 1105 | def _devel_branch_updates( |
234 | @@ -1296,72 +1337,83 @@ def create_import_tag(repo, commit_hash, version, namespace): | |||
235 | 1296 | return repo.get_import_tag(version, namespace) | 1337 | return repo.get_import_tag(version, namespace) |
236 | 1297 | 1338 | ||
237 | 1298 | 1339 | ||
239 | 1299 | def get_changelog_parent_commit( | 1340 | def get_changelog_parent_commits( |
240 | 1300 | repo, | 1341 | repo, |
241 | 1301 | namespace, | 1342 | namespace, |
242 | 1302 | parent_overrides, | 1343 | parent_overrides, |
243 | 1303 | import_tree_versions, | 1344 | import_tree_versions, |
245 | 1304 | patches_applied, | 1345 | patch_state, |
246 | 1305 | ): | 1346 | ): |
260 | 1306 | """Walk changelog backwards until we find an imported version, | 1347 | """Given a changelog history, find the changelog parent commits |
261 | 1307 | skipping the current version | 1348 | |
262 | 1308 | 1349 | "Changelog parents" are defined in the import specification, which refers | |
263 | 1309 | :param repo gitubuntu.git_repository.GitUbuntuRepository The | 1350 | to source package data instances. Since this importer runs incrementally in |
264 | 1310 | repository to use | 1351 | Launchpad publication order, the commits associated with the source package |
265 | 1311 | :param parent_overrides dict See parse_parentfile | 1352 | data instances can be located by traversing the matching reimport tags in |
266 | 1312 | :param import_tree_versions list(str) List of versions to iterate. | 1353 | order. If there are no reimport tags, the sole import tag (if it exists) |
267 | 1313 | :param patches_applied bool If true, look for patches-applied | 1354 | will match the sole corresponding source package data instance. Otherwise |
268 | 1314 | imports | 1355 | we find no changelog parent and return an empty list. |
269 | 1315 | 1356 | ||
270 | 1316 | :rtype str | 1357 | This function performs this search and returns a list of commit hashes that |
271 | 1317 | :returns Git commit hash of the nearest (chronologically) imported | 1358 | are the changelog parents. |
272 | 1318 | changelog version | 1359 | |
273 | 1360 | :param gitubuntu.git_repository.GitUbuntuRepository repo: the repository to | ||
274 | 1361 | use | ||
275 | 1362 | :param dict parent_overrides: see parse_parentfile | ||
276 | 1363 | :param list(str) import_tree_versions: list of package version strings as | ||
277 | 1364 | parsed from debian/changelog in the same order | ||
278 | 1365 | :param PatchState patch_state: whether to look for previous unapplied or | ||
279 | 1366 | applied imports | ||
280 | 1367 | |||
281 | 1368 | :rtype: list(str) | ||
282 | 1369 | :returns: a list of commit hashes of any existing imports of the changelog | ||
283 | 1370 | parents as defined by the import specification | ||
284 | 1319 | """ | 1371 | """ |
285 | 1320 | # skip current version | 1372 | # skip current version |
286 | 1321 | import_tree_versions = import_tree_versions[1:] | 1373 | import_tree_versions = import_tree_versions[1:] |
287 | 1322 | 1374 | ||
288 | 1323 | for version in import_tree_versions: | 1375 | for version in import_tree_versions: |
304 | 1324 | if patches_applied: | 1376 | changelog_parent_tags = get_existing_import_tags( |
305 | 1325 | changelog_parent_tag = repo.get_import_tag( | 1377 | repo, |
306 | 1326 | version, | 1378 | version, |
307 | 1327 | namespace, | 1379 | namespace, |
308 | 1328 | PatchState.APPLIED, | 1380 | patch_state, |
309 | 1329 | ) | 1381 | ) |
295 | 1330 | else: | ||
296 | 1331 | changelog_parent_tag = repo.get_import_tag( | ||
297 | 1332 | version, | ||
298 | 1333 | namespace, | ||
299 | 1334 | PatchState.UNAPPLIED, | ||
300 | 1335 | ) or repo.get_orphan_tag( | ||
301 | 1336 | version, | ||
302 | 1337 | namespace, | ||
303 | 1338 | ) | ||
310 | 1339 | 1382 | ||
312 | 1340 | if not changelog_parent_tag: | 1383 | if not changelog_parent_tags: |
313 | 1341 | continue | 1384 | continue |
314 | 1342 | 1385 | ||
315 | 1343 | # sanity check that version from d/changelog of the | 1386 | # sanity check that version from d/changelog of the |
316 | 1344 | # tagged parent matches ours | 1387 | # tagged parent matches ours |
320 | 1345 | changelog_parent_version, _ = repo.get_changelog_versions_from_treeish( | 1388 | changelog_parent_versions = [ |
321 | 1346 | str(changelog_parent_tag.peel(pygit2.Tree).id) | 1389 | repo.get_changelog_versions_from_treeish( |
322 | 1347 | ) | 1390 | str(tag.peel(pygit2.Tree).id) |
323 | 1391 | )[0] for tag in changelog_parent_tags | ||
324 | 1392 | ] | ||
325 | 1348 | 1393 | ||
326 | 1349 | # if the parent was imported via a parent override | 1394 | # if the parent was imported via a parent override |
327 | 1350 | # itself, assume it is valid without checking its | 1395 | # itself, assume it is valid without checking its |
328 | 1351 | # tree's debian/changelog, as it wasn't used | 1396 | # tree's debian/changelog, as it wasn't used |
329 | 1352 | if (version in parent_overrides or | 1397 | if (version in parent_overrides or |
334 | 1353 | changelog_parent_version == version | 1398 | any( |
335 | 1354 | ): | 1399 | [changelog_parent_version == version |
336 | 1355 | changelog_parent_commit = str( | 1400 | for changelog_parent_version in changelog_parent_versions] |
333 | 1356 | changelog_parent_tag.peel(pygit2.Commit).id | ||
337 | 1357 | ) | 1401 | ) |
341 | 1358 | 1402 | ): | |
342 | 1359 | logging.debug("Changelog parent (tag) is %s", | 1403 | changelog_parent_commits = [ |
343 | 1360 | repo.tag_to_pretty_name(changelog_parent_tag) | 1404 | str(tag.peel(pygit2.Commit).id) |
344 | 1405 | for tag in changelog_parent_tags | ||
345 | 1406 | ] | ||
346 | 1407 | |||
347 | 1408 | logging.debug("Changelog parent(s) (tag(s)) are %s", | ||
348 | 1409 | [ | ||
349 | 1410 | repo.tag_to_pretty_name(tag) | ||
350 | 1411 | for tag in changelog_parent_tags | ||
351 | 1412 | ] | ||
352 | 1361 | ) | 1413 | ) |
354 | 1362 | return changelog_parent_commit | 1414 | return changelog_parent_commits |
355 | 1363 | 1415 | ||
357 | 1364 | return None | 1416 | return [] |
358 | 1365 | 1417 | ||
359 | 1366 | 1418 | ||
360 | 1367 | def import_unapplied_dsc( | 1419 | def import_unapplied_dsc( |
361 | @@ -1463,7 +1515,6 @@ def import_unapplied_dsc( | |||
362 | 1463 | 1515 | ||
363 | 1464 | logging.debug('Tip version is %s', unapplied_tip_version) | 1516 | logging.debug('Tip version is %s', unapplied_tip_version) |
364 | 1465 | 1517 | ||
365 | 1466 | unapplied_changelog_parent_commit = None | ||
366 | 1467 | upload_parent_commit = None | 1518 | upload_parent_commit = None |
367 | 1468 | 1519 | ||
368 | 1469 | if version in parent_overrides: | 1520 | if version in parent_overrides: |
369 | @@ -1474,7 +1525,7 @@ def import_unapplied_dsc( | |||
370 | 1474 | 1525 | ||
371 | 1475 | try: | 1526 | try: |
372 | 1476 | ( | 1527 | ( |
374 | 1477 | unapplied_changelog_parent_commit, | 1528 | unapplied_changelog_parent_commits, |
375 | 1478 | _ | 1529 | _ |
376 | 1479 | ) = override_parents( | 1530 | ) = override_parents( |
377 | 1480 | parent_overrides, | 1531 | parent_overrides, |
378 | @@ -1494,12 +1545,12 @@ def import_unapplied_dsc( | |||
379 | 1494 | unapplied_tip_version, | 1545 | unapplied_tip_version, |
380 | 1495 | ) | 1546 | ) |
381 | 1496 | 1547 | ||
383 | 1497 | unapplied_changelog_parent_commit = get_changelog_parent_commit( | 1548 | unapplied_changelog_parent_commits = get_changelog_parent_commits( |
384 | 1498 | repo, | 1549 | repo, |
385 | 1499 | namespace, | 1550 | namespace, |
386 | 1500 | parent_overrides, | 1551 | parent_overrides, |
387 | 1501 | import_tree_versions, | 1552 | import_tree_versions, |
389 | 1502 | patches_applied=False, | 1553 | patch_state=PatchState.UNAPPLIED, |
390 | 1503 | ) | 1554 | ) |
391 | 1504 | 1555 | ||
392 | 1505 | # check if the version to import has already been uploaded to | 1556 | # check if the version to import has already been uploaded to |
393 | @@ -1515,7 +1566,7 @@ def import_unapplied_dsc( | |||
394 | 1515 | "does not match the published version. Will orphan commit.", | 1566 | "does not match the published version. Will orphan commit.", |
395 | 1516 | repo.tag_to_pretty_name(existing_import_tag), | 1567 | repo.tag_to_pretty_name(existing_import_tag), |
396 | 1517 | ) | 1568 | ) |
398 | 1518 | unapplied_changelog_parent_commit = None | 1569 | unapplied_changelog_parent_commits = [] |
399 | 1519 | else: | 1570 | else: |
400 | 1520 | repo.update_head_to_commit( | 1571 | repo.update_head_to_commit( |
401 | 1521 | head_name, | 1572 | head_name, |
402 | @@ -1549,31 +1600,31 @@ def import_unapplied_dsc( | |||
403 | 1549 | else: | 1600 | else: |
404 | 1550 | upload_parent_commit = str(existing_upload_tag.peel().id) | 1601 | upload_parent_commit = str(existing_upload_tag.peel().id) |
405 | 1551 | 1602 | ||
407 | 1552 | if unapplied_changelog_parent_commit is not None: | 1603 | if unapplied_changelog_parent_commits: |
408 | 1553 | try: | 1604 | try: |
409 | 1554 | repo.git_run( | 1605 | repo.git_run( |
410 | 1555 | [ | 1606 | [ |
411 | 1556 | 'merge-base', | 1607 | 'merge-base', |
412 | 1557 | '--is-ancestor', | 1608 | '--is-ancestor', |
414 | 1558 | unapplied_changelog_parent_commit, | 1609 | unapplied_changelog_parent_commits[0], |
415 | 1559 | upload_parent_commit, | 1610 | upload_parent_commit, |
416 | 1560 | ], | 1611 | ], |
417 | 1561 | verbose_on_failure=False, | 1612 | verbose_on_failure=False, |
418 | 1562 | ) | 1613 | ) |
420 | 1563 | unapplied_changelog_parent_commit = None | 1614 | unapplied_changelog_parent_commits = [] |
421 | 1564 | except CalledProcessError as e: | 1615 | except CalledProcessError as e: |
422 | 1565 | if e.returncode != 1: | 1616 | if e.returncode != 1: |
423 | 1566 | raise | 1617 | raise |
424 | 1567 | 1618 | ||
425 | 1568 | commit_hash = commit_unapplied_patches_import( | 1619 | commit_hash = commit_unapplied_patches_import( |
434 | 1569 | repo, | 1620 | repo=repo, |
435 | 1570 | version, | 1621 | version=version, |
436 | 1571 | head_name, | 1622 | head_name=head_name, |
437 | 1572 | unapplied_import_tree_hash, | 1623 | import_tree_hash=unapplied_import_tree_hash, |
438 | 1573 | namespace, | 1624 | namespace=namespace, |
439 | 1574 | unapplied_changelog_parent_commit, | 1625 | changelog_parent_commits=unapplied_changelog_parent_commits, |
440 | 1575 | upload_parent_commit, | 1626 | upload_parent_commit=upload_parent_commit, |
441 | 1576 | commit_date, | 1627 | commit_date=commit_date, |
442 | 1577 | ) | 1628 | ) |
443 | 1578 | logging.debug( | 1629 | logging.debug( |
444 | 1579 | "Committed patches-unapplied import of %s as %s in %s", | 1630 | "Committed patches-unapplied import of %s as %s in %s", |
445 | @@ -1587,7 +1638,7 @@ def import_unapplied_dsc( | |||
446 | 1587 | # Not imported before | 1638 | # Not imported before |
447 | 1588 | tag = import_tag(version, namespace) | 1639 | tag = import_tag(version, namespace) |
448 | 1589 | elif ( | 1640 | elif ( |
450 | 1590 | unapplied_changelog_parent_commit is None and | 1641 | not unapplied_changelog_parent_commits and |
451 | 1591 | upload_parent_commit is None and | 1642 | upload_parent_commit is None and |
452 | 1592 | head_name in repo.local_branch_names | 1643 | head_name in repo.local_branch_names |
453 | 1593 | ): | 1644 | ): |
454 | @@ -1726,8 +1777,6 @@ def import_applied_dsc( | |||
455 | 1726 | 1777 | ||
456 | 1727 | logging.debug('Tip version is %s', applied_tip_version) | 1778 | logging.debug('Tip version is %s', applied_tip_version) |
457 | 1728 | 1779 | ||
458 | 1729 | applied_changelog_parent_commit = None | ||
459 | 1730 | |||
460 | 1731 | if version in parent_overrides: | 1780 | if version in parent_overrides: |
461 | 1732 | logging.debug('%s is specified in the parent override file.' % | 1781 | logging.debug('%s is specified in the parent override file.' % |
462 | 1733 | version | 1782 | version |
463 | @@ -1735,7 +1784,7 @@ def import_applied_dsc( | |||
464 | 1735 | 1784 | ||
465 | 1736 | ( | 1785 | ( |
466 | 1737 | _, | 1786 | _, |
468 | 1738 | applied_changelog_parent_commit, | 1787 | applied_changelog_parent_commits, |
469 | 1739 | ) = override_parents( | 1788 | ) = override_parents( |
470 | 1740 | parent_overrides, | 1789 | parent_overrides, |
471 | 1741 | repo, | 1790 | repo, |
472 | @@ -1749,12 +1798,12 @@ def import_applied_dsc( | |||
473 | 1749 | ) | 1798 | ) |
474 | 1750 | 1799 | ||
475 | 1751 | 1800 | ||
477 | 1752 | applied_changelog_parent_commit = get_changelog_parent_commit( | 1801 | applied_changelog_parent_commits = get_changelog_parent_commits( |
478 | 1753 | repo, | 1802 | repo, |
479 | 1754 | namespace, | 1803 | namespace, |
480 | 1755 | parent_overrides, | 1804 | parent_overrides, |
481 | 1756 | import_tree_versions, | 1805 | import_tree_versions, |
483 | 1757 | patches_applied=True, | 1806 | patch_state=PatchState.APPLIED, |
484 | 1758 | ) | 1807 | ) |
485 | 1759 | 1808 | ||
486 | 1760 | existing_applied_tag = repo.get_import_tag( | 1809 | existing_applied_tag = repo.get_import_tag( |
487 | @@ -1774,7 +1823,7 @@ def import_applied_dsc( | |||
488 | 1774 | # "version. Will orphan commit.", | 1823 | # "version. Will orphan commit.", |
489 | 1775 | # repo.tag_to_pretty_name(applied_tag), | 1824 | # repo.tag_to_pretty_name(applied_tag), |
490 | 1776 | # ) | 1825 | # ) |
492 | 1777 | # applied_changelog_parent_commit = None | 1826 | # applied_changelog_parent_commits = [] |
493 | 1778 | #else: | 1827 | #else: |
494 | 1779 | repo.update_head_to_commit( | 1828 | repo.update_head_to_commit( |
495 | 1780 | head_name, | 1829 | head_name, |
496 | @@ -1822,14 +1871,14 @@ def import_applied_dsc( | |||
497 | 1822 | raise | 1871 | raise |
498 | 1823 | 1872 | ||
499 | 1824 | commit_hash = commit_applied_patches_import( | 1873 | commit_hash = commit_applied_patches_import( |
508 | 1825 | repo, | 1874 | repo=repo, |
509 | 1826 | version, | 1875 | version=version, |
510 | 1827 | head_name, | 1876 | head_name=head_name, |
511 | 1828 | applied_import_tree_hash, | 1877 | import_tree_hash=applied_import_tree_hash, |
512 | 1829 | namespace, | 1878 | namespace=namespace, |
513 | 1830 | applied_changelog_parent_commit, | 1879 | changelog_parent_commits=applied_changelog_parent_commits, |
514 | 1831 | str(unapplied_parent_commit), | 1880 | unapplied_parent_commit=str(unapplied_parent_commit), |
515 | 1832 | commit_date, | 1881 | commit_date=commit_date, |
516 | 1833 | ) | 1882 | ) |
517 | 1834 | logging.debug( | 1883 | logging.debug( |
518 | 1835 | "Committed patches-applied import of %s as %s in %s", | 1884 | "Committed patches-applied import of %s as %s in %s", |
519 | @@ -1843,7 +1892,7 @@ def import_applied_dsc( | |||
520 | 1843 | # Not imported before | 1892 | # Not imported before |
521 | 1844 | tag = import_tag(version, namespace, PatchState.APPLIED) | 1893 | tag = import_tag(version, namespace, PatchState.APPLIED) |
522 | 1845 | elif ( | 1894 | elif ( |
524 | 1846 | applied_changelog_parent_commit is None and | 1895 | not applied_changelog_parent_commits and |
525 | 1847 | unapplied_parent_commit is None and | 1896 | unapplied_parent_commit is None and |
526 | 1848 | head_name in repo.local_branch_names | 1897 | head_name in repo.local_branch_names |
527 | 1849 | ): | 1898 | ): |
528 | diff --git a/gitubuntu/importer_test.py b/gitubuntu/importer_test.py | |||
529 | index b1dcdc3..95744d9 100644 | |||
530 | --- a/gitubuntu/importer_test.py | |||
531 | +++ b/gitubuntu/importer_test.py | |||
532 | @@ -73,39 +73,46 @@ def test_get_import_tag_msg(): | |||
533 | 73 | 73 | ||
534 | 74 | 74 | ||
535 | 75 | @pytest.mark.parametrize( | 75 | @pytest.mark.parametrize( |
537 | 76 | 'head_name_value, changelog_parent_commit, upload_parent_commit, unapplied_parent_commit, expected', | 76 | 'head_name_value, changelog_parent_commits, upload_parent_commit, unapplied_parent_commit, expected', |
538 | 77 | [ | 77 | [ |
539 | 78 | ( | 78 | ( |
540 | 79 | 'importer/ubuntu/trusty', | 79 | 'importer/ubuntu/trusty', |
542 | 80 | None, | 80 | [], |
543 | 81 | None, | 81 | None, |
544 | 82 | None, | 82 | None, |
545 | 83 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.', | 83 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.', |
546 | 84 | ), | 84 | ), |
547 | 85 | ( | 85 | ( |
548 | 86 | 'importer/ubuntu/trusty', | 86 | 'importer/ubuntu/trusty', |
550 | 87 | '123456', | 87 | ['123456'], |
551 | 88 | None, | 88 | None, |
552 | 89 | None, | 89 | None, |
553 | 90 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nChangelog parent: 123456', | 90 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nChangelog parent: 123456', |
554 | 91 | ), | 91 | ), |
555 | 92 | ( | 92 | ( |
556 | 93 | 'importer/ubuntu/trusty', | 93 | 'importer/ubuntu/trusty', |
558 | 94 | None, | 94 | [], |
559 | 95 | '123456', | 95 | '123456', |
560 | 96 | None, | 96 | None, |
561 | 97 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nUpload parent: 123456', | 97 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nUpload parent: 123456', |
562 | 98 | ), | 98 | ), |
563 | 99 | ( | 99 | ( |
564 | 100 | 'importer/ubuntu/trusty', | 100 | 'importer/ubuntu/trusty', |
565 | 101 | ['123456', '234567'], | ||
566 | 102 | None, | ||
567 | 101 | None, | 103 | None, |
568 | 104 | b'Import patches-unapplied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nChangelog parent: 123456\nChangelog parent: 234567', | ||
569 | 105 | ), | ||
570 | 106 | ( | ||
571 | 107 | 'importer/ubuntu/trusty', | ||
572 | 108 | [], | ||
573 | 102 | None, | 109 | None, |
574 | 103 | '123456', | 110 | '123456', |
575 | 104 | b'Import patches-applied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nUnapplied parent: 123456', | 111 | b'Import patches-applied version 1-1 to ubuntu/trusty\n\nImported using git-ubuntu import.\n\nUnapplied parent: 123456', |
576 | 105 | ), | 112 | ), |
577 | 106 | ( | 113 | ( |
578 | 107 | 'importer/ubuntu/trusty', | 114 | 'importer/ubuntu/trusty', |
580 | 108 | '123456', | 115 | ['123456'], |
581 | 109 | '789123', | 116 | '789123', |
582 | 110 | '456789', | 117 | '456789', |
583 | 111 | 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' | 118 | 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' |
584 | @@ -115,11 +122,30 @@ def test_get_import_tag_msg(): | |||
585 | 115 | def test_get_import_commit_msg( | 122 | def test_get_import_commit_msg( |
586 | 116 | repo, | 123 | repo, |
587 | 117 | head_name_value, | 124 | head_name_value, |
589 | 118 | changelog_parent_commit, | 125 | changelog_parent_commits, |
590 | 119 | upload_parent_commit, | 126 | upload_parent_commit, |
591 | 120 | unapplied_parent_commit, | 127 | unapplied_parent_commit, |
592 | 121 | expected, | 128 | expected, |
593 | 122 | ): | 129 | ): |
594 | 130 | """Test that get_import_commit_msg is generally correct | ||
595 | 131 | |||
596 | 132 | This is the general parameterised test for the common case uses of | ||
597 | 133 | target.get_import_commit_msg. | ||
598 | 134 | |||
599 | 135 | This test uses a default source_builder.SourceSpec() to construct a test | ||
600 | 136 | source tree to provide to get_import_commit_msg, so defaults from | ||
601 | 137 | SourceSpec() will be used such as a package version string of '1-1'. | ||
602 | 138 | |||
603 | 139 | :param GitUbuntuRepository repo: fixture providing a temporary | ||
604 | 140 | GitUbuntuRepository instance to use | ||
605 | 141 | :param str head_name_value: passed through to get_import_commit_msg as | ||
606 | 142 | target_head_name | ||
607 | 143 | :param list(str) changelog_parent_commits: passed through to | ||
608 | 144 | get_import_commit_msg | ||
609 | 145 | :param str upload_parent_commit: passed through to get_import_commit_msg | ||
610 | 146 | :param str unapplied_parent_commit: passed through to get_import_commit_msg | ||
611 | 147 | :param bytes expected: the expected return value from get_import_commit_msg | ||
612 | 148 | """ | ||
613 | 123 | target.get_changelog_for_commit = Mock() | 149 | target.get_changelog_for_commit = Mock() |
614 | 124 | target.get_changelog_for_commit.return_value = b'' | 150 | target.get_changelog_for_commit.return_value = b'' |
615 | 125 | 151 | ||
616 | @@ -137,22 +163,24 @@ def test_get_import_commit_msg( | |||
617 | 137 | head_name_value, | 163 | head_name_value, |
618 | 138 | 'importer', | 164 | 'importer', |
619 | 139 | publish_tree_hash, | 165 | publish_tree_hash, |
621 | 140 | changelog_parent_commit, | 166 | changelog_parent_commits, |
622 | 141 | upload_parent_commit, | 167 | upload_parent_commit, |
623 | 142 | unapplied_parent_commit, | 168 | unapplied_parent_commit, |
624 | 143 | ) == expected | 169 | ) == expected |
625 | 144 | 170 | ||
626 | 145 | 171 | ||
627 | 146 | @pytest.mark.parametrize( | 172 | @pytest.mark.parametrize( |
629 | 147 | 'input_repo, expected', [ | 173 | 'input_repo, patch_state, expected', [ |
630 | 148 | ( | 174 | ( |
631 | 149 | repo_builder.Repo(), | 175 | repo_builder.Repo(), |
632 | 176 | PatchState.UNAPPLIED, | ||
633 | 150 | [], | 177 | [], |
634 | 151 | ), | 178 | ), |
635 | 152 | ( | 179 | ( |
636 | 153 | repo_builder.Repo( | 180 | repo_builder.Repo( |
637 | 154 | tags={'importer/import/1-1': repo_builder.Commit()}, | 181 | tags={'importer/import/1-1': repo_builder.Commit()}, |
638 | 155 | ), | 182 | ), |
639 | 183 | PatchState.UNAPPLIED, | ||
640 | 156 | ['refs/tags/importer/import/1-1'], | 184 | ['refs/tags/importer/import/1-1'], |
641 | 157 | ), | 185 | ), |
642 | 158 | ( | 186 | ( |
643 | @@ -167,32 +195,22 @@ def test_get_import_commit_msg( | |||
644 | 167 | 'importer/reimport/import/1-1/1': repo_builder.Commit(), | 195 | 'importer/reimport/import/1-1/1': repo_builder.Commit(), |
645 | 168 | }, | 196 | }, |
646 | 169 | ), | 197 | ), |
647 | 198 | PatchState.UNAPPLIED, | ||
648 | 170 | [ | 199 | [ |
649 | 171 | 'refs/tags/importer/reimport/import/1-1/0', | 200 | 'refs/tags/importer/reimport/import/1-1/0', |
650 | 172 | 'refs/tags/importer/reimport/import/1-1/1', | 201 | 'refs/tags/importer/reimport/import/1-1/1', |
651 | 173 | ], | 202 | ], |
652 | 174 | ), | 203 | ), |
653 | 175 | ], | ||
654 | 176 | ) | ||
655 | 177 | def test_get_existing_import_tags(repo, input_repo, expected): | ||
656 | 178 | input_repo.write(repo.raw_repo) | ||
657 | 179 | |||
658 | 180 | assert [ | ||
659 | 181 | ref.name for ref in | ||
660 | 182 | target.get_existing_import_tags(repo, '1-1', 'importer') | ||
661 | 183 | ] == expected | ||
662 | 184 | |||
663 | 185 | |||
664 | 186 | @pytest.mark.parametrize( | ||
665 | 187 | 'input_repo, expected', [ | ||
666 | 188 | ( | 204 | ( |
667 | 189 | repo_builder.Repo(), | 205 | repo_builder.Repo(), |
668 | 206 | PatchState.APPLIED, | ||
669 | 190 | [], | 207 | [], |
670 | 191 | ), | 208 | ), |
671 | 192 | ( | 209 | ( |
672 | 193 | repo_builder.Repo( | 210 | repo_builder.Repo( |
673 | 194 | tags={'importer/applied/1-1': repo_builder.Commit()}, | 211 | tags={'importer/applied/1-1': repo_builder.Commit()}, |
674 | 195 | ), | 212 | ), |
675 | 213 | PatchState.APPLIED, | ||
676 | 196 | ['refs/tags/importer/applied/1-1'], | 214 | ['refs/tags/importer/applied/1-1'], |
677 | 197 | ), | 215 | ), |
678 | 198 | ( | 216 | ( |
679 | @@ -207,6 +225,7 @@ def test_get_existing_import_tags(repo, input_repo, expected): | |||
680 | 207 | 'importer/reimport/applied/1-1/1': repo_builder.Commit(), | 225 | 'importer/reimport/applied/1-1/1': repo_builder.Commit(), |
681 | 208 | }, | 226 | }, |
682 | 209 | ), | 227 | ), |
683 | 228 | PatchState.APPLIED, | ||
684 | 210 | [ | 229 | [ |
685 | 211 | 'refs/tags/importer/reimport/applied/1-1/0', | 230 | 'refs/tags/importer/reimport/applied/1-1/0', |
686 | 212 | 'refs/tags/importer/reimport/applied/1-1/1', | 231 | 'refs/tags/importer/reimport/applied/1-1/1', |
687 | @@ -214,18 +233,78 @@ def test_get_existing_import_tags(repo, input_repo, expected): | |||
688 | 214 | ), | 233 | ), |
689 | 215 | ], | 234 | ], |
690 | 216 | ) | 235 | ) |
692 | 217 | def test_get_existing_applied_tags(repo, input_repo, expected): | 236 | def test_get_existing_import_tags(repo, patch_state, input_repo, expected): |
693 | 237 | """Test that get_existing_import_tags is generally correct | ||
694 | 238 | |||
695 | 239 | This is the general parameterised test for the common case uses of | ||
696 | 240 | target.get_existing_import_tags. | ||
697 | 241 | |||
698 | 242 | :param repo gitubuntu.git_repository.GitUbuntuRepository: fixture to hold a | ||
699 | 243 | temporary output repository | ||
700 | 244 | :param PatchState patch_state: passed through to get_existing_import_tags | ||
701 | 245 | :param repo_builder.Repo input_repo: input repository data | ||
702 | 246 | :param list(str) expected: the names of the references that are expected to | ||
703 | 247 | be returned, in order. | ||
704 | 248 | """ | ||
705 | 218 | input_repo.write(repo.raw_repo) | 249 | input_repo.write(repo.raw_repo) |
706 | 219 | 250 | ||
707 | 220 | assert [ | 251 | assert [ |
708 | 221 | ref.name for ref in | 252 | ref.name for ref in |
711 | 222 | target.get_existing_import_tags( | 253 | target.get_existing_import_tags(repo, '1-1', 'importer', patch_state) |
712 | 223 | repo, | 254 | ] == expected |
713 | 255 | |||
714 | 256 | |||
715 | 257 | def test_get_existing_import_tags_ordering(repo): | ||
716 | 258 | """Test that get_existing_import_tags returns results in the correct order | ||
717 | 259 | |||
718 | 260 | To maintain hash stability, the spec defines that multiple changelog | ||
719 | 261 | parents must appear in the order that they were published. For this to | ||
720 | 262 | work, get_existing_import_tags must return the tags in the correct order | ||
721 | 263 | even if the underlying git repository tags appear in an arbitrary order. | ||
722 | 264 | |||
723 | 265 | :param GitUbuntuRepository repo: fixture of a temporary repository to use | ||
724 | 266 | """ | ||
725 | 267 | |||
726 | 268 | # Construct a synthetic git repository containing tags | ||
727 | 269 | repo_builder.Repo( | ||
728 | 270 | tags={ | ||
729 | 271 | 'importer/import/1-1': repo_builder.Commit(), | ||
730 | 272 | 'importer/reimport/import/1-1/0': repo_builder.Commit(), | ||
731 | 273 | 'importer/reimport/import/1-1/1': repo_builder.Commit(), | ||
732 | 274 | } | ||
733 | 275 | ).write(repo.raw_repo) | ||
734 | 276 | |||
735 | 277 | mock_get_all_reimport_tags_patch = patch.object( | ||
736 | 278 | repo, | ||
737 | 279 | 'get_all_reimport_tags', | ||
738 | 280 | autospec=True, | ||
739 | 281 | ) | ||
740 | 282 | with mock_get_all_reimport_tags_patch as mock_get_all_reimport_tags: | ||
741 | 283 | # Intentionally arrange for repo.get_all_reimport_tags to return the | ||
742 | 284 | # expected result but in reverse order | ||
743 | 285 | mock_get_all_reimport_tags.return_value = [ | ||
744 | 286 | repo.raw_repo.lookup_reference('refs/tags/%s' % name) | ||
745 | 287 | for name in [ | ||
746 | 288 | 'importer/reimport/import/1-1/1', | ||
747 | 289 | 'importer/reimport/import/1-1/0', | ||
748 | 290 | ] | ||
749 | 291 | ] | ||
750 | 292 | |||
751 | 293 | # Call function under test | ||
752 | 294 | tags = target.get_existing_import_tags(repo, '1-1', 'importer') | ||
753 | 295 | |||
754 | 296 | # Check that our mock was called as expected | ||
755 | 297 | mock_get_all_reimport_tags.assert_called_once_with( | ||
756 | 224 | '1-1', | 298 | '1-1', |
757 | 225 | 'importer', | 299 | 'importer', |
759 | 226 | PatchState.APPLIED, | 300 | PatchState.UNAPPLIED, |
760 | 227 | ) | 301 | ) |
762 | 228 | ] == expected | 302 | |
763 | 303 | # Result tags should be in numeric order | ||
764 | 304 | assert [ref.name for ref in tags] == [ | ||
765 | 305 | 'refs/tags/importer/reimport/import/1-1/0', | ||
766 | 306 | 'refs/tags/importer/reimport/import/1-1/1', | ||
767 | 307 | ] | ||
768 | 229 | 308 | ||
769 | 230 | 309 | ||
770 | 231 | @pytest.mark.parametrize( | 310 | @pytest.mark.parametrize( |
771 | @@ -442,16 +521,16 @@ def test_create_applied_tag( | |||
772 | 442 | 'input_repo', | 521 | 'input_repo', |
773 | 443 | 'parent_overrides', | 522 | 'parent_overrides', |
774 | 444 | 'changelog_versions', | 523 | 'changelog_versions', |
777 | 445 | 'patches_applied', | 524 | 'patch_state', |
778 | 446 | 'expected_ref', | 525 | 'expected_refs', |
779 | 447 | ], | 526 | ], |
780 | 448 | [ | 527 | [ |
781 | 449 | ( | 528 | ( |
782 | 450 | repo_builder.Repo(), | 529 | repo_builder.Repo(), |
783 | 451 | {}, | 530 | {}, |
784 | 452 | ['1-2', '1-1',], | 531 | ['1-2', '1-1',], |
787 | 453 | False, | 532 | PatchState.UNAPPLIED, |
788 | 454 | None, | 533 | [], |
789 | 455 | ), | 534 | ), |
790 | 456 | ( | 535 | ( |
791 | 457 | repo_builder.Repo( | 536 | repo_builder.Repo( |
792 | @@ -460,8 +539,28 @@ def test_create_applied_tag( | |||
793 | 460 | ), | 539 | ), |
794 | 461 | {}, | 540 | {}, |
795 | 462 | ['1-2', '1-1'], | 541 | ['1-2', '1-1'], |
798 | 463 | False, | 542 | PatchState.UNAPPLIED, |
799 | 464 | 'refs/tags/importer/import/1-1', | 543 | ['refs/tags/importer/import/1-1'], |
800 | 544 | ), | ||
801 | 545 | ( | ||
802 | 546 | repo_builder.Repo( | ||
803 | 547 | commits=[ | ||
804 | 548 | repo_builder.Commit.from_spec(name='import'), | ||
805 | 549 | repo_builder.Commit.from_spec(name='reimport', mutate=1), | ||
806 | 550 | ], | ||
807 | 551 | tags={ | ||
808 | 552 | 'importer/import/1-1': Placeholder('import'), | ||
809 | 553 | 'importer/reimport/import/1-1/0': Placeholder('import'), | ||
810 | 554 | 'importer/reimport/import/1-1/1': Placeholder('reimport'), | ||
811 | 555 | }, | ||
812 | 556 | ), | ||
813 | 557 | {}, | ||
814 | 558 | ['1-2', '1-1'], | ||
815 | 559 | PatchState.UNAPPLIED, | ||
816 | 560 | [ | ||
817 | 561 | 'refs/tags/importer/reimport/import/1-1/0', | ||
818 | 562 | 'refs/tags/importer/reimport/import/1-1/1', | ||
819 | 563 | ], | ||
820 | 465 | ), | 564 | ), |
821 | 466 | ( | 565 | ( |
822 | 467 | repo_builder.Repo( | 566 | repo_builder.Repo( |
823 | @@ -470,15 +569,15 @@ def test_create_applied_tag( | |||
824 | 470 | ), | 569 | ), |
825 | 471 | {}, | 570 | {}, |
826 | 472 | ['1-3', '1-2', '1-1'], | 571 | ['1-3', '1-2', '1-1'], |
829 | 473 | False, | 572 | PatchState.UNAPPLIED, |
830 | 474 | 'refs/tags/importer/import/1-1', | 573 | ['refs/tags/importer/import/1-1'], |
831 | 475 | ), | 574 | ), |
832 | 476 | ( | 575 | ( |
833 | 477 | repo_builder.Repo(), | 576 | repo_builder.Repo(), |
834 | 478 | {}, | 577 | {}, |
835 | 479 | ['1-2', '1-1',], | 578 | ['1-2', '1-1',], |
838 | 480 | True, | 579 | PatchState.APPLIED, |
839 | 481 | None, | 580 | [], |
840 | 482 | ), | 581 | ), |
841 | 483 | ( | 582 | ( |
842 | 484 | repo_builder.Repo( | 583 | repo_builder.Repo( |
843 | @@ -487,8 +586,28 @@ def test_create_applied_tag( | |||
844 | 487 | ), | 586 | ), |
845 | 488 | {}, | 587 | {}, |
846 | 489 | ['1-2', '1-1'], | 588 | ['1-2', '1-1'], |
849 | 490 | True, | 589 | PatchState.APPLIED, |
850 | 491 | 'refs/tags/importer/applied/1-1', | 590 | ['refs/tags/importer/applied/1-1'], |
851 | 591 | ), | ||
852 | 592 | ( | ||
853 | 593 | repo_builder.Repo( | ||
854 | 594 | commits=[ | ||
855 | 595 | repo_builder.Commit.from_spec(name='import'), | ||
856 | 596 | repo_builder.Commit.from_spec(name='reimport', mutate=1), | ||
857 | 597 | ], | ||
858 | 598 | tags={ | ||
859 | 599 | 'importer/applied/1-1': Placeholder('import'), | ||
860 | 600 | 'importer/reimport/applied/1-1/0': Placeholder('import'), | ||
861 | 601 | 'importer/reimport/applied/1-1/1': Placeholder('reimport'), | ||
862 | 602 | }, | ||
863 | 603 | ), | ||
864 | 604 | {}, | ||
865 | 605 | ['1-2', '1-1'], | ||
866 | 606 | PatchState.APPLIED, | ||
867 | 607 | [ | ||
868 | 608 | 'refs/tags/importer/reimport/applied/1-1/0', | ||
869 | 609 | 'refs/tags/importer/reimport/applied/1-1/1', | ||
870 | 610 | ], | ||
871 | 492 | ), | 611 | ), |
872 | 493 | ( | 612 | ( |
873 | 494 | repo_builder.Repo( | 613 | repo_builder.Repo( |
874 | @@ -497,30 +616,51 @@ def test_create_applied_tag( | |||
875 | 497 | ), | 616 | ), |
876 | 498 | {}, | 617 | {}, |
877 | 499 | ['1-3', '1-2', '1-1'], | 618 | ['1-3', '1-2', '1-1'], |
880 | 500 | True, | 619 | PatchState.APPLIED, |
881 | 501 | 'refs/tags/importer/applied/1-1', | 620 | ['refs/tags/importer/applied/1-1'], |
882 | 502 | ), | 621 | ), |
883 | 503 | ], | 622 | ], |
884 | 504 | ) | 623 | ) |
886 | 505 | def test_get_changelog_parent_commit( | 624 | def test_get_changelog_parent_commits( |
887 | 506 | repo, | 625 | repo, |
888 | 507 | input_repo, | 626 | input_repo, |
889 | 508 | parent_overrides, | 627 | parent_overrides, |
890 | 509 | changelog_versions, | 628 | changelog_versions, |
893 | 510 | patches_applied, | 629 | patch_state, |
894 | 511 | expected_ref, | 630 | expected_refs, |
895 | 512 | ): | 631 | ): |
896 | 632 | """Test that get_changelog_parent_commits is generally correct | ||
897 | 633 | |||
898 | 634 | This is the general parameterised test for the common case uses of | ||
899 | 635 | target.get_changelog_parent_commits. | ||
900 | 636 | |||
901 | 637 | :param GitUbuntuRepository repo: fixture providing a temporary | ||
902 | 638 | GitUbuntuRepository instance to use | ||
903 | 639 | :param repo_builder.Repo input_repo: the input repository data to use that | ||
904 | 640 | will be populated into @repo before @repo is passed through to | ||
905 | 641 | get_changelog_parent_commits | ||
906 | 642 | :param dict parent_overrides: passed through to | ||
907 | 643 | get_changelog_parent_commits. | ||
908 | 644 | :param PatchState patch_state: passed through to | ||
909 | 645 | get_changelog_parent_commits | ||
910 | 646 | :param list(str) expected_refs: the expected return value of | ||
911 | 647 | get_changelog_parent_commits expressed using a list of reference names. | ||
912 | 648 | Since get_changelog_parent_commits returns a list of commit hash | ||
913 | 649 | strings, the reference names will need to be dereferenced before | ||
914 | 650 | comparison; this way the test parameters don't need to be opaque hash | ||
915 | 651 | strings. | ||
916 | 652 | """ | ||
917 | 513 | input_repo.write(repo.raw_repo) | 653 | input_repo.write(repo.raw_repo) |
919 | 514 | assert target.get_changelog_parent_commit( | 654 | assert target.get_changelog_parent_commits( |
920 | 515 | repo, | 655 | repo, |
921 | 516 | 'importer', | 656 | 'importer', |
922 | 517 | parent_overrides, | 657 | parent_overrides, |
923 | 518 | changelog_versions, | 658 | changelog_versions, |
926 | 519 | patches_applied, | 659 | patch_state, |
927 | 520 | ) == ( | 660 | ) == ([ |
928 | 521 | str(repo.raw_repo.lookup_reference(expected_ref).peel(pygit2.Commit).id) | 661 | str(repo.raw_repo.lookup_reference(expected_ref).peel(pygit2.Commit).id) |
931 | 522 | if expected_ref else expected_ref | 662 | for expected_ref in expected_refs |
932 | 523 | ) | 663 | ]) |
933 | 524 | 664 | ||
934 | 525 | @patch('gitubuntu.git_repository.GitUbuntuRepository.add_base_remotes') | 665 | @patch('gitubuntu.git_repository.GitUbuntuRepository.add_base_remotes') |
935 | 526 | def test_importer_main_cleanup_on_exception(add_base_remotes_mock): | 666 | def test_importer_main_cleanup_on_exception(add_base_remotes_mock): |
936 | @@ -703,6 +843,19 @@ def test_import_unapplied_spi_quilt_patches( | |||
937 | 703 | ], | 843 | ], |
938 | 704 | [ | 844 | [ |
939 | 705 | pytest.param( | 845 | pytest.param( |
940 | 846 | repo_builder.Repo(), | ||
941 | 847 | ['1-1'], | ||
942 | 848 | { | ||
943 | 849 | 'add_commits': [ | ||
944 | 850 | repo_builder.Commit.from_spec(name='publish'), | ||
945 | 851 | ], | ||
946 | 852 | 'update_tags': {'importer/import/1-1': Placeholder('publish')}, | ||
947 | 853 | }, | ||
948 | 854 | [ | ||
949 | 855 | 'refs/tags/importer/import/1-1', | ||
950 | 856 | ] | ||
951 | 857 | ), | ||
952 | 858 | pytest.param( | ||
953 | 706 | repo_builder.Repo( | 859 | repo_builder.Repo( |
954 | 707 | commits=[repo_builder.Commit.from_spec(name='import')], | 860 | commits=[repo_builder.Commit.from_spec(name='import')], |
955 | 708 | tags={'importer/import/1-1': Placeholder('import')}, | 861 | tags={'importer/import/1-1': Placeholder('import')}, |
956 | @@ -744,7 +897,7 @@ def test_import_unapplied_spi_quilt_patches( | |||
957 | 744 | 'refs/tags/importer/import/1-3', | 897 | 'refs/tags/importer/import/1-3', |
958 | 745 | ], | 898 | ], |
959 | 746 | ), | 899 | ), |
961 | 747 | pytest.param( | 900 | ( |
962 | 748 | repo_builder.Repo( | 901 | repo_builder.Repo( |
963 | 749 | commits=[ | 902 | commits=[ |
964 | 750 | repo_builder.Commit.from_spec(name='import'), | 903 | repo_builder.Commit.from_spec(name='import'), |
965 | @@ -779,7 +932,6 @@ def test_import_unapplied_spi_quilt_patches( | |||
966 | 779 | 'refs/tags/importer/reimport/import/1-1/1', | 932 | 'refs/tags/importer/reimport/import/1-1/1', |
967 | 780 | 'refs/tags/importer/import/1-2', | 933 | 'refs/tags/importer/import/1-2', |
968 | 781 | ], | 934 | ], |
969 | 782 | marks=pytest.mark.xfail(reason='LP: #1761332'), | ||
970 | 783 | ), | 935 | ), |
971 | 784 | ] | 936 | ] |
972 | 785 | ) | 937 | ) |
FAILED: Continuous integration, rev:969c7def726 6a904c1a306d743 503a7083563f5f /jenkins. ubuntu. com/server/ job/git- ubuntu- ci/469/
https:/
Executed test runs:
SUCCESS: VM Setup
SUCCESS: Build
FAILED: Unit Tests
Click here to trigger a rebuild: /jenkins. ubuntu. com/server/ job/git- ubuntu- ci/469/ /rebuild
https:/