0
|
1 |
# Copyright (c) 2005-2009 Nokia Corporation
|
|
2 |
#
|
|
3 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4 |
# you may not use this file except in compliance with the License.
|
|
5 |
# You may obtain a copy of the License at
|
|
6 |
#
|
|
7 |
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8 |
#
|
|
9 |
# Unless required by applicable law or agreed to in writing, software
|
|
10 |
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12 |
# See the License for the specific language governing permissions and
|
|
13 |
# limitations under the License.
|
|
14 |
|
|
15 |
import sys
|
|
16 |
import stat
|
|
17 |
import re
|
|
18 |
import shutil
|
|
19 |
import thread
|
|
20 |
import os.path
|
|
21 |
from os.path import normpath
|
|
22 |
from subprocess import *
|
|
23 |
from threading import Thread
|
|
24 |
import zipfile
|
|
25 |
import tarfile
|
|
26 |
|
|
27 |
|
|
28 |
class CommandFailedException(Exception):
|
|
29 |
pass
|
|
30 |
|
|
31 |
|
|
32 |
class BuildFailedException(Exception):
|
|
33 |
pass
|
|
34 |
|
|
35 |
|
|
36 |
class ConfigureError(Exception):
|
|
37 |
pass
|
|
38 |
|
|
39 |
|
|
40 |
def log(str):
|
|
41 |
"""Prints the log in PyS60 format.
|
|
42 |
This must be used in place of "print" to get uniformity in logs
|
|
43 |
"""
|
|
44 |
print "PyS60: " + str
|
|
45 |
|
|
46 |
|
|
47 |
def run_shell_command(cmd, stdin='', mixed_stderr=0, verbose=0,
|
|
48 |
exception_on_error=1):
|
|
49 |
"""Internal method to execute shell commands"""
|
|
50 |
stdout_buf = []
|
|
51 |
if mixed_stderr:
|
|
52 |
stderr_buf = stdout_buf
|
|
53 |
else:
|
|
54 |
stderr_buf = []
|
|
55 |
if verbose:
|
|
56 |
print '- ', cmd
|
|
57 |
p = Popen(cmd,
|
|
58 |
stdin=PIPE,
|
|
59 |
stdout=PIPE,
|
|
60 |
stderr=PIPE,
|
|
61 |
shell=True)
|
|
62 |
p.stdin.write(stdin)
|
|
63 |
p.stdin.close()
|
|
64 |
|
|
65 |
def handle_stderr():
|
|
66 |
while 1:
|
|
67 |
line = p.stderr.readline()
|
|
68 |
if len(line) == 0:
|
|
69 |
break
|
|
70 |
if verbose:
|
|
71 |
print " ** " + line
|
|
72 |
stderr_buf.append(line)
|
|
73 |
stderr_thread = Thread(target=handle_stderr)
|
|
74 |
stderr_thread.start()
|
|
75 |
while 1:
|
|
76 |
line = p.stdout.readline()
|
|
77 |
if len(line) == 0:
|
|
78 |
break
|
|
79 |
if verbose:
|
|
80 |
print " -- " + line,
|
|
81 |
stdout_buf.append(line)
|
|
82 |
retcode = p.wait()
|
|
83 |
stderr_thread.join()
|
|
84 |
if retcode != 0 and exception_on_error:
|
|
85 |
raise CommandFailedException('Command "%s" failed with code "%s"'
|
|
86 |
% (cmd, retcode))
|
|
87 |
if mixed_stderr:
|
|
88 |
return {'stdout': ''.join(stdout_buf),
|
|
89 |
'return_code': retcode}
|
|
90 |
else:
|
|
91 |
return {'stdout': ''.join(stdout_buf),
|
|
92 |
'stderr': ''.join(stderr_buf),
|
|
93 |
'return_code': retcode}
|
|
94 |
|
|
95 |
|
|
96 |
def run_cmd(cmd, verbose=1, exception_on_error=1):
|
|
97 |
"""Method to execute shell commands.
|
|
98 |
Set verbose to 0 to stop logging messages.
|
|
99 |
"""
|
|
100 |
log('Executing command :<%s>' % cmd)
|
|
101 |
run_shell_command(cmd, mixed_stderr=1, verbose=verbose,
|
|
102 |
exception_on_error=exception_on_error)
|
|
103 |
|
|
104 |
|
|
105 |
def rename_file(fromfile, tofile):
|
|
106 |
if not os.path.exists(fromfile):
|
|
107 |
log("shellutil.py: Error: %s File does not exists" % (fromfile))
|
|
108 |
return
|
|
109 |
fromfile = normpath(fromfile)
|
|
110 |
tofile = normpath(tofile)
|
|
111 |
delete_file(tofile)
|
|
112 |
log("shellutil.py: Renaming: %s -> %s" % (fromfile, tofile))
|
|
113 |
os.rename(fromfile, tofile)
|
|
114 |
|
|
115 |
|
|
116 |
def copy_file(fromfile, tofile):
|
|
117 |
"""Method to copy files"""
|
|
118 |
fromfile = normpath(fromfile)
|
|
119 |
tofile = normpath(tofile)
|
|
120 |
if fromfile == tofile:
|
|
121 |
log("shellutil.py: No need to copy, source and target are the same:" +
|
|
122 |
"%s -> %s" % (fromfile, tofile))
|
|
123 |
else:
|
|
124 |
log("shellutil.py: Copying: %s -> %s" % (fromfile, tofile))
|
|
125 |
targetdir = os.path.dirname(os.path.abspath(tofile))
|
|
126 |
if not os.path.exists(targetdir):
|
|
127 |
os.makedirs(targetdir)
|
|
128 |
content = open(fromfile, 'rb').read()
|
|
129 |
open(tofile, 'wb').write(content)
|
|
130 |
|
|
131 |
|
|
132 |
def delete_file(filename):
|
|
133 |
"""Method to delete a particular file if that exists
|
|
134 |
If access is denied will give an error.
|
|
135 |
"""
|
|
136 |
if os.path.exists(filename):
|
|
137 |
log("Deleting: %s" % filename)
|
|
138 |
os.remove(filename)
|
|
139 |
|
|
140 |
|
|
141 |
def deltree_if_exists(dirname):
|
|
142 |
"""Delete an entire directory."""
|
|
143 |
if os.path.exists(dirname):
|
|
144 |
shutil.rmtree(dirname)
|
|
145 |
|
|
146 |
|
|
147 |
def files_matching_regex(topdir, regex):
|
|
148 |
"""Find the matching files in a directory
|
|
149 |
Return an empty list if file not found
|
|
150 |
"""
|
|
151 |
files = []
|
|
152 |
compiled_regex = re.compile(regex, re.I)
|
|
153 |
for path, dirnames, filenames in os.walk(topdir):
|
|
154 |
for x in filenames:
|
|
155 |
pathname = os.path.join(path, x)
|
|
156 |
if compiled_regex.match(pathname):
|
|
157 |
files.append(pathname)
|
|
158 |
return files
|
|
159 |
|
|
160 |
|
|
161 |
def setcapas(output, capas, compression_type='', verbose=0):
|
|
162 |
"""Method to apply new capability set & compression type on dlls or exes
|
|
163 |
This is used as post linker
|
|
164 |
"""
|
|
165 |
compression_opt = ''
|
|
166 |
if compression_type != '':
|
|
167 |
compression_opt = '-compressionmethod ' + compression_type
|
|
168 |
run_cmd('elftran -capability "%s" %s %s' \
|
|
169 |
% (capas, compression_opt, output))
|
|
170 |
if verbose:
|
|
171 |
run_cmd('elftran -dump s %s' % output, exception_on_error=0)
|
|
172 |
|
|
173 |
|
|
174 |
def create_archive_from_directory(archive_name, topdir, archive_dir='',
|
|
175 |
archive_type='zip'):
|
|
176 |
"""Creates a compressed archive from the contents of the given directory.
|
|
177 |
The archive types supported are tar.gz and zip.
|
|
178 |
"""
|
|
179 |
archive_name = os.path.normpath(archive_name)
|
|
180 |
topdir = os.path.normpath(topdir)
|
|
181 |
print "Creating archive %s from directory %s..." % (archive_name, topdir)
|
|
182 |
|
|
183 |
if archive_type == 'tar.gz':
|
|
184 |
archive = tarfile.open(archive_name, 'w:gz')
|
|
185 |
else:
|
|
186 |
archive = zipfile.ZipFile(archive_name, 'w')
|
|
187 |
abs_topdir = os.path.abspath(topdir)
|
|
188 |
for root, dirs, files in os.walk(topdir):
|
|
189 |
if '.svn' in dirs:
|
|
190 |
dirs.remove('.svn')
|
|
191 |
abs_root = os.path.abspath(root)
|
|
192 |
# Remove the common part from the directory name,
|
|
193 |
# leaving just the relative part
|
|
194 |
relative_path = abs_root[len(abs_topdir) + 1:]
|
|
195 |
for name in files:
|
|
196 |
absolute_filename = os.path.join(abs_root, name)
|
|
197 |
archive_filename = os.path.join(relative_path, name)
|
|
198 |
archive_filename = os.path.join(archive_dir, archive_filename)
|
|
199 |
print "Adding %s as %s" % (absolute_filename, archive_filename)
|
|
200 |
if archive_type == 'tar.gz':
|
|
201 |
archive.add(absolute_filename, archive_filename)
|
|
202 |
else:
|
|
203 |
archive.write(absolute_filename, archive_filename,
|
|
204 |
zipfile.ZIP_DEFLATED)
|
|
205 |
archive.close()
|
|
206 |
print "Created: ", archive_name
|
|
207 |
|
|
208 |
|
|
209 |
class tee(object):
|
|
210 |
"""Class that implements stdout redirection to both file and screen"""
|
|
211 |
|
|
212 |
def __init__(self, name, mode):
|
|
213 |
self.file = open(name, mode)
|
|
214 |
self.stdout = sys.stdout
|
|
215 |
sys.stdout = self
|
|
216 |
|
|
217 |
def close(self):
|
|
218 |
if self.stdout is not None:
|
|
219 |
sys.stdout = self.stdout
|
|
220 |
self.stdout = None
|
|
221 |
if self.file is not None:
|
|
222 |
self.file.close()
|
|
223 |
self.file = None
|
|
224 |
|
|
225 |
def write(self, data):
|
|
226 |
data = data.replace("\r", "")
|
|
227 |
self.file.write(data)
|
|
228 |
self.stdout.write(data)
|
|
229 |
|
|
230 |
def flush(self):
|
|
231 |
self.file.flush()
|
|
232 |
self.stdout.flush()
|
|
233 |
|
|
234 |
def __del__(self):
|
|
235 |
self.close()
|