@@ -38,10 +38,14 @@ def __init__(self, message):
3838 super ().__init__ (message )
3939
4040###############################################################################
41- def call_command (commands , logger , silent = False ):
41+ def call_command (commands , logger , silent = False , return_proc = False ):
4242###############################################################################
4343 """
44- Try a command line and return the output on success (None on failure)
44+ Try a command line and return True only for a zero return code
45+ If silent==True, do not log output and simply return False on an exception
46+ If return_proc==True, return the CompletedProcess instance instead of a boolean
47+ If silent==True and return_proc==True, return None in the case of an exception
48+
4549 >>> _LOGGER = init_log('xml_tools')
4650 >>> set_log_to_null(_LOGGER)
4751 >>> call_command(['ls', 'really__improbable_fffilename.foo'], _LOGGER) #doctest: +IGNORE_EXCEPTION_DETAIL
@@ -50,6 +54,8 @@ def call_command(commands, logger, silent=False):
5054 [Errno 2] No such file or directory
5155 >>> call_command(['ls', 'really__improbable_fffilename.foo'], _LOGGER, silent=True)
5256 False
57+ >>> call_command(['ls'], _LOGGER, silent=True, return_proc=True).returncode
58+ 0
5359 >>> call_command(['ls'], _LOGGER)
5460 True
5561 >>> try:
@@ -75,11 +81,22 @@ def call_command(commands, logger, silent=False):
7581 capture_output = True )
7682 if not silent :
7783 logger .debug (cproc .stdout )
84+ if cproc .stderr :
85+ logger .warning (cproc .stderr )
86+ # end if
87+ # end if
88+ if return_proc :
89+ result = cproc
90+ else :
91+ result = cproc .returncode == 0
7892 # end if
79- result = cproc .returncode == 0
8093 except (OSError , CCPPError , subprocess .CalledProcessError ) as err :
8194 if silent :
82- result = False
95+ if return_proc :
96+ result = None
97+ else :
98+ result = False
99+ # end if
83100 else :
84101 cmd = ' ' .join (commands )
85102 outstr = f"Execution of '{ cmd } ' failed with code: { err .returncode } \n "
@@ -213,7 +230,15 @@ def validate_xml_file(filename, schema_root, version, logger,
213230 logger .debug ("Checking file {} against schema {}" .format (filename ,
214231 schema_file ))
215232 cmd = [_XMLLINT , '--noout' , '--schema' , schema_file , filename ]
216- result = call_command (cmd , logger )
233+ result = call_command (cmd , logger , return_proc = True )
234+ if result .returncode == 0 :
235+ ## We got a pass return code but some versions of xmllint do not
236+ ## correctly return an error code on non-validation so double check
237+ ## the result
238+ result = b'validates' in result .stdout or b'validates' in result .stderr
239+ else :
240+ result = True
241+ # end if
217242 return result
218243 # end if
219244 lmsg = "xmllint not found, could not validate file {}"
@@ -411,11 +436,14 @@ def replace_nested_suite(element, nested_suite, default_path, logger):
411436 suite_name = nested_suite .attrib .get ("name" )
412437 group_name = nested_suite .attrib .get ("group" )
413438 file = nested_suite .attrib .get ("file" )
439+ if not file :
440+ raise CCPPError ("file attribute required for nested_suite tag" )
441+ # end if
414442 if not os .path .isabs (file ):
415443 file = os .path .join (default_path , file )
416444 referenced_suite = load_suite_by_name (suite_name , group_name , file ,
417445 logger = logger )
418- imported_content = [ET .fromstring (ET .tostring (child ))
446+ imported_content = [ET .fromstring (ET .tostring (child ))
419447 for child in referenced_suite ]
420448 # Swap nested suite with imported content
421449 for item in imported_content :
@@ -581,7 +609,7 @@ def expand_nested_suites(suite, default_path, logger=None):
581609 return
582610 raise CCPPError ("Exceeded number of iterations while expanding nested suites:" + \
583611 "check for inifite recursion or adjust limit max_iterations" )
584-
612+
585613###############################################################################
586614def write_xml_file (root , file_path , logger = None ):
587615###############################################################################
@@ -598,7 +626,7 @@ def remove_whitespace_nodes(node):
598626
599627 # Convert ElementTree to a byte string
600628 byte_string = ET .tostring (root , 'us-ascii' )
601-
629+
602630 # Parse string using minidom for pretty printing
603631 reparsed = xml .dom .minidom .parseString (byte_string )
604632
0 commit comments