Merge ~cloud-images-release-managers/cloud-images/+git/mfdiff:features/snap-diffs into ~cloud-images-release-managers/cloud-images/+git/mfdiff:master
- Git
- lp:~cloud-images-release-managers/cloud-images/+git/mfdiff
- features/snap-diffs
- Merge into master
Status: | Merged |
---|---|
Merged at revision: | da2d5005aca2a41d392de2c788a69cfc2765ab83 |
Proposed branch: | ~cloud-images-release-managers/cloud-images/+git/mfdiff:features/snap-diffs |
Merge into: | ~cloud-images-release-managers/cloud-images/+git/mfdiff:master |
Diff against target: |
654 lines (+268/-136) 6 files modified
test/test_manifest.py (+18/-15) test/test_manifestdiff.py (+127/-46) test/util.py (+12/-6) ubuntu/cloudimage/mfdiff/cli.py (+15/-7) ubuntu/cloudimage/mfdiff/manifest.py (+11/-20) ubuntu/cloudimage/mfdiff/manifestdiff.py (+85/-42) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Philip Roche | Approve | ||
Dan Watkins (community) | Approve | ||
Review via email: mp+361239@code.launchpad.net |
Commit message
diff snaps
Description of the change
The output of the command looks like this now (shortened for readability):
new: {}
removed: {'python3-pam': '0.4.2-
changed: ['dash', 'python3-twisted', 'python3-
new snaps: {'test-snap': ['stable', '1']}
removed snaps: {'lxd': ['stable/
changed snaps: ['core']
==== dash: 0.5.10.2-2 => 0.5.10.2-3ubuntu1 ====
==== dash
* preinst is removed, thus divertion is not setup upon
...
==== twisted: 18.7.0-2 => 18.9.0-3 ====
==== python3-twisted python3-
* Don't fix package substvars in binary-arch:, they did not depend on hamcrest
...
Dan Watkins (oddbloke) wrote : | # |
Dan Watkins (oddbloke) wrote : | # |
Other than the naming issue above, this looks really good. (FAOD, I'm not asking you to change every reference to debs as packages; just to modify the names that are introduced/modified in this MP.)
Tobias Koch (tobijk) wrote : | # |
@daniel-thewatkins, ok like this?
Preview Diff
1 | diff --git a/test/test_manifest.py b/test/test_manifest.py | |||
2 | index 29ab614..f3d38a7 100644 | |||
3 | --- a/test/test_manifest.py | |||
4 | +++ b/test/test_manifest.py | |||
5 | @@ -9,34 +9,37 @@ class TestManifest(object): | |||
6 | 9 | manifest_file.write('') | 9 | manifest_file.write('') |
7 | 10 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') | 10 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') |
8 | 11 | assert len(manifest) == 0 | 11 | assert len(manifest) == 0 |
10 | 12 | assert manifest.dict == {} | 12 | assert manifest.debs == {} |
11 | 13 | 13 | ||
14 | 14 | def test_single_package(self, tmpdir): | 14 | def test_single_deb(self, tmpdir): |
15 | 15 | package_name, package_version = 'package_name', '1.0-0ubuntu1' | 15 | deb_name, deb_version = 'deb_name', '1.0-0ubuntu1' |
16 | 16 | manifest_file = tmpdir.join('manifest') | 16 | manifest_file = tmpdir.join('manifest') |
18 | 17 | manifest_file.write(deb_package_line(package_name, package_version)) | 17 | manifest_file.write(deb_package_line(deb_name, deb_version)) |
19 | 18 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') | 18 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') |
20 | 19 | assert len(manifest) == 1 | 19 | assert len(manifest) == 1 |
22 | 20 | assert manifest.dict == { package_name: package_version } | 20 | assert manifest.debs == { deb_name: deb_version } |
23 | 21 | 21 | ||
26 | 22 | def test_snaps_are_skipped(self, tmpdir): | 22 | def test_single_snap(self, tmpdir): |
27 | 23 | package_name, package_version = 'package_name', '1.0-0ubuntu1' | 23 | snap_name, snap_channel, snap_version = ('snap_name', 'snap_channel', |
28 | 24 | 'snap_version') | ||
29 | 24 | manifest_file = tmpdir.join('manifest') | 25 | manifest_file = tmpdir.join('manifest') |
30 | 25 | manifest_file.write('\n'.join([ | 26 | manifest_file.write('\n'.join([ |
31 | 26 | deb_package_line(package_name, package_version), | ||
32 | 27 | snap_package_line('snap_name', 'snap_channel', 'snap_version') | 27 | snap_package_line('snap_name', 'snap_channel', 'snap_version') |
33 | 28 | ])) | 28 | ])) |
34 | 29 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') | 29 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') |
35 | 30 | assert len(manifest) == 1 | 30 | assert len(manifest) == 1 |
37 | 31 | assert manifest.dict == { package_name: package_version } | 31 | assert manifest.snaps == { snap_name: [snap_channel, snap_version]} |
38 | 32 | 32 | ||
41 | 33 | def test_deb_packages_starting_with_snap_arent_skipped(self, tmpdir): | 33 | def test_deb_and_snap(self, tmpdir): |
42 | 34 | package_name, package_version = 'snapd', '1.0-0ubuntu1' | 34 | deb_name, deb_version = 'snapd', '1.0-0ubuntu1' |
43 | 35 | snap_name, snap_channel, snap_version = ('snap_name', 'snap_channel', | ||
44 | 36 | 'snap_version') | ||
45 | 35 | manifest_file = tmpdir.join('manifest') | 37 | manifest_file = tmpdir.join('manifest') |
46 | 36 | manifest_file.write('\n'.join([ | 38 | manifest_file.write('\n'.join([ |
49 | 37 | deb_package_line(package_name, package_version), | 39 | deb_package_line(deb_name, deb_version), |
50 | 38 | snap_package_line('snap_name', 'snap_channel', 'snap_version') | 40 | snap_package_line(snap_name, snap_channel, snap_version) |
51 | 39 | ])) | 41 | ])) |
52 | 40 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') | 42 | manifest = Manifest(str(manifest_file), 'bionic', 'amd64') |
55 | 41 | assert len(manifest) == 1 | 43 | assert len(manifest) == 2 |
56 | 42 | assert manifest.dict == { package_name: package_version } | 44 | assert manifest.debs == { deb_name: deb_version } |
57 | 45 | assert manifest.snaps == { snap_name: [snap_channel, snap_version]} | ||
58 | diff --git a/test/test_manifestdiff.py b/test/test_manifestdiff.py | |||
59 | index 3d33731..c391f17 100644 | |||
60 | --- a/test/test_manifestdiff.py | |||
61 | +++ b/test/test_manifestdiff.py | |||
62 | @@ -5,11 +5,11 @@ from .util import deb_package_line, snap_package_line, write_manifest_file | |||
63 | 5 | class TestManifestDiff(object): | 5 | class TestManifestDiff(object): |
64 | 6 | 6 | ||
65 | 7 | def test_incompatible_manifest_raise_error(self, tmpdir): | 7 | def test_incompatible_manifest_raise_error(self, tmpdir): |
67 | 8 | package_name, package_version = 'package', '1.0-0ubuntu1' | 8 | deb_name, deb_version = 'package', '1.0-0ubuntu1' |
68 | 9 | manifest_file1 = tmpdir.join('manifest1') | 9 | manifest_file1 = tmpdir.join('manifest1') |
69 | 10 | manifest_file2 = tmpdir.join('manifest2') | 10 | manifest_file2 = tmpdir.join('manifest2') |
72 | 11 | manifest_file1.write(deb_package_line(package_name, package_version)) | 11 | manifest_file1.write(deb_package_line(deb_name, deb_version)) |
73 | 12 | manifest_file2.write(deb_package_line(package_name, package_version)) | 12 | manifest_file2.write(deb_package_line(deb_name, deb_version)) |
74 | 13 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | 13 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') |
75 | 14 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'arm64') | 14 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'arm64') |
76 | 15 | 15 | ||
77 | @@ -21,57 +21,57 @@ class TestManifestDiff(object): | |||
78 | 21 | 21 | ||
79 | 22 | assert incompatible == True | 22 | assert incompatible == True |
80 | 23 | 23 | ||
83 | 24 | def test_find_added_packages(self, tmpdir): | 24 | def test_find_added_debs(self, tmpdir): |
84 | 25 | package_list = [ | 25 | deb_list = [ |
85 | 26 | ('package1', '1.0-1'), | 26 | ('package1', '1.0-1'), |
86 | 27 | ('package2', '0.9.1-0ubuntu1'), | 27 | ('package2', '0.9.1-0ubuntu1'), |
87 | 28 | ] | 28 | ] |
89 | 29 | additional_packages = [ | 29 | additional_debs = [ |
90 | 30 | ('package3', '0.8a~tp1-1ubuntu1'), | 30 | ('package3', '0.8a~tp1-1ubuntu1'), |
91 | 31 | ] | 31 | ] |
92 | 32 | 32 | ||
93 | 33 | manifest_file1 = tmpdir.join('manifest1') | 33 | manifest_file1 = tmpdir.join('manifest1') |
94 | 34 | manifest_file2 = tmpdir.join('manifest2') | 34 | manifest_file2 = tmpdir.join('manifest2') |
98 | 35 | write_manifest_file(manifest_file1, package_list) | 35 | write_manifest_file(manifest_file1, debs=deb_list) |
99 | 36 | write_manifest_file(manifest_file2, package_list | 36 | write_manifest_file(manifest_file2, debs=deb_list |
100 | 37 | + additional_packages) | 37 | + additional_debs) |
101 | 38 | 38 | ||
102 | 39 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | 39 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') |
103 | 40 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | 40 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') |
104 | 41 | 41 | ||
105 | 42 | diff = ManifestDiff(manifest1, manifest2) | 42 | diff = ManifestDiff(manifest1, manifest2) |
108 | 43 | added_packages = diff.get_added() | 43 | added_debs = diff.get_added_debs() |
109 | 44 | assert added_packages == dict(additional_packages) | 44 | assert added_debs == dict(additional_debs) |
110 | 45 | 45 | ||
113 | 46 | def test_find_removed_packages(self, tmpdir): | 46 | def test_find_removed_debs(self, tmpdir): |
114 | 47 | package_list = [ | 47 | deb_list = [ |
115 | 48 | ('package1', '1.0-1'), | 48 | ('package1', '1.0-1'), |
116 | 49 | ('package2', '0.9.1-0ubuntu1') | 49 | ('package2', '0.9.1-0ubuntu1') |
117 | 50 | ] | 50 | ] |
119 | 51 | additional_packages = [ | 51 | additional_debs = [ |
120 | 52 | ('package3', '0.8a~tp1-1ubuntu1') | 52 | ('package3', '0.8a~tp1-1ubuntu1') |
121 | 53 | ] | 53 | ] |
122 | 54 | 54 | ||
123 | 55 | manifest_file1 = tmpdir.join('manifest1') | 55 | manifest_file1 = tmpdir.join('manifest1') |
124 | 56 | manifest_file2 = tmpdir.join('manifest2') | 56 | manifest_file2 = tmpdir.join('manifest2') |
128 | 57 | write_manifest_file(manifest_file1, package_list | 57 | write_manifest_file(manifest_file1, debs=deb_list |
129 | 58 | + additional_packages) | 58 | + additional_debs) |
130 | 59 | write_manifest_file(manifest_file2, package_list) | 59 | write_manifest_file(manifest_file2, debs=deb_list) |
131 | 60 | 60 | ||
132 | 61 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | 61 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') |
133 | 62 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | 62 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') |
134 | 63 | 63 | ||
135 | 64 | diff = ManifestDiff(manifest1, manifest2) | 64 | diff = ManifestDiff(manifest1, manifest2) |
138 | 65 | removed_packages = diff.get_removed() | 65 | removed_debs = diff.get_removed_debs() |
139 | 66 | assert removed_packages == dict(additional_packages) | 66 | assert removed_debs == dict(additional_debs) |
140 | 67 | 67 | ||
143 | 68 | def test_find_changed_packages(self, tmpdir): | 68 | def test_find_changed_debs(self, tmpdir): |
144 | 69 | package_list1 = [ | 69 | deb_list1 = [ |
145 | 70 | ('package1', '1.0-1'), | 70 | ('package1', '1.0-1'), |
146 | 71 | ('package2', '0.9.1-0ubuntu1'), | 71 | ('package2', '0.9.1-0ubuntu1'), |
147 | 72 | ('package3', '2.0'), | 72 | ('package3', '2.0'), |
148 | 73 | ] | 73 | ] |
150 | 74 | package_list2 = [ | 74 | deb_list2 = [ |
151 | 75 | ('package1', '1.0-1'), | 75 | ('package1', '1.0-1'), |
152 | 76 | ('package2', '0.10.1-0ubuntu1'), | 76 | ('package2', '0.10.1-0ubuntu1'), |
153 | 77 | ('package3', '2.0'), | 77 | ('package3', '2.0'), |
154 | @@ -79,17 +79,61 @@ class TestManifestDiff(object): | |||
155 | 79 | 79 | ||
156 | 80 | manifest_file1 = tmpdir.join('manifest1') | 80 | manifest_file1 = tmpdir.join('manifest1') |
157 | 81 | manifest_file2 = tmpdir.join('manifest2') | 81 | manifest_file2 = tmpdir.join('manifest2') |
160 | 82 | write_manifest_file(manifest_file1, package_list1) | 82 | write_manifest_file(manifest_file1, debs=deb_list1) |
161 | 83 | write_manifest_file(manifest_file2, package_list2) | 83 | write_manifest_file(manifest_file2, debs=deb_list2) |
162 | 84 | 84 | ||
163 | 85 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | 85 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') |
164 | 86 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | 86 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') |
165 | 87 | diff = ManifestDiff(manifest1, manifest2) | 87 | diff = ManifestDiff(manifest1, manifest2) |
168 | 88 | changed_packages = diff.get_changed() | 88 | changed_debs = diff.get_changed_debs() |
169 | 89 | assert changed_packages == ['package2'] | 89 | assert changed_debs == ['package2'] |
170 | 90 | |||
171 | 91 | def test_find_added_snaps(self, tmpdir): | ||
172 | 92 | snap_list = [ | ||
173 | 93 | ('snap1', ['stable', '1.0-1']), | ||
174 | 94 | ('snap2', ['edge', '0.9.1-0ubuntu1']), | ||
175 | 95 | ] | ||
176 | 96 | additional_snaps = [ | ||
177 | 97 | ('snap3', ['stable/ubuntu-18.04', '0.8a~tp1-1ubuntu1']), | ||
178 | 98 | ] | ||
179 | 99 | |||
180 | 100 | manifest_file1 = tmpdir.join('manifest1') | ||
181 | 101 | manifest_file2 = tmpdir.join('manifest2') | ||
182 | 102 | write_manifest_file(manifest_file1, snaps=snap_list) | ||
183 | 103 | write_manifest_file(manifest_file2, snaps=snap_list | ||
184 | 104 | + additional_snaps) | ||
185 | 105 | |||
186 | 106 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | ||
187 | 107 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | ||
188 | 108 | |||
189 | 109 | diff = ManifestDiff(manifest1, manifest2) | ||
190 | 110 | added_snaps = diff.get_added_snaps() | ||
191 | 111 | assert added_snaps == dict(additional_snaps) | ||
192 | 112 | |||
193 | 113 | def test_find_removed_snaps(self, tmpdir): | ||
194 | 114 | snap_list = [ | ||
195 | 115 | ('snap1', ['stable', '1.0-1']), | ||
196 | 116 | ('snap2', ['edge', '0.9.1-0ubuntu1']) | ||
197 | 117 | ] | ||
198 | 118 | additional_snaps = [ | ||
199 | 119 | ('package3', ['stable/ubuntu-18.04', '0.8a~tp1-1ubuntu1']) | ||
200 | 120 | ] | ||
201 | 121 | |||
202 | 122 | manifest_file1 = tmpdir.join('manifest1') | ||
203 | 123 | manifest_file2 = tmpdir.join('manifest2') | ||
204 | 124 | write_manifest_file(manifest_file1, snaps=snap_list | ||
205 | 125 | + additional_snaps) | ||
206 | 126 | write_manifest_file(manifest_file2, snaps=snap_list) | ||
207 | 127 | |||
208 | 128 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | ||
209 | 129 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | ||
210 | 130 | |||
211 | 131 | diff = ManifestDiff(manifest1, manifest2) | ||
212 | 132 | removed_snaps = diff.get_removed_snaps() | ||
213 | 133 | assert removed_snaps == dict(additional_snaps) | ||
214 | 90 | 134 | ||
215 | 91 | def test_find_added_removed_changed(self, tmpdir): | 135 | def test_find_added_removed_changed(self, tmpdir): |
217 | 92 | package_list1 = [ | 136 | deb_list1 = [ |
218 | 93 | ('package1', '1.0'), | 137 | ('package1', '1.0'), |
219 | 94 | ('package4', '1.0'), | 138 | ('package4', '1.0'), |
220 | 95 | ('package5', '1.0'), | 139 | ('package5', '1.0'), |
221 | @@ -99,7 +143,7 @@ class TestManifestDiff(object): | |||
222 | 99 | ('package9', '1.0'), | 143 | ('package9', '1.0'), |
223 | 100 | ('package10', '1.0') | 144 | ('package10', '1.0') |
224 | 101 | ] | 145 | ] |
226 | 102 | package_list2 = [ | 146 | deb_list2 = [ |
227 | 103 | ('package1', '1.0'), | 147 | ('package1', '1.0'), |
228 | 104 | ('package2', '1.0'), | 148 | ('package2', '1.0'), |
229 | 105 | ('package3', '1.0'), | 149 | ('package3', '1.0'), |
230 | @@ -110,40 +154,77 @@ class TestManifestDiff(object): | |||
231 | 110 | ('package10', '1.0') | 154 | ('package10', '1.0') |
232 | 111 | ] | 155 | ] |
233 | 112 | 156 | ||
234 | 157 | snap_list1 = [ | ||
235 | 158 | ('snap1', ['stable', '1.0']), | ||
236 | 159 | ('snap4', ['stable', '1.0']), | ||
237 | 160 | ('snap5', ['stable', '1.0']), | ||
238 | 161 | ('snap6', ['stable', '1.0']), | ||
239 | 162 | ('snap7', ['stable', '1.0']), | ||
240 | 163 | ('snap8', ['stable', '1.0']), | ||
241 | 164 | ('snap9', ['stable', '1.0']), | ||
242 | 165 | ('snap10', ['stable', '1.0']), | ||
243 | 166 | ] | ||
244 | 167 | snap_list2 = [ | ||
245 | 168 | ('snap1', ['stable', '1.0']), | ||
246 | 169 | ('snap2', ['stable', '1.0']), | ||
247 | 170 | ('snap3', ['stable', '1.0']), | ||
248 | 171 | ('snap4', ['stable', '2.0']), | ||
249 | 172 | ('snap5', ['edge', '1.0']), | ||
250 | 173 | ('snap6', ['stable', '1.0']), | ||
251 | 174 | ('snap9', ['stable', '1.0']), | ||
252 | 175 | ('snap10', ['stable', '1.0']), | ||
253 | 176 | ] | ||
254 | 177 | |||
255 | 113 | manifest_file1 = tmpdir.join('manifest1') | 178 | manifest_file1 = tmpdir.join('manifest1') |
256 | 114 | manifest_file2 = tmpdir.join('manifest2') | 179 | manifest_file2 = tmpdir.join('manifest2') |
259 | 115 | write_manifest_file(manifest_file1, package_list1) | 180 | write_manifest_file(manifest_file1, debs=deb_list1, |
260 | 116 | write_manifest_file(manifest_file2, package_list2) | 181 | snaps=snap_list1) |
261 | 182 | write_manifest_file(manifest_file2, debs=deb_list2, | ||
262 | 183 | snaps=snap_list2) | ||
263 | 117 | 184 | ||
264 | 118 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | 185 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') |
265 | 119 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | 186 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') |
266 | 120 | diff = ManifestDiff(manifest1, manifest2) | 187 | diff = ManifestDiff(manifest1, manifest2) |
267 | 121 | 188 | ||
271 | 122 | added_packages = diff.get_added() | 189 | added_debs = diff.get_added_debs() |
272 | 123 | removed_packages = diff.get_removed() | 190 | removed_debs = diff.get_removed_debs() |
273 | 124 | changed_packages = diff.get_changed() | 191 | changed_debs = diff.get_changed_debs() |
274 | 192 | |||
275 | 193 | assert added_debs == {'package2': '1.0', 'package3': '1.0'} | ||
276 | 194 | assert removed_debs == {'package7': '1.0', 'package8': '1.0'} | ||
277 | 195 | assert changed_debs == ['package4', 'package5'] | ||
278 | 196 | |||
279 | 197 | added_snaps = diff.get_added_snaps() | ||
280 | 198 | removed_snaps = diff.get_removed_snaps() | ||
281 | 199 | changed_snaps = diff.get_changed_snaps() | ||
282 | 125 | 200 | ||
286 | 126 | assert added_packages == {'package2': '1.0', 'package3': '1.0'} | 201 | assert added_snaps == { |
287 | 127 | assert removed_packages == {'package7': '1.0', 'package8': '1.0'} | 202 | 'snap2': ['stable', '1.0'], |
288 | 128 | assert changed_packages == ['package4', 'package5'] | 203 | 'snap3': ['stable', '1.0'] |
289 | 204 | } | ||
290 | 205 | assert removed_snaps == { | ||
291 | 206 | 'snap7': ['stable', '1.0'], | ||
292 | 207 | 'snap8': ['stable', '1.0'] | ||
293 | 208 | } | ||
294 | 209 | assert changed_snaps == ['snap4', 'snap5'] | ||
295 | 129 | 210 | ||
296 | 130 | def test_kernel_fixups(self, tmpdir): | 211 | def test_kernel_fixups(self, tmpdir): |
299 | 131 | package_list1 = [('linux-image-4.13.0-16-generic', '4.13.0-16.19')] | 212 | deb_list1 = [('linux-image-4.13.0-16-generic', '4.13.0-16.19')] |
300 | 132 | package_list2 = [('linux-image-4.13.0-25-generic', '4.13.0-25.29')] | 213 | deb_list2 = [('linux-image-4.13.0-25-generic', '4.13.0-25.29')] |
301 | 133 | 214 | ||
302 | 134 | manifest_file1 = tmpdir.join('manifest1') | 215 | manifest_file1 = tmpdir.join('manifest1') |
303 | 135 | manifest_file2 = tmpdir.join('manifest2') | 216 | manifest_file2 = tmpdir.join('manifest2') |
306 | 136 | write_manifest_file(manifest_file1, package_list1) | 217 | write_manifest_file(manifest_file1, debs=deb_list1) |
307 | 137 | write_manifest_file(manifest_file2, package_list2) | 218 | write_manifest_file(manifest_file2, debs=deb_list2) |
308 | 138 | 219 | ||
309 | 139 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') | 220 | manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64') |
310 | 140 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') | 221 | manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64') |
311 | 141 | diff = ManifestDiff(manifest1, manifest2) | 222 | diff = ManifestDiff(manifest1, manifest2) |
312 | 142 | 223 | ||
316 | 143 | added_packages = diff.get_added() | 224 | added_debs = diff.get_added_debs() |
317 | 144 | removed_packages = diff.get_removed() | 225 | removed_debs = diff.get_removed_debs() |
318 | 145 | changed_packages = diff.get_changed() | 226 | changed_debs = diff.get_changed_debs() |
319 | 146 | 227 | ||
323 | 147 | assert added_packages == {} | 228 | assert added_debs == {} |
324 | 148 | assert removed_packages == {} | 229 | assert removed_debs == {} |
325 | 149 | assert changed_packages == ['linux-image-4.13.0-25-generic'] | 230 | assert changed_debs == ['linux-image-4.13.0-25-generic'] |
326 | diff --git a/test/util.py b/test/util.py | |||
327 | index 9979a78..a39b7ec 100644 | |||
328 | --- a/test/util.py | |||
329 | +++ b/test/util.py | |||
330 | @@ -1,6 +1,6 @@ | |||
332 | 1 | def deb_package_line(package_name, package_version): | 1 | def deb_package_line(deb_name, deb_version): |
333 | 2 | """Format a deb package manifest line""" | 2 | """Format a deb package manifest line""" |
335 | 3 | return '\t'.join([package_name, package_version]) | 3 | return '\t'.join([deb_name, deb_version]) |
336 | 4 | 4 | ||
337 | 5 | 5 | ||
338 | 6 | def snap_package_line(snap_name, snap_channel, snap_version): | 6 | def snap_package_line(snap_name, snap_channel, snap_version): |
339 | @@ -8,14 +8,20 @@ def snap_package_line(snap_name, snap_channel, snap_version): | |||
340 | 8 | return '\t'.join( | 8 | return '\t'.join( |
341 | 9 | ['snap:{}'.format(snap_name), snap_channel, snap_version]) | 9 | ['snap:{}'.format(snap_name), snap_channel, snap_version]) |
342 | 10 | 10 | ||
344 | 11 | def write_manifest_file(path_obj, packages): | 11 | def write_manifest_file(path_obj, debs=None, snaps=None): |
345 | 12 | """Write a list of packages to a manifest file.""" | 12 | """Write a list of packages to a manifest file.""" |
346 | 13 | manifest_lines = [] | 13 | manifest_lines = [] |
347 | 14 | 14 | ||
348 | 15 | # Then add more to the second. | 15 | # Then add more to the second. |
352 | 16 | for package_name, package_version in packages: | 16 | if debs is not None: |
353 | 17 | manifest_lines.append(deb_package_line( | 17 | for deb_name, deb_version in debs: |
354 | 18 | package_name, package_version)) | 18 | manifest_lines.append(deb_package_line( |
355 | 19 | deb_name, deb_version)) | ||
356 | 20 | |||
357 | 21 | if snaps is not None: | ||
358 | 22 | for snap_name, (snap_channel, snap_version) in snaps: | ||
359 | 23 | manifest_lines.append(snap_package_line( | ||
360 | 24 | snap_name, snap_channel, snap_version)) | ||
361 | 19 | 25 | ||
362 | 20 | path_obj.write("\n".join(manifest_lines)) | 26 | path_obj.write("\n".join(manifest_lines)) |
363 | 21 | 27 | ||
364 | diff --git a/ubuntu/cloudimage/mfdiff/cli.py b/ubuntu/cloudimage/mfdiff/cli.py | |||
365 | index ba8d102..5cc0629 100644 | |||
366 | --- a/ubuntu/cloudimage/mfdiff/cli.py | |||
367 | +++ b/ubuntu/cloudimage/mfdiff/cli.py | |||
368 | @@ -128,14 +128,22 @@ def main(): | |||
369 | 128 | manifest_from = Manifest(manifest_from_filename, release, arch) | 128 | manifest_from = Manifest(manifest_from_filename, release, arch) |
370 | 129 | manifest_diff = ManifestDiff(manifest_from, manifest_to) | 129 | manifest_diff = ManifestDiff(manifest_from, manifest_to) |
371 | 130 | 130 | ||
375 | 131 | added_pkgs = manifest_diff.get_added() | 131 | added_debs = manifest_diff.get_added_debs() |
376 | 132 | removed_pkgs = manifest_diff.get_removed() | 132 | removed_debs = manifest_diff.get_removed_debs() |
377 | 133 | changed_pkgs = manifest_diff.get_changed() | 133 | changed_debs = manifest_diff.get_changed_debs() |
378 | 134 | 134 | ||
382 | 135 | print("new: %s" % added_pkgs) | 135 | added_snaps = manifest_diff.get_added_snaps() |
383 | 136 | print("removed: %s" % removed_pkgs) | 136 | removed_snaps = manifest_diff.get_removed_snaps() |
384 | 137 | print("changed: %s" % changed_pkgs) | 137 | changed_snaps = manifest_diff.get_changed_snaps() |
385 | 138 | |||
386 | 139 | print("new: %s" % added_debs) | ||
387 | 140 | print("removed: %s" % removed_debs) | ||
388 | 141 | print("changed: %s" % changed_debs) | ||
389 | 142 | |||
390 | 143 | print("new snaps: %s" % added_snaps) | ||
391 | 144 | print("removed snaps: %s" % removed_snaps) | ||
392 | 145 | print("changed snaps: %s" % changed_snaps) | ||
393 | 138 | 146 | ||
394 | 139 | # if modified packages, download all changelogs from changelogs. | 147 | # if modified packages, download all changelogs from changelogs. |
396 | 140 | if changed_pkgs: | 148 | if changed_debs: |
397 | 141 | print(manifest_diff.render_changelog()) | 149 | print(manifest_diff.render_changelog()) |
398 | diff --git a/ubuntu/cloudimage/mfdiff/manifest.py b/ubuntu/cloudimage/mfdiff/manifest.py | |||
399 | index 6907ad8..bd1f416 100644 | |||
400 | --- a/ubuntu/cloudimage/mfdiff/manifest.py | |||
401 | +++ b/ubuntu/cloudimage/mfdiff/manifest.py | |||
402 | @@ -27,23 +27,10 @@ class Manifest(object): | |||
403 | 27 | def __init__(self, filename, release, arch): | 27 | def __init__(self, filename, release, arch): |
404 | 28 | self.release = release | 28 | self.release = release |
405 | 29 | self.arch = arch | 29 | self.arch = arch |
420 | 30 | self.dict = self._manifest_to_dict(filename) | 30 | self.debs, self.snaps = self._manifest_to_dict(filename) |
407 | 31 | |||
408 | 32 | def __iter__(self): | ||
409 | 33 | for item in self.dict: | ||
410 | 34 | yield item | ||
411 | 35 | |||
412 | 36 | def __getitem__(self, key): | ||
413 | 37 | return self.dict[key] | ||
414 | 38 | |||
415 | 39 | def __setitem__(self, key, value): | ||
416 | 40 | self.dict[key] = value | ||
417 | 41 | |||
418 | 42 | def __delitem__(self, key): | ||
419 | 43 | del self.dict[key] | ||
421 | 44 | 31 | ||
422 | 45 | def __len__(self): | 32 | def __len__(self): |
424 | 46 | return len(self.dict) | 33 | return len(self.debs) + len(self.snaps) |
425 | 47 | 34 | ||
426 | 48 | @classmethod | 35 | @classmethod |
427 | 49 | def _manifest_to_dict(cls, filename): | 36 | def _manifest_to_dict(cls, filename): |
428 | @@ -54,12 +41,16 @@ class Manifest(object): | |||
429 | 54 | :return: List of package versions by name | 41 | :return: List of package versions by name |
430 | 55 | :rtype: dict | 42 | :rtype: dict |
431 | 56 | """ | 43 | """ |
433 | 57 | ret = {} | 44 | debs = {} |
434 | 45 | snaps = {} | ||
435 | 46 | |||
436 | 58 | logging.debug('Reading package manifest from %s', filename) | 47 | logging.debug('Reading package manifest from %s', filename) |
437 | 59 | with open(filename, "r") as manifest: | 48 | with open(filename, "r") as manifest: |
438 | 60 | for line in manifest: | 49 | for line in manifest: |
439 | 61 | if line.startswith("snap:"): | 50 | if line.startswith("snap:"): |
444 | 62 | continue | 51 | (name, channel, ver) = line[5:].split() |
445 | 63 | (pkg, ver) = line.split() | 52 | snaps[name] = [channel, ver] |
446 | 64 | ret[pkg] = ver | 53 | else: |
447 | 65 | return ret | 54 | (name, ver) = line.split() |
448 | 55 | debs[name] = ver | ||
449 | 56 | return debs, snaps | ||
450 | diff --git a/ubuntu/cloudimage/mfdiff/manifestdiff.py b/ubuntu/cloudimage/mfdiff/manifestdiff.py | |||
451 | index 20e7804..436e6fa 100644 | |||
452 | --- a/ubuntu/cloudimage/mfdiff/manifestdiff.py | |||
453 | +++ b/ubuntu/cloudimage/mfdiff/manifestdiff.py | |||
454 | @@ -64,9 +64,12 @@ class ManifestDiff(object): | |||
455 | 64 | 64 | ||
456 | 65 | self._manifest_from = manifest_from | 65 | self._manifest_from = manifest_from |
457 | 66 | self._manifest_to = manifest_to | 66 | self._manifest_to = manifest_to |
461 | 67 | self._added_pkgs = {} | 67 | self._added_debs = {} |
462 | 68 | self._removed_pkgs = {} | 68 | self._removed_debs = {} |
463 | 69 | self._changed_pkgs = [] | 69 | self._changed_debs = [] |
464 | 70 | self._added_snaps = {} | ||
465 | 71 | self._removed_snaps = {} | ||
466 | 72 | self._changed_snaps = [] | ||
467 | 70 | 73 | ||
468 | 71 | self._cache = ManifestCache(manifest_from.release, | 74 | self._cache = ManifestCache(manifest_from.release, |
469 | 72 | manifest_from.arch) | 75 | manifest_from.arch) |
470 | @@ -74,37 +77,59 @@ class ManifestDiff(object): | |||
471 | 74 | if apply_fixups: | 77 | if apply_fixups: |
472 | 75 | self.apply_kernel_fixups() | 78 | self.apply_kernel_fixups() |
473 | 76 | 79 | ||
475 | 77 | def get_added(self): | 80 | def get_added_debs(self): |
476 | 78 | "Find new packages in manifest_to" | 81 | "Find new packages in manifest_to" |
485 | 79 | if not self._added_pkgs: | 82 | if not self._added_debs: |
486 | 80 | for pkg in sorted(viewkeys(self._manifest_to.dict) - | 83 | self._added_debs = self._get_added_dict_items( |
487 | 81 | viewkeys(self._manifest_from.dict)): | 84 | self._manifest_from.debs, |
488 | 82 | logging.debug('New package: %s', pkg) | 85 | self._manifest_to.debs |
489 | 83 | self._added_pkgs[pkg] = self._manifest_to.dict[pkg] | 86 | ) |
490 | 84 | return self._added_pkgs | 87 | return self._added_debs |
491 | 85 | 88 | ||
492 | 86 | def get_removed(self): | 89 | def get_removed_debs(self): |
493 | 87 | "Find packages removed from manifest_from" | 90 | "Find packages removed from manifest_from" |
502 | 88 | if not self._removed_pkgs: | 91 | if not self._removed_debs: |
503 | 89 | for pkg in sorted(viewkeys(self._manifest_from.dict) - | 92 | self._removed_debs = self._get_removed_dict_items( |
504 | 90 | viewkeys(self._manifest_to.dict)): | 93 | self._manifest_from.debs, |
505 | 91 | logging.debug('Removed package: %s', pkg) | 94 | self._manifest_to.debs |
506 | 92 | self._removed_pkgs[pkg] = self._manifest_from[pkg] | 95 | ) |
507 | 93 | return self._removed_pkgs | 96 | return self._removed_debs |
508 | 94 | 97 | ||
509 | 95 | def get_changed(self): | 98 | def get_changed_debs(self): |
510 | 96 | "Find modified packages" | 99 | "Find modified packages" |
522 | 97 | if not self._changed_pkgs: | 100 | if not self._changed_debs: |
523 | 98 | changed = [] | 101 | self._changed_debs = self._get_changed_dict_items( |
524 | 99 | for pkg in sorted(viewkeys(self._manifest_from.dict) & | 102 | self._manifest_from.debs, |
525 | 100 | viewkeys(self._manifest_to.dict)): | 103 | self._manifest_to.debs |
526 | 101 | if self._manifest_from[pkg] != self._manifest_to[pkg]: | 104 | ) |
527 | 102 | logging.debug('Changed package: %s', pkg) | 105 | return self._changed_debs |
528 | 103 | changed.append(pkg) | 106 | |
529 | 104 | 107 | def get_added_snaps(self): | |
530 | 105 | self._changed_pkgs = changed | 108 | "Find new snaps in manifest_to" |
531 | 106 | 109 | if not self._added_snaps: | |
532 | 107 | return self._changed_pkgs | 110 | self._added_snaps = self._get_added_dict_items( |
533 | 111 | self._manifest_from.snaps, | ||
534 | 112 | self._manifest_to.snaps | ||
535 | 113 | ) | ||
536 | 114 | return self._added_snaps | ||
537 | 115 | |||
538 | 116 | def get_removed_snaps(self): | ||
539 | 117 | "Find snaps removed from manifest_from" | ||
540 | 118 | if not self._removed_snaps: | ||
541 | 119 | self._removed_snaps = self._get_removed_dict_items( | ||
542 | 120 | self._manifest_from.snaps, | ||
543 | 121 | self._manifest_to.snaps | ||
544 | 122 | ) | ||
545 | 123 | return self._removed_snaps | ||
546 | 124 | |||
547 | 125 | def get_changed_snaps(self): | ||
548 | 126 | "Find modified snaps" | ||
549 | 127 | if not self._changed_snaps: | ||
550 | 128 | self._changed_snaps = self._get_changed_dict_items( | ||
551 | 129 | self._manifest_from.snaps, | ||
552 | 130 | self._manifest_to.snaps | ||
553 | 131 | ) | ||
554 | 132 | return self._changed_snaps | ||
555 | 108 | 133 | ||
556 | 109 | def render_changelog(self): | 134 | def render_changelog(self): |
557 | 110 | """ | 135 | """ |
558 | @@ -114,7 +139,7 @@ class ManifestDiff(object): | |||
559 | 114 | 139 | ||
560 | 115 | srcs = {} | 140 | srcs = {} |
561 | 116 | errors = [] | 141 | errors = [] |
563 | 117 | src2bins = self._cache.get_src2bin_mapping(self._changed_pkgs) | 142 | src2bins = self._cache.get_src2bin_mapping(self._changed_debs) |
564 | 118 | 143 | ||
565 | 119 | # Generate changelog data per unique source package | 144 | # Generate changelog data per unique source package |
566 | 120 | for source_name in src2bins: | 145 | for source_name in src2bins: |
567 | @@ -127,19 +152,19 @@ class ManifestDiff(object): | |||
568 | 127 | # Find the source version data for the binary in manifest #2 | 152 | # Find the source version data for the binary in manifest #2 |
569 | 128 | try: | 153 | try: |
570 | 129 | src['version_to'] = self._cache.source_version_for_binary( | 154 | src['version_to'] = self._cache.source_version_for_binary( |
572 | 130 | binary_name, self._manifest_to[binary_name]) | 155 | binary_name, self._manifest_to.debs[binary_name]) |
573 | 131 | except UnknownSourceVersionError as excp: | 156 | except UnknownSourceVersionError as excp: |
574 | 132 | logging.error(str(excp)) | 157 | logging.error(str(excp)) |
575 | 133 | errors.append(excp) | 158 | errors.append(excp) |
576 | 134 | continue | 159 | continue |
577 | 135 | 160 | ||
578 | 136 | # Find the source version data for the binary in manifest #1 | 161 | # Find the source version data for the binary in manifest #1 |
580 | 137 | binver_from = self._manifest_from[binary_name] | 162 | binver_from = self._manifest_from.debs[binary_name] |
581 | 138 | try: | 163 | try: |
582 | 139 | src['version_from'] = self._cache.source_version_for_binary( | 164 | src['version_from'] = self._cache.source_version_for_binary( |
583 | 140 | binary_name, binver_from) | 165 | binary_name, binver_from) |
584 | 141 | except UnknownSourceVersionError as excp: | 166 | except UnknownSourceVersionError as excp: |
586 | 142 | if self._manifest_to[binary_name] == src['version_to']: | 167 | if self._manifest_to.debs[binary_name] == src['version_to']: |
587 | 143 | logging.info('Could not find source version data in apt ' | 168 | logging.info('Could not find source version data in apt ' |
588 | 144 | 'cache. Assuming source %s version %s from ' | 169 | 'cache. Assuming source %s version %s from ' |
589 | 145 | 'binary %s', source_name, binver_from, | 170 | 'binary %s', source_name, binver_from, |
590 | @@ -189,8 +214,8 @@ class ManifestDiff(object): | |||
591 | 189 | binlist = sorted(src2bins[source_name]) | 214 | binlist = sorted(src2bins[source_name]) |
592 | 190 | binary = binlist[0] | 215 | binary = binlist[0] |
593 | 191 | result.append("==== %s: %s => %s ====" % | 216 | result.append("==== %s: %s => %s ====" % |
596 | 192 | (source_name, self._manifest_from[binary], | 217 | (source_name, self._manifest_from.debs[binary], |
597 | 193 | self._manifest_to[binary])) | 218 | self._manifest_to.debs[binary])) |
598 | 194 | result.append("==== %s" % ' '.join(binlist)) | 219 | result.append("==== %s" % ' '.join(binlist)) |
599 | 195 | for block in srcs[source_name]["changeblocks"]: | 220 | for block in srcs[source_name]["changeblocks"]: |
600 | 196 | entry = '\n'.join([x for x in block.changes() if x]) | 221 | entry = '\n'.join([x for x in block.changes() if x]) |
601 | @@ -213,17 +238,17 @@ class ManifestDiff(object): | |||
602 | 213 | """ | 238 | """ |
603 | 214 | kfixups = {} | 239 | kfixups = {} |
604 | 215 | kmatch = re.compile("linux-image-[0-9]") | 240 | kmatch = re.compile("linux-image-[0-9]") |
606 | 216 | for pkg in self._manifest_to: | 241 | for pkg in self._manifest_to.debs: |
607 | 217 | # if this is a linux-image-* binary package do some hacks to make it | 242 | # if this is a linux-image-* binary package do some hacks to make it |
608 | 218 | # look like manifest_from is the same (format like | 243 | # look like manifest_from is the same (format like |
609 | 219 | # linux-image-2.6.32-32-virtual) | 244 | # linux-image-2.6.32-32-virtual) |
610 | 220 | if kmatch.match(pkg): | 245 | if kmatch.match(pkg): |
611 | 221 | logging.debug('Found kernel %s in manifest #2', pkg) | 246 | logging.debug('Found kernel %s in manifest #2', pkg) |
612 | 222 | img_type = pkg.split("-")[-1] | 247 | img_type = pkg.split("-")[-1] |
614 | 223 | if pkg in self._manifest_from: | 248 | if pkg in self._manifest_from.debs: |
615 | 224 | logging.debug('Found same kernel in manifest #1') | 249 | logging.debug('Found same kernel in manifest #1') |
616 | 225 | continue | 250 | continue |
618 | 226 | for fpkg in self._manifest_from: | 251 | for fpkg in self._manifest_from.debs: |
619 | 227 | if kmatch.match(fpkg) and fpkg.endswith("-%s" % img_type): | 252 | if kmatch.match(fpkg) and fpkg.endswith("-%s" % img_type): |
620 | 228 | logging.debug('Found similar kernel %s in manifest #1', | 253 | logging.debug('Found similar kernel %s in manifest #1', |
621 | 229 | fpkg) | 254 | fpkg) |
622 | @@ -232,8 +257,8 @@ class ManifestDiff(object): | |||
623 | 232 | for pkg_to, pkg_from in iteritems(kfixups): | 257 | for pkg_to, pkg_from in iteritems(kfixups): |
624 | 233 | logging.debug('Substituting kernel %s for %s in manifest #1 to ' | 258 | logging.debug('Substituting kernel %s for %s in manifest #1 to ' |
625 | 234 | 'enable version comparison', pkg_to, pkg_from) | 259 | 'enable version comparison', pkg_to, pkg_from) |
628 | 235 | self._manifest_from[pkg_to] = self._manifest_from[pkg_from] | 260 | self._manifest_from.debs[pkg_to] = self._manifest_from.debs[pkg_from] |
629 | 236 | del self._manifest_from[pkg_from] | 261 | del self._manifest_from.debs[pkg_from] |
630 | 237 | 262 | ||
631 | 238 | def _filter_changelog(self, changelog_path, version_low, version_high): | 263 | def _filter_changelog(self, changelog_path, version_low, version_high): |
632 | 239 | """ | 264 | """ |
633 | @@ -282,3 +307,21 @@ class ManifestDiff(object): | |||
634 | 282 | logging.error(error_msg) | 307 | logging.error(error_msg) |
635 | 283 | return change_blocks, error_msg | 308 | return change_blocks, error_msg |
636 | 284 | 309 | ||
637 | 310 | def _get_added_dict_items(self, from_dict, to_dict): | ||
638 | 311 | added = {} | ||
639 | 312 | for key in sorted(viewkeys(to_dict) - viewkeys(from_dict)): | ||
640 | 313 | added[key] = to_dict[key] | ||
641 | 314 | return added | ||
642 | 315 | |||
643 | 316 | def _get_removed_dict_items(self, from_dict, to_dict): | ||
644 | 317 | removed = {} | ||
645 | 318 | for key in sorted(viewkeys(from_dict) - viewkeys(to_dict)): | ||
646 | 319 | removed[key] = from_dict[key] | ||
647 | 320 | return removed | ||
648 | 321 | |||
649 | 322 | def _get_changed_dict_items(self, from_dict, to_dict): | ||
650 | 323 | changed = [] | ||
651 | 324 | for key in sorted(viewkeys(from_dict) & viewkeys(to_dict)): | ||
652 | 325 | if from_dict[key] != to_dict[key]: | ||
653 | 326 | changed.append(key) | ||
654 | 327 | return changed |
I haven't had time to do a full review, but I have a naming change suggestion: snaps are packages too, so using "pkgs" for debs is a little confusing. Could you do s/pkgs/debs/ (or deb_pkgs or something)?