Merge lp:~zyga/checkbox/fix-1300263 into lp:checkbox

Proposed by Zygmunt Krynicki
Status: Merged
Approved by: Daniel Manrique
Approved revision: 2858
Merged at revision: 2857
Proposed branch: lp:~zyga/checkbox/fix-1300263
Merge into: lp:checkbox
Diff against target: 82 lines (+30/-9)
1 file modified
plainbox/plainbox/provider_manager.py (+30/-9)
To merge this branch: bzr merge lp:~zyga/checkbox/fix-1300263
Reviewer Review Type Date Requested Status
Daniel Manrique (community) Approve
Review via email: mp+213536@code.launchpad.net

Description of the change

e075587 plainbox:provider_manager: silence warnings if optional files are missing
9e7fd3a plainbox:provider_manager: install built executables

To post a comment you must log in.
Revision history for this message
Daniel Manrique (roadmr) wrote :

Looks good!

26 + try:
27 + os.makedirs(dest_bin_dir, exist_ok=True)
28 + except IOError:
29 + pass

Why are you ignoring IOError? if creation failed, won't things fail later?

exist_ok=True avoids OSError if components already exist (though "OSError will also be raised if the directory creation fails."), but maybe IOError signals something else that would warrant our attention.

review: Needs Information
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

os.makedirs is notoriously odd, it doesn't work as if exists_ok=True was passed. I think it's a python bug but for now I apply the same tactics everywhere. I agree that this should be cleaned up but I would rather fix all instances (and reference any bugs in os.makedirs(exists_ok=True)

Revision history for this message
Daniel Manrique (roadmr) wrote :

ok, let's approve then, just don't forget to handle this. Also, it should raise OSError, not IOError, which is what tripped me up. A repro case of when you saw it raise IOError would be useful.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plainbox/plainbox/provider_manager.py'
2--- plainbox/plainbox/provider_manager.py 2014-03-31 17:55:04 +0000
3+++ plainbox/plainbox/provider_manager.py 2014-03-31 18:56:23 +0000
4@@ -254,20 +254,35 @@
5 associated with this commands have been parsed and are ready for
6 execution.
7 """
8- self._write_provider_file(ns.root, ns.prefix, ns.layout)
9+ provider = self.get_provider()
10+ self._write_provider_file(ns.root, ns.prefix, ns.layout, provider)
11+ self._copy_all_executables(ns.root, ns.prefix, ns.layout, provider)
12 self._copy_all_data(ns.root, ns.prefix, ns.layout)
13
14- def _write_provider_file(self, root, prefix, layout):
15+ def _write_provider_file(self, root, prefix, layout, provider):
16 self._write_to_file(
17 root, self._PROVIDER_TEMPLATE.format(
18 prefix=prefix, provider=self.definition),
19 lambda stream: self._get_provider_config_obj(
20- layout, prefix).write(stream))
21+ layout, prefix, provider).write(stream))
22+
23+ def _copy_all_executables(self, root, prefix, layout, provider):
24+ dest_map = self._get_dest_map(layout, prefix)
25+ dest_bin_dir = root + dest_map['bin']
26+ try:
27+ os.makedirs(dest_bin_dir, exist_ok=True)
28+ except IOError:
29+ pass
30+ for executable in provider.get_all_executables():
31+ shutil.copy(executable, dest_bin_dir)
32
33 def _copy_all_data(self, root, prefix, layout):
34 dest_map = self._get_dest_map(layout, prefix)
35 assert os.path.isabs(self.definition.location)
36 for src_name, dst_name in dest_map.items():
37+ # the bin/ directory is handled by _copy_all_executables()
38+ if src_name == 'bin':
39+ continue
40 assert not os.path.isabs(src_name)
41 assert os.path.isabs(dst_name)
42 src_name = os.path.join(self.definition.location, src_name)
43@@ -279,9 +294,6 @@
44 pass
45 _logger.info(_("copying: %s => %s"), src_name, dst_name)
46 shutil.copytree(src_name, dst_name)
47- else:
48- _logger.warning(_("cannot copy %s, no such file or directory"),
49- src_name)
50
51 def _get_dest_map(self, layout, prefix):
52 # Compute directory layout
53@@ -293,7 +305,7 @@
54 if dest_name_template is not None
55 }
56
57- def _get_provider_config_obj(self, layout, prefix):
58+ def _get_provider_config_obj(self, layout, prefix, provider):
59 dest_map = self._get_dest_map(layout, prefix)
60 # Create the .provider file config object
61 config_obj = self.definition.get_parser_obj()
62@@ -310,9 +322,18 @@
63 # explicit
64 config_obj.remove_option(section, 'location')
65 for src_name, key_id in self._DEF_MAP.items():
66- if os.path.exists(os.path.join(self.definition.location,
67- src_name)):
68+ # We should emit each foo_dir key only if the corresponding
69+ # directory actually exists
70+ should_emit_key = os.path.exists(
71+ os.path.join(self.definition.location, src_name))
72+ if should_emit_key:
73 config_obj.set(section, key_id, dest_map[src_name])
74+ # NOTE: Handle bin_dir specially:
75+ # For bin_dir do the exception that any executables (also
76+ # counting those from build/bin) should trigger bin_dir to be
77+ # listed since we will create/copy files there anyway.
78+ if provider.get_all_executables() != []:
79+ config_obj.set(section, 'bin_dir', dest_map['bin'])
80 return config_obj
81
82 def _write_to_file(self, root, pathname, callback):

Subscribers

People subscribed via source and target branches