Alessandro Angelino / mbed-tools

Fork of mbed-tools by Morpheus

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers utils.py Source File

utils.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2013 ARM Limited
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009     http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 """
00017 import sys
00018 import inspect
00019 import os
00020 from os import listdir, remove, makedirs
00021 from shutil import copyfile
00022 from os.path import isdir, join, exists, split, relpath, splitext
00023 from subprocess import Popen, PIPE, STDOUT, call
00024 
00025 
00026 def cmd(l, check=True, verbose=False, shell=False, cwd=None):
00027     text = l if shell else ' '.join(l)
00028     if verbose:
00029         print text
00030     rc = call(l, shell=shell, cwd=cwd)
00031     if check and rc != 0:
00032         raise Exception('ERROR %d: "%s"' % (rc, text))
00033 
00034 
00035 def run_cmd(command, wd=None, redirect=False):
00036     assert is_cmd_valid(command[0])
00037     p = Popen(command, stdout=PIPE, stderr=STDOUT if redirect else PIPE, cwd=wd)
00038     _stdout, _stderr = p.communicate()
00039     return _stdout, _stderr, p.returncode
00040 
00041 
00042 def run_cmd_ext(command):
00043     assert is_cmd_valid(command[0])
00044     p = Popen(command, stdout=PIPE, stderr=PIPE)
00045     _stdout, _stderr = p.communicate()
00046     return _stdout, _stderr, p.returncode
00047 
00048 
00049 def is_cmd_valid(cmd):
00050     caller = get_caller_name()
00051     abspath = find_cmd_abspath(cmd)
00052     if not abspath:
00053         error("%s: Command '%s' can't be found" % (caller, cmd))
00054     if not is_exec(abspath):
00055         error("%s: Command '%s' resolves to file '%s' which is not executable" % (caller, cmd, abspath))
00056     return True
00057 
00058 
00059 def is_exec(path):
00060     return os.access(path, os.X_OK) or os.access(path+'.exe', os.X_OK)
00061 
00062 
00063 def find_cmd_abspath (cmd):
00064     """ Returns the absolute path to a command.
00065         None is returned if no absolute path was found.
00066     """
00067     if exists(cmd) or exists(cmd + '.exe'):
00068         return os.path.abspath(cmd)
00069     if not 'PATH' in os.environ:
00070         raise Exception("Can't find command path for current platform ('%s')" % sys.platform)
00071     PATH=os.environ['PATH']
00072     for path in PATH.split(os.pathsep):
00073         abspath = '%s/%s' % (path, cmd)
00074         if exists(abspath) or exists(abspath + '.exe'):
00075             return abspath
00076 
00077 
00078 def mkdir(path):
00079     if not exists(path):
00080         makedirs(path)
00081 
00082 
00083 def copy_file (src, dst):
00084     """ Implement the behaviour of "shutil.copy(src, dst)" without copying the
00085         permissions (this was causing errors with directories mounted with samba)
00086     """
00087     if isdir(dst):
00088         _, file = split(src)
00089         dst = join(dst, file)
00090     copyfile(src, dst)
00091 
00092 
00093 def delete_dir_files(dir):
00094     if not exists(dir):
00095         return
00096 
00097     for f in listdir(dir):
00098         file = join(dir, f)
00099         if not isdir(file):
00100             remove(file)
00101 
00102 
00103 def get_caller_name (steps=2):
00104     """
00105     When called inside a function, it returns the name
00106     of the caller of that function.
00107     """
00108     return inspect.stack()[steps][3]
00109 
00110 
00111 def error(msg):
00112     print("ERROR: %s" % msg)
00113     sys.exit(1)
00114 
00115 
00116 def rel_path(path, base, dot=False):
00117     p = relpath(path, base)
00118     if dot and not p.startswith('.'):
00119         p = './' + p
00120     return p
00121 
00122 
00123 class ToolException(Exception):
00124     pass
00125 
00126 class NotSupportedException(Exception):
00127     pass
00128 
00129 def split_path(path):
00130     base, file = split(path)
00131     name, ext = splitext(file)
00132     return base, name, ext
00133 
00134 
00135 def args_error(parser, message):
00136     print "\n\n%s\n\n" % message
00137     parser.print_help()
00138     sys.exit()
00139 
00140 
00141 def construct_enum (**enums):
00142     """ Create your own pseudo-enums """
00143     return type('Enum', (), enums)
00144 
00145 
00146 def check_required_modules (required_modules, verbose=True):
00147     """ Function checks for Python modules which should be "importable" (installed)
00148         before test suite can be used.
00149         @return returns True if all modules are installed already
00150     """
00151     import imp
00152     not_installed_modules = []
00153     for module_name in required_modules:
00154         try:
00155             imp.find_module(module_name)
00156         except ImportError as e:
00157             # We also test against a rare case: module is an egg file
00158             try:
00159                 __import__(module_name)
00160             except ImportError as e:
00161                 not_installed_modules.append(module_name)
00162                 if verbose:
00163                     print "Error: %s" % e
00164 
00165     if verbose:
00166         if not_installed_modules:
00167             print "Warning: Module(s) %s not installed. Please install required module(s) before using this script."% (', '.join(not_installed_modules))
00168 
00169     if not_installed_modules:
00170         return False
00171     else:
00172         return True