Merge lp:~milo/linaro-image-tools/method-refactor into lp:linaro-image-tools/11.11

Proposed by Milo Casagrande
Status: Merged
Merged at revision: 579
Proposed branch: lp:~milo/linaro-image-tools/method-refactor
Merge into: lp:linaro-image-tools/11.11
Diff against target: 283 lines (+154/-113)
1 file modified
linaro_image_tools/hwpack/builder.py (+154/-113)
To merge this branch: bzr merge lp:~milo/linaro-image-tools/method-refactor
Reviewer Review Type Date Requested Status
James Tunnicliffe (community) Approve
Paul Sokolovsky Pending
Linaro Infrastructure Pending
Review via email: mp+130123@code.launchpad.net

Description of the change

Branch with some code refactoring for the build() method in builder.py.
The method was starting to be very big and dificult to read.

To post a comment you must log in.
Revision history for this message
James Tunnicliffe (dooferlad) wrote :

Thanks for tidying this up, but since it is a tidy-up branch, I am
going to be extra picky :-)

154 + def _old_format_extract_files(self):
155 + """
156 + Extract files for hwpack versions < 3.0.
157 + """

I think you have space to put the docstring on one line.
http://www.python.org/dev/peps/pep-0257/ likes docstrings that start
on the same line as the opening quote and is OK with the closing quote
on the same line.

There are several new functions without docstrings. Since this is a
re-factor, should probably include them.

161 + bootloader_package = \
162 + self.find_fetched_package(self.packages,
163 + self.config.bootloader_package)

I personally find the use of \ to continue a line ugly and think the
following form is easier on the eyes:

            bootloader_package = self.find_fetched_package(
                                        self.packages,
                                        self.config.bootloader_package)

Just personal preference though. There are several instances of this
type of line continuation that I think are only there because it was
how the old code was formatted.

Fix those two and it is fine (I assume you have done some test builds
and the unit tests pass).

579. By Milo Casagrande

Fixed docstring and code indent.

580. By Milo Casagrande

Added docstrings.

Revision history for this message
Milo Casagrande (milo) wrote :

Hey James!

Thanks for the review.

On Wed, Oct 17, 2012 at 5:42 PM, James Tunnicliffe
<email address hidden> wrote:
> Thanks for tidying this up, but since it is a tidy-up branch, I am
> going to be extra picky :-)
>
> 154 + def _old_format_extract_files(self):
> 155 + """
> 156 + Extract files for hwpack versions < 3.0.
> 157 + """
>
> I think you have space to put the docstring on one line.
> http://www.python.org/dev/peps/pep-0257/ likes docstrings that start
> on the same line as the opening quote and is OK with the closing quote
> on the same line.
>
> There are several new functions without docstrings. Since this is a
> re-factor, should probably include them.

Fixed them both, at least for the newly introduced functions.

>
> 161 + bootloader_package = \
> 162 + self.find_fetched_package(self.packages,
> 163 + self.config.bootloader_package)
>
> I personally find the use of \ to continue a line ugly and think the
> following form is easier on the eyes:
>
> bootloader_package = self.find_fetched_package(
> self.packages,
> self.config.bootloader_package)
>
> Just personal preference though. There are several instances of this
> type of line continuation that I think are only there because it was
> how the old code was formatted.

I do not like using \ either, removed and used a better formatting.
Thanks again!

--
Milo Casagrande
Infrastructure Engineer
Linaro.org <www.linaro.org> │ Open source software for ARM SoCs

Revision history for this message
Milo Casagrande (milo) wrote :

Forgot about this last:

On Wed, Oct 17, 2012 at 5:42 PM, James Tunnicliffe
<email address hidden> wrote:
> Fix those two and it is fine (I assume you have done some test builds
> and the unit tests pass).

Yes, tests pass (apart the one from bug 1067786).
I created also two hwpacks with the new code, and compared with two
done using old code: they seems to work to the point where l-m-c can
create an image.

