Clone of official tools
Diff: utils.py
- Revision:
- 43:2a7da56ebd24
- Parent:
- 36:96847d42f010
--- a/utils.py Mon Nov 06 13:17:14 2017 -0600 +++ b/utils.py Tue Sep 25 13:43:09 2018 -0500 @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. """ +from __future__ import print_function, division, absolute_import import sys import inspect import os @@ -30,6 +31,11 @@ import logging from intelhex import IntelHex +try: + unicode +except NameError: + unicode = str + def remove_if_in(lst, thing): if thing in lst: lst.remove(thing) @@ -66,14 +72,14 @@ """A wrapper to run a command as a blocking job""" text = command if shell else ' '.join(command) if verbose: - print text + print(text) return_code = call(command, shell=shell, cwd=cwd) if check and return_code != 0: raise Exception('ERROR %d: "%s"' % (return_code, text)) def run_cmd(command, work_dir=None, chroot=None, redirect=False): - """Run a command in the forground + """Run a command in the foreground Positional arguments: command - the command to run @@ -100,7 +106,7 @@ stderr=STDOUT if redirect else PIPE, cwd=work_dir) _stdout, _stderr = process.communicate() except OSError: - print "[OS ERROR] Command: "+(' '.join(command)) + print("[OS ERROR] Command: "+(' '.join(command))) raise return _stdout, _stderr, process.returncode @@ -173,6 +179,27 @@ makedirs(path) +def write_json_to_file(json_data, file_name): + """ + Write json content in file + :param json_data: + :param file_name: + :return: + """ + # Create the target dir for file if necessary + test_spec_dir = os.path.dirname(file_name) + + if test_spec_dir: + mkdir(test_spec_dir) + + try: + with open(file_name, 'w') as f: + f.write(json.dumps(json_data, indent=2)) + except IOError as e: + print("[ERROR] Error writing test spec to file") + print(e) + + def copy_file(src, dst): """ Implement the behaviour of "shutil.copy(src, dst)" without copying the permissions (this was causing errors with directories mounted with samba) @@ -199,7 +226,7 @@ for element in listdir(directory): to_remove = join(directory, element) if not isdir(to_remove): - remove(file) + remove(to_remove) def get_caller_name(steps=2): @@ -318,38 +345,19 @@ except ImportError as exc: not_installed_modules.append(module_name) if verbose: - print "Error: %s" % exc + print("Error: %s" % exc) if verbose: if not_installed_modules: - print ("Warning: Module(s) %s not installed. Please install " + \ - "required module(s) before using this script.")\ - % (', '.join(not_installed_modules)) + print("Warning: Module(s) %s not installed. Please install " + "required module(s) before using this script." + % (', '.join(not_installed_modules))) if not_installed_modules: return False else: return True -def dict_to_ascii(dictionary): - """ Utility function: traverse a dictionary and change all the strings in - the dictionary to ASCII from Unicode. Useful when reading ASCII JSON data, - because the JSON decoder always returns Unicode string. Based on - http://stackoverflow.com/a/13105359 - - Positional arguments: - dictionary - The dict that contains some Unicode that should be ASCII - """ - if isinstance(dictionary, dict): - return OrderedDict([(dict_to_ascii(key), dict_to_ascii(value)) - for key, value in dictionary.iteritems()]) - elif isinstance(dictionary, list): - return [dict_to_ascii(element) for element in dictionary] - elif isinstance(dictionary, unicode): - return dictionary.encode('ascii') - else: - return dictionary - def json_file_to_dict(fname): """ Read a JSON file and return its Python representation, transforming all the strings from Unicode to ASCII. The order of keys in the JSON file is @@ -360,8 +368,8 @@ """ try: with open(fname, "r") as file_obj: - return dict_to_ascii(json.load(file_obj, - object_pairs_hook=OrderedDict)) + return json.loads(file_obj.read().encode('ascii', 'ignore'), + object_pairs_hook=OrderedDict) except (ValueError, IOError): sys.stderr.write("Error parsing '%s':\n" % fname) raise @@ -375,6 +383,8 @@ the string, or the hyphens/underscores do not match the expected style of the argument. """ + if not isinstance(string, unicode): + string = string.decode() if prefer_hyphen: newstring = casedness(string).replace("_", "-") else: @@ -393,10 +403,10 @@ return middle # short cuts for the argparse_type versions -argparse_uppercase_type = argparse_type(str.upper, False) -argparse_lowercase_type = argparse_type(str.lower, False) -argparse_uppercase_hyphen_type = argparse_type(str.upper, True) -argparse_lowercase_hyphen_type = argparse_type(str.lower, True) +argparse_uppercase_type = argparse_type(unicode.upper, False) +argparse_lowercase_type = argparse_type(unicode.lower, False) +argparse_uppercase_hyphen_type = argparse_type(unicode.upper, True) +argparse_lowercase_hyphen_type = argparse_type(unicode.lower, True) def argparse_force_type(case): """ validate that an argument passed in (as string) is a member of the list @@ -404,8 +414,12 @@ """ def middle(lst, type_name): """ The parser type generator""" + if not isinstance(lst[0], unicode): + lst = [o.decode() for o in lst] def parse_type(string): """ The parser type""" + if not isinstance(string, unicode): + string = string.decode() for option in lst: if case(string) == case(option): return option @@ -416,8 +430,8 @@ return middle # these two types convert the case of their arguments _before_ validation -argparse_force_uppercase_type = argparse_force_type(str.upper) -argparse_force_lowercase_type = argparse_force_type(str.lower) +argparse_force_uppercase_type = argparse_force_type(unicode.upper) +argparse_force_lowercase_type = argparse_force_type(unicode.lower) def argparse_many(func): """ An argument parser combinator that takes in an argument parser and @@ -529,3 +543,11 @@ raise ToolException("File %s does not have a known binary file type" % filename) return ih + + +def integer(maybe_string, base): + """Make an integer of a number or a string""" + if isinstance(maybe_string, int): + return maybe_string + else: + return int(maybe_string, base)