--- /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()