src/tools/shellutil.py
changeset 0 ca70ae20a155
--- /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()