1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-03 17:52:07 +02:00

patman: Adjust 'command' to return strings instead of bytes

At present all the 'command' methods return bytes. Most of the time we
actually want strings, so change this. We still need to keep the internal
representation as bytes since otherwise unicode strings might break over
a read() boundary (e.g. 4KB), causing errors. But we can convert the end
result to strings.

Add a 'binary' parameter to cover the few cases where bytes are needed.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2019-10-31 07:42:50 -06:00
parent f0921f5098
commit 3b3e3c0f6c
4 changed files with 46 additions and 18 deletions

View File

@@ -56,7 +56,7 @@ class TestCbfs(unittest.TestCase):
cls.have_lz4 = True cls.have_lz4 = True
try: try:
tools.Run('lz4', '--no-frame-crc', '-c', tools.Run('lz4', '--no-frame-crc', '-c',
tools.GetInputFilename('u-boot.bin')) tools.GetInputFilename('u-boot.bin'), binary=True)
except: except:
cls.have_lz4 = False cls.have_lz4 = False

View File

@@ -174,7 +174,7 @@ class TestFunctional(unittest.TestCase):
cls.have_lz4 = True cls.have_lz4 = True
try: try:
tools.Run('lz4', '--no-frame-crc', '-c', tools.Run('lz4', '--no-frame-crc', '-c',
os.path.join(cls._indir, 'u-boot.bin')) os.path.join(cls._indir, 'u-boot.bin'), binary=True)
except: except:
cls.have_lz4 = False cls.have_lz4 = False

View File

