Status: | Merged |
---|---|
Approved by: | Michael Vogt |
Approved revision: | 562 |
Merged at revision: | 454 |
Proposed branch: | lp:click/devel |
Merge into: | lp:click |
Diff against target: |
798 lines (+285/-160) 14 files modified
click/build.py (+48/-71) click/commands/build.py (+5/-0) click/commands/buildsource.py (+6/-0) click/framework.py (+19/-13) click/tests/helpers.py (+21/-0) click/tests/test_build.py (+37/-35) click/tests/test_database.py (+12/-0) click/tests/test_user.py (+22/-8) debian/changelog (+17/-0) debian/rules (+1/-1) doc/manpage.rst (+12/-2) lib/click/database.vala (+29/-3) lib/click/user.vala (+48/-27) pk-plugin/pk-plugin-click.c (+8/-0) |
To merge this branch: | bzr merge lp:click/devel |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
click hackers | Pending | ||
Review via email: mp+250584@code.launchpad.net |
Commit message
Click 0.4.38: stop apps when uninstalling them, fix crash on empty db, add --ignore option to click build, fix framework validation for snappy frameworks
Description of the change
click (0.4.38) UNRELEASED; urgency=low
* lp:~mvo/click/lp1232130-kill-on-remove-2:
- When uninstalling a app, stop it if its running (LP: #1232130)
* lp:~mvo/click/dont-crash-for-empty-db:
- Do not crash when no database configuration is used and
Click.
* lp:~mvo/click/lp1219912-build-exclude:
- add a new --ignore option to click {build,buildsource}
(LP: #1219912)
* lp:~mvo/click/fix-multiple-framework-validation:
- fix framework validation for snappy
-- Michael Vogt <email address hidden> Mon, 23 Feb 2015 08:20:04 +0100
- 563. By Michael Vogt
- 564. By Michael Vogt
-
bump version number
- 565. By Michael Vogt
-
bump version number
- 566. By Michael Vogt
-
run debian/
packagekit- check with "sh" as something in jenkins
made it mode 0644 - 567. By Michael Vogt
Preview Diff
1 | === modified file 'click/build.py' |
2 | --- click/build.py 2015-01-19 10:26:26 +0000 |
3 | +++ click/build.py 2015-02-26 17:06:20 +0000 |
4 | @@ -83,6 +83,42 @@ |
5 | class ClickBuilderBase: |
6 | def __init__(self): |
7 | self.file_map = {} |
8 | + # From @Dpkg::Source::Package::tar_ignore_default_pattern. |
9 | + # (more in ClickSourceBuilder) |
10 | + self._ignore_patterns = [ |
11 | + "*.click", |
12 | + ".*.sw?", |
13 | + "*~", |
14 | + ",,*", |
15 | + ".[#~]*", |
16 | + ".arch-ids", |
17 | + ".arch-inventory", |
18 | + ".bzr", |
19 | + ".bzr-builddeb", |
20 | + ".bzr.backup", |
21 | + ".bzr.tags", |
22 | + ".bzrignore", |
23 | + ".cvsignore", |
24 | + ".git", |
25 | + ".gitattributes", |
26 | + ".gitignore", |
27 | + ".gitmodules", |
28 | + ".hg", |
29 | + ".hgignore", |
30 | + ".hgsigs", |
31 | + ".hgtags", |
32 | + ".shelf", |
33 | + ".svn", |
34 | + "CVS", |
35 | + "DEADJOE", |
36 | + "RCS", |
37 | + "_MTN", |
38 | + "_darcs", |
39 | + "{arch}", |
40 | + ] |
41 | + |
42 | + def add_ignore_pattern(self, pattern): |
43 | + self._ignore_patterns.append(pattern) |
44 | |
45 | def add_file(self, source_path, dest_path): |
46 | self.file_map[source_path] = dest_path |
47 | @@ -132,39 +168,6 @@ |
48 | |
49 | |
50 | class ClickBuilder(ClickBuilderBase): |
51 | - # TODO: This should be configurable, or at least extensible. |
52 | - _ignore_patterns = [ |
53 | - "*.click", |
54 | - ".*.sw?", |
55 | - "*~", |
56 | - ",,*", |
57 | - ".[#~]*", |
58 | - ".arch-ids", |
59 | - ".arch-inventory", |
60 | - ".be", |
61 | - ".bzr", |
62 | - ".bzr-builddeb", |
63 | - ".bzr.backup", |
64 | - ".bzr.tags", |
65 | - ".bzrignore", |
66 | - ".cvsignore", |
67 | - ".git", |
68 | - ".gitattributes", |
69 | - ".gitignore", |
70 | - ".gitmodules", |
71 | - ".hg", |
72 | - ".hgignore", |
73 | - ".hgsigs", |
74 | - ".hgtags", |
75 | - ".shelf", |
76 | - ".svn", |
77 | - "CVS", |
78 | - "DEADJOE", |
79 | - "RCS", |
80 | - "_MTN", |
81 | - "_darcs", |
82 | - "{arch}", |
83 | - ] |
84 | |
85 | def list_files(self, root_path): |
86 | for dirpath, _, filenames in os.walk(root_path): |
87 | @@ -298,44 +301,18 @@ |
88 | |
89 | |
90 | class ClickSourceBuilder(ClickBuilderBase): |
91 | - # From @Dpkg::Source::Package::tar_ignore_default_pattern. |
92 | - # TODO: This should be configurable, or at least extensible. |
93 | - _ignore_patterns = [ |
94 | - "*.a", |
95 | - "*.click", |
96 | - "*.la", |
97 | - "*.o", |
98 | - "*.so", |
99 | - ".*.sw?", |
100 | - "*~", |
101 | - ",,*", |
102 | - ".[#~]*", |
103 | - ".arch-ids", |
104 | - ".arch-inventory", |
105 | - ".be", |
106 | - ".bzr", |
107 | - ".bzr-builddeb", |
108 | - ".bzr.backup", |
109 | - ".bzr.tags", |
110 | - ".bzrignore", |
111 | - ".cvsignore", |
112 | - ".deps", |
113 | - ".git", |
114 | - ".gitattributes", |
115 | - ".gitignore", |
116 | - ".gitmodules", |
117 | - ".hg", |
118 | - ".hgignore", |
119 | - ".hgsigs", |
120 | - ".hgtags", |
121 | - ".shelf", |
122 | - ".svn", |
123 | - "CVS", |
124 | - "DEADJOE", |
125 | - "RCS", |
126 | - "_MTN", |
127 | - "_darcs", |
128 | - "{arch}", |
129 | + |
130 | + def __init__(self): |
131 | + super(ClickSourceBuilder, self).__init__() |
132 | + # From @Dpkg::Source::Package::tar_ignore_default_pattern. |
133 | + # (more in ClickBuilderBase) |
134 | + self._ignore_patterns += [ |
135 | + "*.a", |
136 | + ".be", |
137 | + ".deps", |
138 | + "*.la", |
139 | + "*.o", |
140 | + "*.so", |
141 | ] |
142 | |
143 | def build(self, dest_dir, manifest_path=None): |
144 | |
145 | === modified file 'click/commands/build.py' |
146 | --- click/commands/build.py 2014-09-05 14:03:19 +0000 |
147 | +++ click/commands/build.py 2015-02-26 17:06:20 +0000 |
148 | @@ -34,6 +34,9 @@ |
149 | parser.add_option( |
150 | "--no-validate", action="store_false", default=True, dest="validate", |
151 | help="Don't run click-reviewers-tools check on resulting .click") |
152 | + parser.add_option( |
153 | + "-I", "--ignore", metavar="file-pattern", action='append', default=[], |
154 | + help="Ignore the given pattern when building the package") |
155 | options, args = parser.parse_args(argv) |
156 | if len(args) < 1: |
157 | parser.error("need directory") |
158 | @@ -48,6 +51,8 @@ |
159 | (directory, options.manifest)) |
160 | builder = ClickBuilder() |
161 | builder.add_file(directory, "./") |
162 | + for ignore in options.ignore: |
163 | + builder.add_ignore_pattern(ignore) |
164 | try: |
165 | path = builder.build(".", manifest_path=options.manifest) |
166 | except ClickBuildError as e: |
167 | |
168 | === modified file 'click/commands/buildsource.py' |
169 | --- click/commands/buildsource.py 2014-06-17 08:25:27 +0000 |
170 | +++ click/commands/buildsource.py 2015-02-26 17:06:20 +0000 |
171 | @@ -29,6 +29,10 @@ |
172 | parser.add_option( |
173 | "-m", "--manifest", metavar="PATH", |
174 | help="read package manifest from PATH") |
175 | + parser.add_option( |
176 | + "-I", "--ignore", metavar="file-pattern", action='append', |
177 | + default=[], |
178 | + help="Ignore the given pattern when building the package") |
179 | options, args = parser.parse_args(argv) |
180 | if len(args) < 1: |
181 | parser.error("need directory") |
182 | @@ -45,6 +49,8 @@ |
183 | (directory, options.manifest)) |
184 | builder = ClickSourceBuilder() |
185 | builder.add_file(directory, "./") |
186 | + for ignore in options.ignore: |
187 | + builder.add_ignore_pattern(ignore) |
188 | try: |
189 | path = builder.build(".", manifest_path=options.manifest) |
190 | except ClickBuildError as e: |
191 | |
192 | === modified file 'click/framework.py' |
193 | --- click/framework.py 2014-06-23 21:14:06 +0000 |
194 | +++ click/framework.py 2015-02-26 17:06:20 +0000 |
195 | @@ -31,12 +31,6 @@ |
196 | pass |
197 | |
198 | |
199 | -# FIXME: use native lib if available |
200 | -#from gi.repository import Click |
201 | -#click_framework_get_base_version = Click.framework_get_base_version |
202 | -#click_framework_has_framework = Click.has_framework |
203 | - |
204 | - |
205 | # python version of the vala parse_deb822_file() |
206 | def parse_deb822_file(filename): |
207 | data = {} |
208 | @@ -76,6 +70,12 @@ |
209 | return deb822.get("base-version", None) |
210 | |
211 | |
212 | +# python version of the vala click_framework_get_base_version() |
213 | +def click_framework_get_base_name(framework_name): |
214 | + deb822 = parse_deb822_file(get_framework_path(framework_name)) |
215 | + return deb822.get("base-name", None) |
216 | + |
217 | + |
218 | # python version of the vala click_framework_has_framework |
219 | def click_framework_has_framework(framework_name): |
220 | return os.path.exists(get_framework_path(framework_name)) |
221 | @@ -94,7 +94,7 @@ |
222 | raise ClickFrameworkInvalid( |
223 | 'Could not parse framework "%s"' % framework_string) |
224 | |
225 | - framework_base_versions = set() |
226 | + base_name_versions = {} |
227 | missing_frameworks = [] |
228 | for or_dep in parsed_framework: |
229 | if len(or_dep) > 1: |
230 | @@ -110,9 +110,20 @@ |
231 | if not click_framework_has_framework(framework_name): |
232 | missing_frameworks.append(framework_name) |
233 | continue |
234 | + # ensure we do not use different base versions for the same base-name |
235 | + framework_base_name = click_framework_get_base_name( |
236 | + framework_name) |
237 | framework_base_version = click_framework_get_base_version( |
238 | framework_name) |
239 | - framework_base_versions.add(framework_base_version) |
240 | + prev = base_name_versions.get(framework_base_name, None) |
241 | + if prev and prev != framework_base_version: |
242 | + raise ClickFrameworkInvalid( |
243 | + 'Multiple frameworks with different base versions are not ' |
244 | + 'allowed. Found: {} ({} != {})'.format( |
245 | + framework_base_name, |
246 | + framework_base_version, |
247 | + base_name_versions[framework_base_name])) |
248 | + base_name_versions[framework_base_name] = framework_base_version |
249 | |
250 | if not ignore_missing_frameworks: |
251 | if len(missing_frameworks) > 1: |
252 | @@ -132,8 +143,3 @@ |
253 | elif missing_frameworks: |
254 | logging.warning('Ignoring missing framework "%s"' % ( |
255 | missing_frameworks[0])) |
256 | - |
257 | - if len(framework_base_versions) > 1: |
258 | - raise ClickFrameworkInvalid( |
259 | - 'Multiple frameworks with different base versions are not ' |
260 | - 'allowed. Found: {0}'.format(framework_base_versions)) |
261 | |
262 | === modified file 'click/tests/helpers.py' |
263 | --- click/tests/helpers.py 2014-09-29 13:23:52 +0000 |
264 | +++ click/tests/helpers.py 2015-02-26 17:06:20 +0000 |
265 | @@ -30,6 +30,7 @@ |
266 | |
267 | import contextlib |
268 | from functools import wraps |
269 | +import json |
270 | import os |
271 | import re |
272 | import shutil |
273 | @@ -59,6 +60,26 @@ |
274 | return wrapper |
275 | |
276 | |
277 | +def make_installed_click(db, db_dir, package="test-1", version="1.0", |
278 | + json_data={}, make_current=True, user="@all"): |
279 | + """Create a fake installed click package for the given db/db_dir""" |
280 | + json_data["name"] = package |
281 | + json_data["version"] = version |
282 | + with mkfile_utf8(os.path.join( |
283 | + db_dir, package, version, ".click", "info", |
284 | + "%s.manifest" % package)) as f: |
285 | + json.dump(json_data, f, ensure_ascii=False) |
286 | + if make_current: |
287 | + os.symlink( |
288 | + version, os.path.join(db_dir, package, "current")) |
289 | + if user == "@all": |
290 | + registry = Click.User.for_all_users(db) |
291 | + else: |
292 | + registry = Click.User.for_user(db, user) |
293 | + registry.set_version(package, version) |
294 | + return os.path.join(db_dir, package, version) |
295 | + |
296 | + |
297 | class TestCase(gimock.GIMockTestCase): |
298 | def setUp(self): |
299 | super(TestCase, self).setUp() |
300 | |
301 | === modified file 'click/tests/test_build.py' |
302 | --- click/tests/test_build.py 2015-01-19 10:26:26 +0000 |
303 | +++ click/tests/test_build.py 2015-02-26 17:06:20 +0000 |
304 | @@ -207,21 +207,37 @@ |
305 | self.assertEqual( |
306 | "foo", os.readlink(os.path.join(extract_path, "bin", "bar"))) |
307 | |
308 | + def _make_scratch_dir(self, manifest_override={}): |
309 | + self.use_temp_dir() |
310 | + scratch = os.path.join(self.temp_dir, "scratch") |
311 | + manifest = { |
312 | + "name": "com.example.test", |
313 | + "version": "1.0", |
314 | + "maintainer": "Foo Bar <foo@example.org>", |
315 | + "title": "test title", |
316 | + "architecture": "all", |
317 | + "framework": "ubuntu-sdk-13.10", |
318 | + } |
319 | + manifest.update(manifest_override) |
320 | + with mkfile(os.path.join(scratch, "manifest.json")) as f: |
321 | + json.dump(manifest, f) |
322 | + self.builder.add_file(scratch, "/") |
323 | + return scratch |
324 | + |
325 | @disable_logging |
326 | def test_build_excludes_dot_click(self): |
327 | - self.use_temp_dir() |
328 | - scratch = os.path.join(self.temp_dir, "scratch") |
329 | + scratch = self._make_scratch_dir() |
330 | touch(os.path.join(scratch, ".click", "evil-file")) |
331 | - with mkfile(os.path.join(scratch, "manifest.json")) as f: |
332 | - json.dump({ |
333 | - "name": "com.example.test", |
334 | - "version": "1.0", |
335 | - "maintainer": "Foo Bar <foo@example.org>", |
336 | - "title": "test title", |
337 | - "architecture": "all", |
338 | - "framework": "ubuntu-sdk-13.10", |
339 | - }, f) |
340 | + path = self.builder.build(self.temp_dir) |
341 | + extract_path = os.path.join(self.temp_dir, "extract") |
342 | + subprocess.check_call(["dpkg-deb", "-x", path, extract_path]) |
343 | + self.assertEqual([], os.listdir(extract_path)) |
344 | + |
345 | + def test_build_ignore_pattern(self): |
346 | + scratch = self._make_scratch_dir() |
347 | + touch(os.path.join(scratch, "build", "foo.o")) |
348 | self.builder.add_file(scratch, "/") |
349 | + self.builder.add_ignore_pattern("build") |
350 | path = self.builder.build(self.temp_dir) |
351 | extract_path = os.path.join(self.temp_dir, "extract") |
352 | subprocess.check_call(["dpkg-deb", "-x", path, extract_path]) |
353 | @@ -229,18 +245,9 @@ |
354 | |
355 | @disable_logging |
356 | def test_build_multiple_architectures(self): |
357 | - self.use_temp_dir() |
358 | - scratch = os.path.join(self.temp_dir, "scratch") |
359 | - with mkfile(os.path.join(scratch, "manifest.json")) as f: |
360 | - json.dump({ |
361 | - "name": "com.example.test", |
362 | - "version": "1.0", |
363 | - "maintainer": "Foo Bar <foo@example.org>", |
364 | - "title": "test title", |
365 | + scratch = self._make_scratch_dir(manifest_override={ |
366 | "architecture": ["armhf", "i386"], |
367 | - "framework": "ubuntu-sdk-13.10", |
368 | - }, f) |
369 | - self.builder.add_file(scratch, "/") |
370 | + }) |
371 | path = os.path.join(self.temp_dir, "com.example.test_1.0_multi.click") |
372 | self.assertEqual(path, self.builder.build(self.temp_dir)) |
373 | self.assertTrue(os.path.exists(path)) |
374 | @@ -255,22 +262,12 @@ |
375 | del target_json["installed-size"] |
376 | self.assertEqual(source_json, target_json) |
377 | |
378 | - # FIXME: DRY violation with test_build_multiple_architectures etc |
379 | @disable_logging |
380 | def test_build_multiple_frameworks(self): |
381 | - self.use_temp_dir() |
382 | - scratch = os.path.join(self.temp_dir, "scratch") |
383 | - with mkfile(os.path.join(scratch, "manifest.json")) as f: |
384 | - json.dump({ |
385 | - "name": "com.example.test", |
386 | - "version": "1.0", |
387 | - "maintainer": "Foo Bar <foo@example.org>", |
388 | - "title": "test title", |
389 | - "architecture": "all", |
390 | + scratch = self._make_scratch_dir(manifest_override={ |
391 | "framework": |
392 | "ubuntu-sdk-14.04-basic, ubuntu-sdk-14.04-webapps", |
393 | - }, f) |
394 | - self.builder.add_file(scratch, "/") |
395 | + }) |
396 | path = self.builder.build(self.temp_dir) |
397 | control_path = os.path.join(self.temp_dir, "control") |
398 | subprocess.check_call(["dpkg-deb", "-e", path, control_path]) |
399 | @@ -289,13 +286,15 @@ |
400 | self.builder = ClickBuilder() |
401 | for framework_name in ("ubuntu-sdk-13.10", |
402 | "ubuntu-sdk-14.04-papi", |
403 | - "ubuntu-sdk-14.04-html"): |
404 | + "ubuntu-sdk-14.04-html", |
405 | + "docker-sdk-1.3"): |
406 | self._create_mock_framework_file(framework_name) |
407 | |
408 | def test_validate_framework_good(self): |
409 | valid_framework_values = ( |
410 | "ubuntu-sdk-13.10", |
411 | "ubuntu-sdk-14.04-papi, ubuntu-sdk-14.04-html", |
412 | + "ubuntu-sdk-13.10, docker-sdk-1.3", |
413 | ) |
414 | for framework in valid_framework_values: |
415 | self.builder._validate_framework(framework) |
416 | @@ -322,6 +321,8 @@ |
417 | scratch = os.path.join(self.temp_dir, "scratch") |
418 | touch(os.path.join(scratch, "bin", "foo")) |
419 | touch(os.path.join(scratch, ".git", "config")) |
420 | + touch(os.path.join(scratch, "foo.so")) |
421 | + touch(os.path.join(scratch, "build", "meep.goah")) |
422 | with mkfile(os.path.join(scratch, "manifest.json")) as f: |
423 | json.dump({ |
424 | "name": "com.example.test", |
425 | @@ -334,6 +335,7 @@ |
426 | # build() overrides this back to 0o644 |
427 | os.fchmod(f.fileno(), 0o600) |
428 | self.builder.add_file(scratch, "./") |
429 | + self.builder.add_ignore_pattern("build") |
430 | path = os.path.join(self.temp_dir, "com.example.test_1.0.tar.gz") |
431 | self.assertEqual(path, self.builder.build(self.temp_dir)) |
432 | self.assertTrue(os.path.exists(path)) |
433 | |
434 | === modified file 'click/tests/test_database.py' |
435 | --- click/tests/test_database.py 2014-09-10 11:54:14 +0000 |
436 | +++ click/tests/test_database.py 2015-02-26 17:06:20 +0000 |
437 | @@ -562,6 +562,18 @@ |
438 | db = Click.DB() |
439 | self.assertEqual(0, db.props.size) |
440 | |
441 | + def test_no_db_conf_errors(self): |
442 | + db = Click.DB() |
443 | + self.assertRaisesDatabaseError( |
444 | + Click.DatabaseError.INVALID, db.get, 0) |
445 | + self.assertEqual(db.props.overlay, "") |
446 | + self.assertRaisesDatabaseError( |
447 | + Click.DatabaseError.INVALID, db.maybe_remove, "something", "1.0") |
448 | + self.assertRaisesDatabaseError( |
449 | + Click.DatabaseError.INVALID, db.gc) |
450 | + self.assertRaisesDatabaseError( |
451 | + Click.DatabaseError.INVALID, db.ensure_ownership) |
452 | + |
453 | def test_read_nonexistent(self): |
454 | db = Click.DB() |
455 | db.read(db_dir=os.path.join(self.temp_dir, "nonexistent")) |
456 | |
457 | === modified file 'click/tests/test_user.py' |
458 | --- click/tests/test_user.py 2014-09-29 11:12:52 +0000 |
459 | +++ click/tests/test_user.py 2015-02-26 17:06:20 +0000 |
460 | @@ -34,6 +34,7 @@ |
461 | from click.tests.gimock_types import Passwd |
462 | from click.tests.helpers import ( |
463 | TestCase, |
464 | + make_installed_click, |
465 | mkfile, |
466 | make_file_with_content, |
467 | touch, |
468 | @@ -557,21 +558,34 @@ |
469 | self.assertEqual(b_overlay, registry.get_path("b")) |
470 | self.assertTrue(registry.is_removable("b")) |
471 | |
472 | - def test_app_stops_on_remove(self): |
473 | + |
474 | +class StopAppTestCase(TestCase): |
475 | + |
476 | + def setUp(self): |
477 | + super(StopAppTestCase, self).setUp() |
478 | + self.use_temp_dir() |
479 | + self.db = Click.DB() |
480 | + self.db.add(self.temp_dir) |
481 | + |
482 | + # setup fake app_stop |
483 | fake_app_stop = os.path.join(self.temp_dir, "bin", "ubuntu-app-stop") |
484 | - fake_app_stop_output = os.path.join(self.temp_dir, "fake-app-stop.out") |
485 | + self.fake_app_stop_output = os.path.join( |
486 | + self.temp_dir, "fake-app-stop.out") |
487 | fake_app_stop_content = dedent("""\ |
488 | #!/bin/sh |
489 | echo "$@" >> %s |
490 | - """ % fake_app_stop_output) |
491 | + """ % self.fake_app_stop_output) |
492 | make_file_with_content(fake_app_stop, fake_app_stop_content, 0o755) |
493 | # its ok to modify env here, click.helpers.TestCase will take care |
494 | # of it |
495 | os.environ["PATH"] = "%s:%s" % ( |
496 | os.path.dirname(fake_app_stop), os.environ["PATH"]) |
497 | - # get a app with manifest etc all |
498 | - _, registry = self._setUpMultiDB() |
499 | - registry.remove("a") |
500 | + |
501 | + def test_app_stops_on_remove(self): |
502 | + make_installed_click(self.db, self.temp_dir, "meep", "2.0", |
503 | + {"hooks": {"a-app": {}}}) |
504 | + registry = Click.User.for_user(self.db, "user") |
505 | + registry.remove("meep") |
506 | # ensure that stop was called with the right app |
507 | - with open(fake_app_stop_output) as f: |
508 | - self.assertEqual("a_a-app_1.1", f.read().strip()) |
509 | + with open(self.fake_app_stop_output) as f: |
510 | + self.assertEqual("meep_a-app_2.0", f.read().strip()) |
511 | |
512 | === modified file 'debian/changelog' |
513 | --- debian/changelog 2015-02-13 14:46:35 +0000 |
514 | +++ debian/changelog 2015-02-26 17:06:20 +0000 |
515 | @@ -1,3 +1,20 @@ |
516 | +click (0.4.38.4) UNRELEASED; urgency=low |
517 | + |
518 | + * lp:~mvo/click/lp1232130-kill-on-remove-2: |
519 | + - When uninstalling a app, stop it if its running (LP: #1232130) |
520 | + * lp:~mvo/click/dont-crash-for-empty-db: |
521 | + - Do not crash when no database configuration is used and |
522 | + Click.DB.{get,props.overlay,gc,ensure_ownership} are called. |
523 | + * lp:~mvo/click/lp1219912-build-exclude: |
524 | + - add a new --ignore option to click {build,buildsource} |
525 | + (LP: #1219912) |
526 | + * lp:~mvo/click/fix-multiple-framework-validation: |
527 | + - fix framework validation for snappy |
528 | + * run debian/packagekit-check with "sh" as something in jenkins |
529 | + made it mode 0644 |
530 | + |
531 | + -- Michael Vogt <michael.vogt@ubuntu.com> Mon, 23 Feb 2015 08:20:04 +0100 |
532 | + |
533 | click (0.4.37) vivid; urgency=low |
534 | |
535 | [ Michael Vogt ] |
536 | |
537 | === modified file 'debian/rules' |
538 | --- debian/rules 2014-10-10 07:10:23 +0000 |
539 | +++ debian/rules 2015-02-26 17:06:20 +0000 |
540 | @@ -1,6 +1,6 @@ |
541 | #! /usr/bin/make -f |
542 | |
543 | -PACKAGEKIT := $(shell debian/packagekit-check) |
544 | +PACKAGEKIT := $(shell sh debian/packagekit-check) |
545 | ifeq ($(PACKAGEKIT),yes) |
546 | EXTRA_DH_OPTIONS := |
547 | else |
548 | |
549 | === modified file 'doc/manpage.rst' |
550 | --- doc/manpage.rst 2014-10-13 12:48:35 +0000 |
551 | +++ doc/manpage.rst 2015-02-26 17:06:20 +0000 |
552 | @@ -73,6 +73,11 @@ |
553 | |
554 | -m PATH, --manifest=PATH Read package manifest from PATH |
555 | (default: ``manifest.json``). |
556 | +-I file-pattern, --ignore=file-pattern Ignore the given shell-pattern |
557 | + when building the package. |
558 | + The option may be repeated multiple |
559 | + times to list multiple patterns to |
560 | + exclude. |
561 | --no-validate Don't run checks from click-reviewers-tools on |
562 | the resulting .click file. |
563 | |
564 | @@ -90,8 +95,13 @@ |
565 | |
566 | Options: |
567 | |
568 | --m PATH, --manifest=PATH Read package manifest from PATH |
569 | - (default: ``manifest.json``). |
570 | +-m PATH, --manifest=PATH Read package manifest from PATH |
571 | + (default: ``manifest.json``). |
572 | +-I file-pattern, --ignore=file-pattern Ignore the given shell-pattern |
573 | + when building the package. |
574 | + The option may be repeated multiple |
575 | + times to list multiple patterns to |
576 | + exclude. |
577 | |
578 | click chroot |
579 | ------------ |
580 | |
581 | === modified file 'lib/click/database.vala' |
582 | --- lib/click/database.vala 2014-09-12 11:46:05 +0000 |
583 | +++ lib/click/database.vala 2015-02-26 17:06:20 +0000 |
584 | @@ -34,7 +34,11 @@ |
585 | /** |
586 | * Package manifest cannot be parsed. |
587 | */ |
588 | - BAD_MANIFEST |
589 | + BAD_MANIFEST, |
590 | + /** |
591 | + * No database available for the given request |
592 | + */ |
593 | + INVALID |
594 | } |
595 | |
596 | private string? app_pid_command = null; |
597 | @@ -602,8 +606,11 @@ |
598 | public int size { get { return db.size; } } |
599 | |
600 | public new SingleDB |
601 | - @get (int index) |
602 | + @get (int index) throws DatabaseError |
603 | { |
604 | + if (index >= db.size) |
605 | + throw new DatabaseError.INVALID |
606 | + ("invalid index %i for db of size %i", index, db.size); |
607 | return db.get (index); |
608 | } |
609 | |
610 | @@ -618,7 +625,15 @@ |
611 | * |
612 | * The directory where changes should be written. |
613 | */ |
614 | - public string overlay { get { return db.last ().root; } } |
615 | + public string overlay |
616 | + { |
617 | + get { |
618 | + if (db.size == 0) |
619 | + return ""; |
620 | + else |
621 | + return db.last ().root; |
622 | + } |
623 | + } |
624 | |
625 | /** |
626 | * get_path: |
627 | @@ -812,21 +827,32 @@ |
628 | return generator.to_data (null); |
629 | } |
630 | |
631 | + private void |
632 | + ensure_db () throws Error |
633 | + { |
634 | + if (db.size == 0) |
635 | + throw new DatabaseError.INVALID |
636 | + ("no database loaded"); |
637 | + } |
638 | + |
639 | public void |
640 | maybe_remove (string package, string version) throws Error |
641 | { |
642 | + ensure_db(); |
643 | db.last ().maybe_remove (package, version); |
644 | } |
645 | |
646 | public void |
647 | gc () throws Error |
648 | { |
649 | + ensure_db(); |
650 | db.last ().gc (); |
651 | } |
652 | |
653 | public void |
654 | ensure_ownership () throws Error |
655 | { |
656 | + ensure_db(); |
657 | db.last ().ensure_ownership (); |
658 | } |
659 | } |
660 | |
661 | === modified file 'lib/click/user.vala' |
662 | --- lib/click/user.vala 2014-12-05 15:09:48 +0000 |
663 | +++ lib/click/user.vala 2015-02-26 17:06:20 +0000 |
664 | @@ -658,8 +658,49 @@ |
665 | old_version, username); |
666 | } |
667 | |
668 | - private bool |
669 | - stop_running_app (string package, string version) |
670 | + private string |
671 | + get_dbus_session_bus_env_for_current_user() |
672 | + { |
673 | + string euid = "%i".printf((int)(Posix.geteuid ())); |
674 | + var dbus_session_file = Path.build_filename( |
675 | + "/run", "user", euid, "dbus-session"); |
676 | + string session_env; |
677 | + try { |
678 | + FileUtils.get_contents(dbus_session_file, out session_env); |
679 | + session_env = session_env.strip(); |
680 | + } catch (Error e) { |
681 | + warning("Can not get the dbus session to stop app (%s)", e.message); |
682 | + } |
683 | + return session_env; |
684 | + } |
685 | + |
686 | + private bool |
687 | + stop_single_app (string app_id) |
688 | + { |
689 | + // get the users dbus session when we run as root first as this |
690 | + // is where ubuntu-app-stop listens |
691 | + string[] envp = Environ.get(); |
692 | + envp += get_dbus_session_bus_env_for_current_user(); |
693 | + |
694 | + string[] command = { |
695 | + "ubuntu-app-stop", app_id |
696 | + }; |
697 | + bool res = false; |
698 | + try { |
699 | + int exit_status; |
700 | + Process.spawn_sync |
701 | + (null, command, envp, |
702 | + SpawnFlags.SEARCH_PATH, |
703 | + null, null, null, out exit_status); |
704 | + res = Process.check_exit_status (exit_status); |
705 | + } catch (Error e) { |
706 | + res = false; |
707 | + } |
708 | + return res; |
709 | + } |
710 | + |
711 | + private bool |
712 | + stop_running_apps_for_package (string package, string version) |
713 | { |
714 | var res = true; |
715 | if (! find_on_path ("ubuntu-app-stop")) |
716 | @@ -679,24 +720,7 @@ |
717 | } |
718 | var hooks = manifest.get_object_member ("hooks"); |
719 | foreach (unowned string app_name in hooks.get_members ()) |
720 | - { |
721 | - // FIXME: move this into a "stop_single_app" helper |
722 | - string[] command = { |
723 | - "ubuntu-app-stop", |
724 | - @"$(package)_$(app_name)_$(version)" |
725 | - }; |
726 | - try { |
727 | - int exit_status; |
728 | - Process.spawn_sync |
729 | - (null, command, null, |
730 | - SpawnFlags.SEARCH_PATH | |
731 | - SpawnFlags.STDOUT_TO_DEV_NULL, |
732 | - null, null, null, out exit_status); |
733 | - res &= Process.check_exit_status (exit_status); |
734 | - } catch (Error e) { |
735 | - res &= false; |
736 | - } |
737 | - } |
738 | + res &= stop_single_app (@"$(package)_$(app_name)_$(version)"); |
739 | return res; |
740 | } |
741 | |
742 | @@ -718,6 +742,8 @@ |
743 | old_version = Path.get_basename (target); |
744 | drop_privileges (); |
745 | try { |
746 | + // stop before removing the path to the manifest |
747 | + stop_running_apps_for_package (package, old_version); |
748 | unlink_force (path); |
749 | } finally { |
750 | regain_privileges (); |
751 | @@ -733,19 +759,14 @@ |
752 | ensure_db (); |
753 | drop_privileges (); |
754 | try { |
755 | + // stop before removing the path to the manifest |
756 | + stop_running_apps_for_package (package, old_version); |
757 | symlink_force (HIDDEN_VERSION, path); |
758 | } finally { |
759 | regain_privileges (); |
760 | } |
761 | } |
762 | |
763 | - drop_privileges (); |
764 | - try { |
765 | - stop_running_app (package, old_version); |
766 | - } finally { |
767 | - regain_privileges (); |
768 | - } |
769 | - |
770 | if (! is_pseudo_user) |
771 | package_remove_hooks (db, package, old_version, name); |
772 | |
773 | |
774 | === modified file 'pk-plugin/pk-plugin-click.c' |
775 | --- pk-plugin/pk-plugin-click.c 2014-09-02 08:44:39 +0000 |
776 | +++ pk-plugin/pk-plugin-click.c 2015-02-26 17:06:20 +0000 |
777 | @@ -637,6 +637,11 @@ |
778 | GError *error = NULL; |
779 | gchar *summary = NULL; |
780 | |
781 | + // PK does not set a PATH, but we need one for removal |
782 | + const gchar *old_path = g_getenv("PATH"); |
783 | + if(old_path == NULL) |
784 | + g_setenv("PATH", DEFAULT_PATH, 0); |
785 | + |
786 | username = click_get_username_for_uid |
787 | (pk_transaction_get_uid (transaction)); |
788 | if (!username) { |
789 | @@ -701,6 +706,9 @@ |
790 | ret = TRUE; |
791 | |
792 | out: |
793 | + if(old_path == NULL) |
794 | + g_unsetenv("PATH"); |
795 | + |
796 | g_free (summary); |
797 | if (error) |
798 | g_error_free (error); |