diff -r 000000000000 -r ca70ae20a155 src/tools/shellutil.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/shellutil.py Tue Feb 16 10:07:05 2010 +0530 @@ -0,0 +1,235 @@ +# Copyright (c) 2005-2009 Nokia Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import stat +import re +import shutil +import thread +import os.path +from os.path import normpath +from subprocess import * +from threading import Thread +import zipfile +import tarfile + + +class CommandFailedException(Exception): + pass + + +class BuildFailedException(Exception): + pass + + +class ConfigureError(Exception): + pass + + +def log(str): + """Prints the log in PyS60 format. + This must be used in place of "print" to get uniformity in logs + """ + print "PyS60: " + str + + +def run_shell_command(cmd, stdin='', mixed_stderr=0, verbose=0, + exception_on_error=1): + """Internal method to execute shell commands""" + stdout_buf = [] + if mixed_stderr: + stderr_buf = stdout_buf + else: + stderr_buf = [] + if verbose: + print '- ', cmd + p = Popen(cmd, + stdin=PIPE, + stdout=PIPE, + stderr=PIPE, + shell=True) + p.stdin.write(stdin) + p.stdin.close() + + def handle_stderr(): + while 1: + line = p.stderr.readline() + if len(line) == 0: + break + if verbose: + print " ** " + line + stderr_buf.append(line) + stderr_thread = Thread(target=handle_stderr) + stderr_thread.start() + while 1: + line = p.stdout.readline() + if len(line) == 0: + break + if verbose: + print " -- " + line, + stdout_buf.append(line) + retcode = p.wait() + stderr_thread.join() + if retcode != 0 and exception_on_error: + raise CommandFailedException('Command "%s" failed with code "%s"' + % (cmd, retcode)) + if mixed_stderr: + return {'stdout': ''.join(stdout_buf), + 'return_code': retcode} + else: + return {'stdout': ''.join(stdout_buf), + 'stderr': ''.join(stderr_buf), + 'return_code': retcode} + + +def run_cmd(cmd, verbose=1, exception_on_error=1): + """Method to execute shell commands. + Set verbose to 0 to stop logging messages. + """ + log('Executing command :<%s>' % cmd) + run_shell_command(cmd, mixed_stderr=1, verbose=verbose, + exception_on_error=exception_on_error) + + +def rename_file(fromfile, tofile): + if not os.path.exists(fromfile): + log("shellutil.py: Error: %s File does not exists" % (fromfile)) + return + fromfile = normpath(fromfile) + tofile = normpath(tofile) + delete_file(tofile) + log("shellutil.py: Renaming: %s -> %s" % (fromfile, tofile)) + os.rename(fromfile, tofile) + + +def copy_file(fromfile, tofile): + """Method to copy files""" + fromfile = normpath(fromfile) + tofile = normpath(tofile) + if fromfile == tofile: + log("shellutil.py: No need to copy, source and target are the same:" + + "%s -> %s" % (fromfile, tofile)) + else: + log("shellutil.py: Copying: %s -> %s" % (fromfile, tofile)) + targetdir = os.path.dirname(os.path.abspath(tofile)) + if not os.path.exists(targetdir): + os.makedirs(targetdir) + content = open(fromfile, 'rb').read() + open(tofile, 'wb').write(content) + + +def delete_file(filename): + """Method to delete a particular file if that exists + If access is denied will give an error. + """ + if os.path.exists(filename): + log("Deleting: %s" % filename) + os.remove(filename) + + +def deltree_if_exists(dirname): + """Delete an entire directory.""" + if os.path.exists(dirname): + shutil.rmtree(dirname) + + +def files_matching_regex(topdir, regex): + """Find the matching files in a directory + Return an empty list if file not found + """ + files = [] + compiled_regex = re.compile(regex, re.I) + for path, dirnames, filenames in os.walk(topdir): + for x in filenames: + pathname = os.path.join(path, x) + if compiled_regex.match(pathname): + files.append(pathname) + return files + + +def setcapas(output, capas, compression_type='', verbose=0): + """Method to apply new capability set & compression type on dlls or exes + This is used as post linker + """ + compression_opt = '' + if compression_type != '': + compression_opt = '-compressionmethod ' + compression_type + run_cmd('elftran -capability "%s" %s %s' \ + % (capas, compression_opt, output)) + if verbose: + run_cmd('elftran -dump s %s' % output, exception_on_error=0) + + +def create_archive_from_directory(archive_name, topdir, archive_dir='', + archive_type='zip'): + """Creates a compressed archive from the contents of the given directory. + The archive types supported are tar.gz and zip. + """ + archive_name = os.path.normpath(archive_name) + topdir = os.path.normpath(topdir) + print "Creating archive %s from directory %s..." % (archive_name, topdir) + + if archive_type == 'tar.gz': + archive = tarfile.open(archive_name, 'w:gz') + else: + archive = zipfile.ZipFile(archive_name, 'w') + abs_topdir = os.path.abspath(topdir) + for root, dirs, files in os.walk(topdir): + if '.svn' in dirs: + dirs.remove('.svn') + abs_root = os.path.abspath(root) + # Remove the common part from the directory name, + # leaving just the relative part + relative_path = abs_root[len(abs_topdir) + 1:] + for name in files: + absolute_filename = os.path.join(abs_root, name) + archive_filename = os.path.join(relative_path, name) + archive_filename = os.path.join(archive_dir, archive_filename) + print "Adding %s as %s" % (absolute_filename, archive_filename) + if archive_type == 'tar.gz': + archive.add(absolute_filename, archive_filename) + else: + archive.write(absolute_filename, archive_filename, + zipfile.ZIP_DEFLATED) + archive.close() + print "Created: ", archive_name + + +class tee(object): + """Class that implements stdout redirection to both file and screen""" + + def __init__(self, name, mode): + self.file = open(name, mode) + self.stdout = sys.stdout + sys.stdout = self + + def close(self): + if self.stdout is not None: + sys.stdout = self.stdout + self.stdout = None + if self.file is not None: + self.file.close() + self.file = None + + def write(self, data): + data = data.replace("\r", "") + self.file.write(data) + self.stdout.write(data) + + def flush(self): + self.file.flush() + self.stdout.flush() + + def __del__(self): + self.close()