From 512f4550d29547819ef41c7aa39689dafde5afef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:23 -0600 Subject: tools: Drop duplicate raise_on_error argument If kwargs contains raise_on_error then this function generates an error due to a duplicate argument. Fix this. Signed-off-by: Simon Glass --- tools/patman/command.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/patman') diff --git a/tools/patman/command.py b/tools/patman/command.py index 14edcdaffd..16299f3f5b 100644 --- a/tools/patman/command.py +++ b/tools/patman/command.py @@ -108,8 +108,8 @@ def RunPipe(pipe_list, infile=None, outfile=None, return result def Output(*cmd, **kwargs): - raise_on_error = kwargs.get('raise_on_error', True) - return RunPipe([cmd], capture=True, raise_on_error=raise_on_error).stdout + kwargs['raise_on_error'] = kwargs.get('raise_on_error', True) + return RunPipe([cmd], capture=True, **kwargs).stdout def OutputOneLine(*cmd, **kwargs): raise_on_error = kwargs.pop('raise_on_error', True) -- cgit From c22b8cfc1dc6a8fd9e45dd56b2945ccf979aa2c8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:27 -0600 Subject: patman: Add a way to set the search path for tools Sometimes tools can be located by looking in other locations. Add a way to direct the search. Signed-off-by: Simon Glass --- tools/patman/tools.py | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'tools/patman') diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 8e9f22afe8..0b3049f91f 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -24,6 +24,8 @@ chroot_path = None # Search paths to use for Filename(), used to find files search_paths = [] +tool_search_paths = [] + # Tools and the packages that contain them, on debian packages = { 'lz4': 'liblz4-tool', @@ -154,26 +156,56 @@ def Align(pos, align): def NotPowerOfTwo(num): return num and (num & (num - 1)) -def PathHasFile(fname): +def SetToolPaths(toolpaths): + """Set the path to search for tools + + Args: + toolpaths: List of paths to search for tools executed by Run() + """ + global tool_search_paths + + tool_search_paths = toolpaths + +def PathHasFile(path_spec, fname): """Check if a given filename is in the PATH Args: + path_spec: Value of PATH variable to check fname: Filename to check Returns: True if found, False if not """ - for dir in os.environ['PATH'].split(':'): + for dir in path_spec.split(':'): if os.path.exists(os.path.join(dir, fname)): return True return False def Run(name, *args, **kwargs): + """Run a tool with some arguments + + This runs a 'tool', which is a program used by binman to process files and + perhaps produce some output. Tools can be located on the PATH or in a + search path. + + Args: + name: Command name to run + args: Arguments to the tool + kwargs: Options to pass to command.run() + + Returns: + CommandResult object + """ try: - return command.Run(name, *args, cwd=outdir, capture=True, **kwargs) + env = None + if tool_search_paths: + env = dict(os.environ) + env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH'] + return command.Run(name, *args, capture=True, + capture_stderr=True, env=env, **kwargs) except: - if not PathHasFile(name): - msg = "Plesae install tool '%s'" % name + if env and not PathHasFile(env['PATH'], name): + msg = "Please install tool '%s'" % name package = packages.get(name) if package: msg += " (e.g. from package '%s')" % package -- cgit From 07d9e70bf9a65f3c94573b9e11f12025b472cff1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:41 -0600 Subject: patman: Add functions to compress and decompress data Add utility functions to compress and decompress using lz4 and lzma algorithms. In the latter case these use the legacy lzma support favoured by coreboot's CBFS. No tests are provided as these functions will be tested by the CBFS tests in a separate patch. Signed-off-by: Simon Glass --- tools/patman/tools.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'tools/patman') diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 0b3049f91f..69d03d3860 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -374,3 +374,69 @@ def ToBytes(string): if sys.version_info[0] >= 3: return string.encode('utf-8') return string + +def Compress(indata, algo): + """Compress some data using a given algorithm + + Note that for lzma this uses an old version of the algorithm, not that + provided by xz. + + This requires 'lz4' and 'lzma_alone' tools. It also requires an output + directory to be previously set up, by calling PrepareOutputDir(). + + Args: + indata: Input data to compress + algo: Algorithm to use ('none', 'gzip', 'lz4' or 'lzma') + + Returns: + Compressed data + """ + if algo == 'none': + return indata + fname = GetOutputFilename('%s.comp.tmp' % algo) + WriteFile(fname, indata) + if algo == 'lz4': + data = Run('lz4', '--no-frame-crc', '-c', fname, binary=True) + # cbfstool uses a very old version of lzma + elif algo == 'lzma': + outfname = GetOutputFilename('%s.comp.otmp' % algo) + Run('lzma_alone', 'e', fname, outfname, '-lc1', '-lp0', '-pb0', '-d8') + data = ReadFile(outfname) + elif algo == 'gzip': + data = Run('gzip', '-c', fname, binary=True) + else: + raise ValueError("Unknown algorithm '%s'" % algo) + return data + +def Decompress(indata, algo): + """Decompress some data using a given algorithm + + Note that for lzma this uses an old version of the algorithm, not that + provided by xz. + + This requires 'lz4' and 'lzma_alone' tools. It also requires an output + directory to be previously set up, by calling PrepareOutputDir(). + + Args: + indata: Input data to decompress + algo: Algorithm to use ('none', 'gzip', 'lz4' or 'lzma') + + Returns: + Compressed data + """ + if algo == 'none': + return indata + fname = GetOutputFilename('%s.decomp.tmp' % algo) + with open(fname, 'wb') as fd: + fd.write(indata) + if algo == 'lz4': + data = Run('lz4', '-dc', fname, binary=True) + elif algo == 'lzma': + outfname = GetOutputFilename('%s.decomp.otmp' % algo) + Run('lzma_alone', 'd', fname, outfname) + data = ReadFile(outfname) + elif algo == 'gzip': + data = Run('gzip', '-cd', fname, binary=True) + else: + raise ValueError("Unknown algorithm '%s'" % algo) + return data -- cgit From 1cfdfc064a190529c988065e867a6569cdc3c168 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 13:18:51 -0600 Subject: patman: Add a function to write ifwitool This tool has quite a few arguments and options, so put the functionality in a function so that we call it from one place and hopefully get it right. Signed-off-by: Simon Glass --- tools/patman/tools.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'tools/patman') diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 69d03d3860..e945b54fa2 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -3,6 +3,8 @@ # Copyright (c) 2016 Google, Inc # +from __future__ import print_function + import command import glob import os @@ -440,3 +442,34 @@ def Decompress(indata, algo): else: raise ValueError("Unknown algorithm '%s'" % algo) return data + +CMD_CREATE, CMD_DELETE, CMD_ADD, CMD_REPLACE, CMD_EXTRACT = range(5) + +IFWITOOL_CMDS = { + CMD_CREATE: 'create', + CMD_DELETE: 'delete', + CMD_ADD: 'add', + CMD_REPLACE: 'replace', + CMD_EXTRACT: 'extract', + } + +def RunIfwiTool(ifwi_file, cmd, fname=None, subpart=None, entry_name=None): + """Run ifwitool with the given arguments: + + Args: + ifwi_file: IFWI file to operation on + cmd: Command to execute (CMD_...) + fname: Filename of file to add/replace/extract/create (None for + CMD_DELETE) + subpart: Name of sub-partition to operation on (None for CMD_CREATE) + entry_name: Name of directory entry to operate on, or None if none + """ + args = ['ifwitool', ifwi_file] + args.append(IFWITOOL_CMDS[cmd]) + if fname: + args += ['-f', fname] + if subpart: + args += ['-n', subpart] + if entry_name: + args += ['-d', '-e', entry_name] + Run(*args) -- cgit From 53cd5d921dd76d4651f2c99681a3c050743b6ba1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 14:25:29 -0600 Subject: binman: Convert to use ArgumentParser This class is the new way to handle arguments in Python. Convert binman over to use it. At the same time, introduce commands so that we can separate out the different parts of binman functionality. Signed-off-by: Simon Glass --- tools/patman/test_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/patman') diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index ea36cd1633..40098159c0 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -46,9 +46,10 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): glob_list = [] glob_list += exclude_list glob_list += ['*libfdt.py', '*site-packages*', '*dist-packages*'] + test_cmd = 'test' if 'binman.py' in prog else '-t' cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools %s-coverage run ' - '--omit "%s" %s -P1 -t' % (build_dir, PYTHON, ','.join(glob_list), - prog)) + '--omit "%s" %s %s -P1' % (build_dir, PYTHON, ','.join(glob_list), + prog, test_cmd)) os.system(cmd) stdout = command.Output('%s-coverage' % PYTHON, 'report') lines = stdout.splitlines() -- cgit From e430440232e455c0b670a3f5647fbab649e34f4b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 14:25:32 -0600 Subject: binman: Allow easy importing of entry modules At present entry modules can only be accessed using Entry.Lookup() or Entry.Create(). Most of the time this is fine, but sometimes a module needs to provide constants or helper functions useful to other modules. It is easier in this case to use 'import'. Add an __init__ file to permit this. Signed-off-by: Simon Glass --- tools/patman/test_util.py | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/patman') diff --git a/tools/patman/test_util.py b/tools/patman/test_util.py index 40098159c0..09f258c26b 100644 --- a/tools/patman/test_util.py +++ b/tools/patman/test_util.py @@ -58,6 +58,7 @@ def RunTestCoverage(prog, filter_fname, exclude_list, build_dir, required=None): test_set = set([os.path.splitext(os.path.basename(line.split()[0]))[0] for line in lines if '/etype/' in line]) missing_list = required + missing_list.discard('__init__') missing_list.difference_update(test_set) if missing_list: print('Missing tests for %s' % (', '.join(missing_list))) -- cgit From eea264ead3ca198ed66f62a78dc4940075621ae7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 14:25:49 -0600 Subject: binman: Allow for logging information to be displayed Binman generally operates silently but in some cases it is useful to see what Binman is actually doing at each step. Enable some logging output with different logging levels selectable via the -v flag. Signed-off-by: Simon Glass --- tools/patman/tout.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'tools/patman') diff --git a/tools/patman/tout.py b/tools/patman/tout.py index 4957c7ae1d..15acce28cb 100644 --- a/tools/patman/tout.py +++ b/tools/patman/tout.py @@ -131,13 +131,21 @@ def Info(msg): """ _Output(3, msg) +def Detail(msg): + """Display a detailed message + + Args: + msg; Message to display. + """ + _Output(4, msg) + def Debug(msg): """Display a debug message Args: msg; Message to display. """ - _Output(4, msg) + _Output(5, msg) def UserOutput(msg): """Display a message regardless of the current output level. -- cgit