@@ -4,6 +4,7 @@
import os import os
import cros_subprocess import cros_subprocess
import tools
"""Shell command ease-ups for Python.""" """Shell command ease-ups for Python."""
@@ -31,6 +32,13 @@ class CommandResult:
self.return_code = return_code self.return_code = return_code
self.exception = exception self.exception = exception
def ToOutput(self, binary):
if not binary:
self.stdout = tools.ToString(self.stdout)
self.stderr = tools.ToString(self.stderr)
self.combined = tools.ToString(self.combined)
return self
# This permits interception of RunPipe for test purposes. If it is set to # This permits interception of RunPipe for test purposes. If it is set to
# a function, then that function is called with the pipe list being # a function, then that function is called with the pipe list being
@@ -41,7 +49,7 @@ test_result = None
def RunPipe(pipe_list, infile=None, outfile=None, def RunPipe(pipe_list, infile=None, outfile=None,
capture=False, capture_stderr=False, oneline=False, capture=False, capture_stderr=False, oneline=False,
raise_on_error=True, cwd=None, **kwargs): raise_on_error=True, cwd=None, binary=False, **kwargs):
""" """
Perform a command pipeline, with optional input/output filenames. Perform a command pipeline, with optional input/output filenames.
@@ -67,7 +75,7 @@ def RunPipe(pipe_list, infile=None, outfile=None,
else: else:
return test_result return test_result
# No result: fall through to normal processing # No result: fall through to normal processing
result = CommandResult() result = CommandResult(b'', b'', b'')
last_pipe = None last_pipe = None
pipeline = list(pipe_list) pipeline = list(pipe_list)
user_pipestr = '|'.join([' '.join(pipe) for pipe in pipe_list]) user_pipestr = '|'.join([' '.join(pipe) for pipe in pipe_list])
@@ -93,29 +101,36 @@ def RunPipe(pipe_list, infile=None, outfile=None,
if raise_on_error: if raise_on_error:
raise Exception("Error running '%s': %s" % (user_pipestr, str)) raise Exception("Error running '%s': %s" % (user_pipestr, str))
result.return_code = 255 result.return_code = 255
return result return result.ToOutput(binary)
if capture: if capture:
result.stdout, result.stderr, result.combined = ( result.stdout, result.stderr, result.combined = (
last_pipe.CommunicateFilter(None)) last_pipe.CommunicateFilter(None))
if result.stdout and oneline: if result.stdout and oneline:
result.output = result.stdout.rstrip('\r\n') result.output = result.stdout.rstrip(b'\r\n')
result.return_code = last_pipe.wait() result.return_code = last_pipe.wait()
else: else:
result.return_code = os.waitpid(last_pipe.pid, 0)[1] result.return_code = os.waitpid(last_pipe.pid, 0)[1]
if raise_on_error and result.return_code: if raise_on_error and result.return_code:
raise Exception("Error running '%s'" % user_pipestr) raise Exception("Error running '%s'" % user_pipestr)
return result return result.ToOutput(binary)
def Output(*cmd, **kwargs): def Output(*cmd, **kwargs):
kwargs['raise_on_error'] = kwargs.get('raise_on_error', True) kwargs['raise_on_error'] = kwargs.get('raise_on_error', True)
return RunPipe([cmd], capture=True, **kwargs).stdout return RunPipe([cmd], capture=True, **kwargs).stdout
def OutputOneLine(*cmd, **kwargs): def OutputOneLine(*cmd, **kwargs):
"""Run a command and output it as a single-line string
The command us expected to produce a single line of output
Returns:
String containing output of command
"""
raise_on_error = kwargs.pop('raise_on_error', True) raise_on_error = kwargs.pop('raise_on_error', True)
return (RunPipe([cmd], capture=True, oneline=True, result = RunPipe([cmd], capture=True, oneline=True,
raise_on_error=raise_on_error, raise_on_error=raise_on_error, **kwargs).stdout.strip()
**kwargs).stdout.strip()) return result
def Run(*cmd, **kwargs): def Run(*cmd, **kwargs):
return RunPipe([cmd], **kwargs).stdout return RunPipe([cmd], **kwargs).stdout

View File

@@ -186,7 +186,7 @@ def PathHasFile(path_spec, fname):
return True return True
return False return False
def Run(name, *args): def Run(name, *args, **kwargs):
"""Run a tool with some arguments """Run a tool with some arguments
This runs a 'tool', which is a program used by binman to process files and This runs a 'tool', which is a program used by binman to process files and
@@ -201,13 +201,14 @@ def Run(name, *args):
CommandResult object CommandResult object
""" """
try: try:
binary = kwargs.get('binary')
env = None env = None
if tool_search_paths: if tool_search_paths:
env = dict(os.environ) env = dict(os.environ)
env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH'] env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH']
all_args = (name,) + args all_args = (name,) + args
result = command.RunPipe([all_args], capture=True, capture_stderr=True, result = command.RunPipe([all_args], capture=True, capture_stderr=True,
env=env, raise_on_error=False) env=env, raise_on_error=False, binary=binary)
if result.return_code: if result.return_code:
raise Exception("Error %d running '%s': %s" % raise Exception("Error %d running '%s': %s" %
(result.return_code,' '.join(all_args), (result.return_code,' '.join(all_args),
@@ -375,7 +376,7 @@ def ToBytes(string):
"""Convert a str type into a bytes type """Convert a str type into a bytes type
Args: Args:
string: string to convert value string: string to convert
Returns: Returns:
Python 3: A bytes type Python 3: A bytes type
@@ -385,6 +386,18 @@ def ToBytes(string):
return string.encode('utf-8') return string.encode('utf-8')
return string return string
def ToString(bval):
"""Convert a bytes type into a str type
Args:
bval: bytes value to convert
Returns:
Python 3: A bytes type
Python 2: A string type
"""
return bval.decode('utf-8')
def Compress(indata, algo, with_header=True): def Compress(indata, algo, with_header=True):
"""Compress some data using a given algorithm """Compress some data using a given algorithm
@@ -406,14 +419,14 @@ def Compress(indata, algo, with_header=True):
fname = GetOutputFilename('%s.comp.tmp' % algo) fname = GetOutputFilename('%s.comp.tmp' % algo)
WriteFile(fname, indata) WriteFile(fname, indata)
if algo == 'lz4': if algo == 'lz4':
data = Run('lz4', '--no-frame-crc', '-c', fname) data = Run('lz4', '--no-frame-crc', '-c', fname, binary=True)
# cbfstool uses a very old version of lzma # cbfstool uses a very old version of lzma
elif algo == 'lzma': elif algo == 'lzma':
outfname = GetOutputFilename('%s.comp.otmp' % algo) outfname = GetOutputFilename('%s.comp.otmp' % algo)
Run('lzma_alone', 'e', fname, outfname, '-lc1', '-lp0', '-pb0', '-d8') Run('lzma_alone', 'e', fname, outfname, '-lc1', '-lp0', '-pb0', '-d8')
data = ReadFile(outfname) data = ReadFile(outfname)
elif algo == 'gzip': elif algo == 'gzip':
data = Run('gzip', '-c', fname) data = Run('gzip', '-c', fname, binary=True)
else: else:
raise ValueError("Unknown algorithm '%s'" % algo) raise ValueError("Unknown algorithm '%s'" % algo)
if with_header: if with_header:
@@ -446,13 +459,13 @@ def Decompress(indata, algo, with_header=True):
with open(fname, 'wb') as fd: with open(fname, 'wb') as fd:
fd.write(indata) fd.write(indata)
if algo == 'lz4': if algo == 'lz4':
data = Run('lz4', '-dc', fname) data = Run('lz4', '-dc', fname, binary=True)
elif algo == 'lzma': elif algo == 'lzma':
outfname = GetOutputFilename('%s.decomp.otmp' % algo) outfname = GetOutputFilename('%s.decomp.otmp' % algo)
Run('lzma_alone', 'd', fname, outfname) Run('lzma_alone', 'd', fname, outfname)
data = ReadFile(outfname) data = ReadFile(outfname, binary=True)
elif algo == 'gzip': elif algo == 'gzip':
data = Run('gzip', '-cd', fname) data = Run('gzip', '-cd', fname, binary=True)
else: else:
raise ValueError("Unknown algorithm '%s'" % algo) raise ValueError("Unknown algorithm '%s'" % algo)
return data return data