--
Milo Casagrande
Infrastructure Engineer
Linaro.org <www.linaro.org> │ Open source software for ARM SoCs

Revision history for this message
James Tunnicliffe (dooferlad) wrote :

Great, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'linaro_image_tools/hwpack/builder.py'
2--- linaro_image_tools/hwpack/builder.py 2012-10-12 12:31:22 +0000
3+++ linaro_image_tools/hwpack/builder.py 2012-10-17 16:06:24 +0000
4@@ -270,125 +270,166 @@
5 self.packages,
6 download_content=self.config.include_debs)
7
8- # On a v3 hwpack, all the values we need to check are
9- # in the bootloaders and boards section, so we loop
10- # through both of them changing what is necessary.
11-
12- if self.config.format.format_as_string == '3.0':
13+ if self.format.format_as_string == '3.0':
14 self.extract_files()
15 else:
16- bootloader_package = None
17- if self.config.bootloader_file is not None:
18- assert(self.config.bootloader_package
19- is not None)
20- bootloader_package = self.find_fetched_package(
21- self.packages,
22- self.config.bootloader_package)
23- self.hwpack.metadata.u_boot = \
24- self.add_file_to_hwpack(
25- bootloader_package,
26- self.config.bootloader_file,
27- self.hwpack.U_BOOT_DIR)
28-
29- spl_package = None
30- if self.config.spl_file is not None:
31- assert self.config.spl_package is not None
32- spl_package = self.find_fetched_package(
33- self.packages,
34- self.config.spl_package)
35- self.hwpack.metadata.spl = \
36- self.add_file_to_hwpack(
37- spl_package,
38- self.config.spl_file,
39- self.hwpack.SPL_DIR)
40-
41- # bootloader_package and spl_package can be
42- # identical
43- if (bootloader_package is not None and
44- bootloader_package in self.packages):
45- self.packages.remove(bootloader_package)
46- if (spl_package is not None and
47- spl_package in self.packages):
48- self.packages.remove(spl_package)
49-
50- logger.debug("Adding packages to hwpack")
51- self.hwpack.add_packages(self.packages)
52- for local_package in local_packages:
53- if local_package not in self.packages:
54- logger.warning(
55- "Local package '%s' not included",
56- local_package.name)
57- self.hwpack.add_dependency_package(
58- self.config.packages)
59+ self._old_format_extract_files()
60+
61+ self._add_packages_to_hwpack(local_packages)
62+
63 out_name = self.out_name
64 if not out_name:
65 out_name = self.hwpack.filename()
66- with open(out_name, 'w') as f:
67- self.hwpack.to_file(f)
68- logger.info("Wrote %s" % out_name)
69+
70 manifest_name = os.path.splitext(out_name)[0]
71 if manifest_name.endswith('.tar'):
72 manifest_name = os.path.splitext(manifest_name)[0]
73 manifest_name += '.manifest.txt'
74- with open(manifest_name, 'w') as f:
75- f.write(self.hwpack.manifest_text())
76-
77- logger.debug("Extracting build-info")
78- build_info_dir = os.path.join(fetcher.cache.tempdir,
79- 'build-info')
80- build_info_available = 0
81- for deb_pkg in self.packages:
82- deb_pkg_file_path = deb_pkg.filepath
83- if os.path.islink(deb_pkg_file_path):
84- # Skip symlink-ed debian package file
85- # e.g. fetched package with dummy information
86- continue
87- try:
88- # Extract Build-Info attribute from debian
89- # control
90- deb_control = \
91- DebFile(deb_pkg_file_path).control.debcontrol()
92- build_info = deb_control.get('Build-Info')
93- except ArError:
94- # Skip invalid debian package file
95- # e.g. fetched package with dummy information
96- continue
97- if build_info is not None:
98- build_info_available += 1
99- # Extract debian packages with build
100- # information
101- env = os.environ
102- env['LC_ALL'] = 'C'
103- env['NO_PKG_MANGLE'] = '1'
104- proc = cmd_runner.Popen(['dpkg-deb', '-x',
105- deb_pkg_file_path, build_info_dir],
106- env=env, stdout=subprocess.PIPE,
107- stderr=subprocess.PIPE)
108- (stdoutdata, stderrdata) = proc.communicate()
109- if proc.returncode:
110- raise ValueError('dpkg-deb extract failed!'
111- '\n%s' % stderrdata)
112- if stderrdata:
113- raise ValueError('dpkg-deb extract had '
114- 'warnings:\n%s' % stderrdata)
115-
116- # Concatenate BUILD-INFO.txt files
117- dst_file = open('BUILD-INFO.txt', 'wb')
118- if build_info_available > 0:
119- build_info_path = \
120- r'%s/usr/share/doc/*/BUILD-INFO.txt' % \
121- build_info_dir
122- for src_file in iglob(build_info_path):
123- with open(src_file, 'rb') as f:
124- dst_file.write('\nFiles-Pattern: %s\n' % \
125- out_name)
126- shutil.copyfileobj(f, dst_file)
127- dst_file.write('\nFiles-Pattern: %s\n'
128- 'License-Type: open\n' %\
129- manifest_name)
130- else:
131- dst_file.write('Format-Version: 0.1\n'
132- 'Files-Pattern: %s, %s\n'
133- 'License-Type: open\n' % \
134- (out_name, manifest_name))
135- dst_file.close()
136+
137+ self._write_hwpack_and_manifest(out_name,
138+ manifest_name)
139+
140+ cache_dir = fetcher.cache.tempdir
141+ self._extract_build_info(cache_dir, out_name,
142+ manifest_name)
143+
144+ def _write_hwpack_and_manifest(self, out_name, manifest_name):
145+ """Write the real hwpack file and its manifest file.
146+
147+ :param out_name: The name of the file to write.
148+ :type out_name: str
149+ :param manifest_name: The name of the manifest file.
150+ :type manifest_name: str
151+ """
152+ logger.debug("Writing hwpack file")
153+ with open(out_name, 'w') as f:
154+ self.hwpack.to_file(f)
155+ logger.info("Wrote %s" % out_name)
156+
157+ logger.debug("Writing manifest file content")
158+ with open(manifest_name, 'w') as f:
159+ f.write(self.hwpack.manifest_text())
160+
161+ def _old_format_extract_files(self):
162+ """Extract files for hwpack versions < 3.0."""
163+ bootloader_package = None
164+ if self.config.bootloader_file is not None:
165+ assert(self.config.bootloader_package is not None)
166+ bootloader_package = self.find_fetched_package(
167+ self.packages,
168+ self.config.bootloader_package)
169+ self.hwpack.metadata.u_boot = self.add_file_to_hwpack(
170+ bootloader_package,
171+ self.config.bootloader_file,
172+ self.hwpack.U_BOOT_DIR)
173+
174+ spl_package = None
175+ if self.config.spl_file is not None:
176+ assert self.config.spl_package is not None
177+ spl_package = self.find_fetched_package(self.packages,
178+ self.config.spl_package)
179+ self.hwpack.metadata.spl = self.add_file_to_hwpack(
180+ spl_package,
181+ self.config.spl_file,
182+ self.hwpack.SPL_DIR)
183+
184+ # bootloader_package and spl_package can be identical
185+ if (bootloader_package is not None and
186+ bootloader_package in self.packages):
187+ self.packages.remove(bootloader_package)
188+ if (spl_package is not None and spl_package in self.packages):
189+ self.packages.remove(spl_package)
190+
191+ def _add_packages_to_hwpack(self, local_packages):
192+ """Adds the packages to the hwpack.
193+
194+ :param local_packages: The packages to add.
195+ :type local_packages: list
196+ """
197+ logger.debug("Adding packages to hwpack")
198+ self.hwpack.add_packages(self.packages)
199+ for local_package in local_packages:
200+ if local_package not in self.packages:
201+ logger.warning("Local package '%s' not included",
202+ local_package.name)
203+ self.hwpack.add_dependency_package(self.config.packages)
204+
205+ def _extract_build_info(self, cache_dir, out_name, manifest_name):
206+ """Extracts build-info from the packages.
207+
208+ :param cache_dir: The cache directory where build-info should be
209+ located.
210+ :type cache_dir: str
211+ :param out_name: The name of the hwpack file.
212+ :type out_name: str
213+ :param manifest_name: The name of the manifest file.
214+ :type manifest_name: str
215+ """
216+ logger.debug("Extracting build-info")
217+ build_info_dir = os.path.join(cache_dir, 'build-info')
218+ build_info_available = 0
219+ for deb_pkg in self.packages:
220+ deb_pkg_file_path = deb_pkg.filepath
221+ if os.path.islink(deb_pkg_file_path):
222+ # Skip symlink-ed debian package file
223+ # e.g. fetched package with dummy information
224+ continue
225+ try:
226+ # Extract Build-Info attribute from debian control
227+ deb_control = DebFile(deb_pkg_file_path).control.debcontrol()
228+ build_info = deb_control.get('Build-Info')
229+ except ArError:
230+ # Skip invalid debian package file
231+ # e.g. fetched package with dummy information
232+ continue
233+ if build_info is not None:
234+ build_info_available += 1
235+ # Extract debian packages with build information
236+ env = os.environ
237+ env['LC_ALL'] = 'C'
238+ env['NO_PKG_MANGLE'] = '1'
239+ proc = cmd_runner.Popen(['dpkg-deb', '-x',
240+ deb_pkg_file_path, build_info_dir],
241+ env=env, stdout=subprocess.PIPE,
242+ stderr=subprocess.PIPE)
243+
244+ (stdoutdata, stderrdata) = proc.communicate()
245+ if proc.returncode:
246+ raise ValueError('dpkg-deb extract failed!\n%s' %
247+ stderrdata)
248+ if stderrdata:
249+ raise ValueError('dpkg-deb extract had warnings:\n%s' %
250+ stderrdata)
251+
252+ self._concatenate_build_info(build_info_available, build_info_dir,
253+ out_name, manifest_name)
254+
255+ def _concatenate_build_info(self, build_info_available, build_info_dir,
256+ out_name, manifest_name):
257+ """Concatenates the build-info text if more than one is available.
258+
259+ :param build_info_available: The number of available build-info.
260+ :type build_info_available: int
261+ :param build_info_dir: Where build-info files should be.
262+ :type build_info_dir: str
263+ :param out_name: The name of the hwpack file.
264+ :type out_name: str
265+ :param manifest_name: The name of the manifest file.
266+ :type manifest_name: str
267+ """
268+ logger.debug("Concatenating build-info files")
269+ dst_file = open('BUILD-INFO.txt', 'wb')
270+ if build_info_available > 0:
271+ build_info_path = (r'%s/usr/share/doc/*/BUILD-INFO.txt' %
272+ build_info_dir)
273+ for src_file in iglob(build_info_path):
274+ with open(src_file, 'rb') as f:
275+ dst_file.write('\nFiles-Pattern: %s\n' % out_name)
276+ shutil.copyfileobj(f, dst_file)
277+ dst_file.write('\nFiles-Pattern: %s\nLicense-Type: open\n' %
278+ manifest_name)
279+ else:
280+ dst_file.write('Format-Version: 0.1\n'
281+ 'Files-Pattern: %s, %s\n'
282+ 'License-Type: open\n' % (out_name, manifest_name))
283+ dst_file.close()

Subscribers

People subscribed via source and target branches