[Test] Update touch_firmware_versions script.
Check in my local changes. This includes:
- Handle reef-specific changes.
- Refactor code to use a firmwareInfo class, instead of just printing.
- Minor regex improvements, including allowing .hex filenames.
- Clean up a few logic errors that don't cause trouble with existing
ebuilds but could in the future.
BUG=None
TEST=result output does not change (except sorted and has reef changes)
Change-Id: Ib089b891ab13e8a5effc5071551daeee4924c8a5
Reviewed-on: https://chromium-review.googlesource.com/617511
Commit-Ready: Katherine Threlkeld <kathrelkeld@chromium.org>
Tested-by: Katherine Threlkeld <kathrelkeld@chromium.org>
Reviewed-by: Vinayak Suley <vsuley@chromium.org>
diff --git a/provingground/touch_firmware_versions.py b/provingground/touch_firmware_versions.py
index b91bc49..9c2d546 100755
--- a/provingground/touch_firmware_versions.py
+++ b/provingground/touch_firmware_versions.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/env python2
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -29,10 +29,28 @@
SRC_DIR = '../../../' # Relative path from this file to source directory
-def output_values(device, hw_id, fw_version, fw_file, ebuild_file):
- """Formats and prints results for a single type of hardware."""
- print('%s\t%s\t%s\t%s\t%s' % (
- device, hw_id, fw_version, fw_file, ebuild_file))
+class firmwareInfo(object):
+ """Information about a particular firmware file."""
+ def __init__(self, device, path):
+ self.device = device
+ self.ebuild_filepath = path
+
+ self.hw_id = None
+ self.fw_id = None
+ self.fw_file = None
+
+ self.problem_found = False
+ self.error = ''
+
+ def __str__(self):
+ return ('%s\t%s\t%s\t%s\t%s' % (
+ self.device, self.hw_id, self.fw_id, self.fw_file,
+ self.ebuild_filepath))
+
+ def set_ids(self, hwid, fwid, filename):
+ self.hw_id = hwid
+ self.fw_id = fwid
+ self.fw_file = filename
def find_value_of_variable(var, text):
@@ -57,11 +75,10 @@
def reduce_string(link, text):
"""Finds the absolute value of the given string.
- Assumes variables embedded in a string are in ${VAR} format.
+ Assumes variables embedded in a string are in ${VAR} or \s$VAR\s format.
E.g., given '"${PRODUCT_ID_TP}_${FIRMWARE_VERSION_TP}.bin"' return
'"85.0_7.0.bin"', after following all variables.
- Assumes the entire string could be a varible of the form
- $VAR (no { }).
+ Assumes the entire string could be a varible of the form $VAR (no { }).
Args:
link: the string which contains variables to reduce.
@@ -70,35 +87,37 @@
Returns:
The given string with all variables replaced, or '' if error.
"""
- search = re.search(r'\$\{(.*?)\}', link)
- if not search:
- search = re.search(r'\$([^\s]*)', link)
- if not search:
- return link
+ var_formats = [r'\$\{(.*?)\}', r'\$([^\s]*)']
+ for var_format in var_formats:
+ search = re.search(var_format, link)
+ if search:
+ break
+ else:
+ return link
variable = search.group(1)
value = find_value_of_variable(variable, text)
if not value:
return ''
- new_link = link.replace('${%s}' % variable, value)
+
+ # Whatever the variable format ended up being, swap in the value found.
+ variable_format = search.group(0).replace(search.group(1), '%s')
+ new_link = link.replace(variable_format % variable, value)
+
return reduce_string(new_link, text)
-def find_values_from_line(device, line, text):
- """Finds the values to be output for the given dosym line.
+def find_info_from_line(info, line, text):
+ """Finds the info to be output for the given dosym line.
Makes exceptions for known formatting problems.
Args:
- device: the name of the device, e.g., 'squawks'
+ info: the firmwareInfo class for this firmware line. This function will
+ update this object with hardware id, firmware id, and firmware path.
line: the dosym line to evaluate. Passed in the form of a list:
[linked from argument, NA, linked to argument].
text: the text of the ebuild file.
-
- Returns:
- The hardware version, firmware version, and firmware filename.
- A value of None indicates that this entry should be skipped, and a value
- of '' indicates an error.
"""
link_from = reduce_string(line[0], text) # dosym FROM
link_to = reduce_string(line[2], text) # dosym TO
@@ -106,34 +125,32 @@
# Find needed value from the symlink filenames.
hw_id, fw_version, fw_file = '', '', ''
if link_from != '':
- search = re.search(r'/([^/]*)_(.*)\.', link_from)
+ search = re.search(r'([^/"]*)_(.*)\.', link_from)
if search:
hw_id = search.group(1)
fw_version = search.group(2)
if link_to != '':
- search = re.search(r'/([^/]*?)(\.bin|\.fw)?"', link_to)
+ search = re.search(r'/([^/]*?)(\.bin|\.fw|\.hex)?"', link_to)
if search:
fw_file = search.group(1)
+ info.set_ids(hw_id, fw_version, fw_file)
+
# Exceptions for unfortunately formatted files.
- if (device == 'lulu' or device == 'umaro') and fw_file == '':
+ if (info.device == 'lulu' or info.device == 'umaro') and fw_file == '':
bad_fmt = 'SYNA_TP_SYM_LINK_PATH=}'
good_fmt = bad_fmt.replace('=', '')
new_line = list(line)
if bad_fmt in line[2]:
new_line[2] = line[2].replace(bad_fmt, good_fmt)
- hw_id, fw_version, fw_file = find_values_from_line(
- device, new_line, text)
- elif device == 'kip' and link_from.find('dummy') >= 0:
- hw_id = None
- elif (device == 'sumo' and
- link_to and 'fw.bin' not in link_to):
- hw_id = None
-
- return hw_id, fw_version, fw_file
+ find_info_from_line(info, new_line, text)
+ elif info.device == 'kip' and link_from.find('dummy') >= 0:
+ info.hw_id = None
+ elif info.device == 'sumo' and link_to and 'fw.bin' not in link_to:
+ info.hw_id = None
-def find_values_in_file(path):
+def find_firmwares_in_file(path):
"""Finds all dosym lines in the file and outputs values as needed.
If anything went wrong, outputs the devicename for manual inspection.
@@ -141,55 +158,92 @@
Args:
path: the path to the ebuild file.
"""
- device = re.search('overlay-(variant-)?([^/]*?)(-private)?/', path).group(2)
+ def create_error_info(device, path, error):
+ error_values = firmwareInfo(device, path)
+ error_values.problem_found = True
+ error_values.error = error
+ return error_values
+
+ search = re.search('/(overlay-)?(variant-)?(baseboard-)?([^/]*?)(-private)?/',
+ path)
+ if not search:
+ return [create_error_info(
+ path, path, 'Project path did not match expected format!')]
+
+ device = search.group(4)
+
with open(path) as fh:
text = fh.read()
- # Find all symlinks for firmware and config files. Some lines are
- # actually multiline in the file, so use findall to get the entirety.
+ # Special case for unified reef, look for "install_firmware".
+ if device == 'reef':
+ if not re.search('install_fw', text):
+ return [create_error_info(
+ device, path, 'No "install_fw" lines found in this file!')]
+
+ search = re.findall(r'install_fw\s([^\s]*)\s*(\\*\s*\n)?\s*([^\s]*)', text,
+ re.MULTILINE)
+
+ # For all other boards, find all symlinks for firmware and config files.
+ else:
if not re.search('dosym', text):
- return
+ return [create_error_info(
+ device, path, 'No "dosym" lines found in this file!')]
+
search = re.findall(r'dosym\s([^\s]*)\s*(\\*\s*\n)?\s*([^\s]*)', text,
re.MULTILINE)
- if not search:
- return device
+ if not search:
+ return [create_error_info(
+ device, path, 'The dosym lines did not match expected format!')]
- # Each line has the format [from, N/A, to]
- problems_found = False
- for line in search:
- hw_id, fw_version, fw_file = find_values_from_line(device, line, text)
- # None = skip me. '' = problem.
- if hw_id != None:
- if hw_id == '' or fw_version == '' or fw_file == '':
- problems_found = True
- else:
- output_values(device, hw_id, fw_version, fw_file, path)
+ # Each line has the format [from, N/A, to]
+ values_list = []
+ for line in search:
+ values = firmwareInfo(device, path)
+ find_info_from_line(values, line, text)
+ if values.hw_id != None:
+ if values.hw_id == '' or values.fw_id == '' or values.fw_file == '':
+ values.problem_found = True
+ values.error = ('Values did not make sense: %s' % values)
+ values_list.append(values)
- if problems_found:
- return device
+ return values_list
-def main():
- """Finds all touch-firmware files and find their firmware values."""
+
+def firmware_versions():
+ """Finds all touch-firmware files and their firmware values."""
file_dir = os.path.realpath(os.path.dirname(__file__))
src_dir = os.path.join(file_dir, SRC_DIR)
os.chdir(src_dir)
+
+ # Find ebuild files, e.g. chromeos-touch-firmware-caroline-0.0.1.ebuild
find_output = ''
- cmd = 'find %s -name *touch-firmware-*-0.0.[0-9].ebuild'
+ cmd = 'find %s -regex .*touch-firmware-.*-[0-9]+\.[0-9]+\.[0-9]+\.ebuild'
for d in ['private-overlays/', 'overlays/']:
find_output += subprocess.check_output((cmd % d).split(' '))
ebuilds = find_output.split()
ebuilds.sort()
- # Find and output values.
- problem_devices = []
+ values_list = []
for path in ebuilds:
- err = find_values_in_file(path)
- if err:
- problem_devices.append(err)
+ values_list += find_firmwares_in_file(path)
+
+ values_list.sort(key=lambda x: x.device)
+ return values_list
+
+def main():
+ values_list = firmware_versions()
+ problem_devices = {}
+ for values in values_list:
+ if values.problem_found:
+ problem_devices[values.device] = values.error
+ else:
+ print(values)
# Output any problematic devices found, if any.
if len(problem_devices) > 0:
print('ERROR: please review %s' % problem_devices)
+
if __name__ == '__main__':
main()