install-debugclients.py

changeset 5053
dac4920b55ad
child 5145
95947ce71171
equal deleted inserted replaced
5051:3586ebd9fac8 5053:dac4920b55ad
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 # Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de>
5 #
6 # This is the install script for the eric6 debug client. It may be used
7 # to just install the debug clients for remote debugging.
8 #
9
10 """
11 Installation script for the eric6 debug clients.
12 """
13
14 from __future__ import unicode_literals, print_function
15 try:
16 import cStringIO as io
17 import sip
18 sip.setapi('QString', 2)
19 sip.setapi('QVariant', 2)
20 sip.setapi('QTextStream', 2)
21 except (ImportError):
22 import io # __IGNORE_WARNING__
23
24 import sys
25 import os
26 import re
27 import compileall
28 import shutil
29 import fnmatch
30 import distutils.sysconfig
31
32 # Define the globals.
33 progName = None
34 currDir = os.getcwd()
35 modDir = None
36 pyModDir = None
37 distDir = None
38 installPackage = "eric6DebugClients"
39 doCleanup = True
40 doCompile = True
41 sourceDir = "eric"
42
43
44 def exit(rcode=0):
45 """
46 Exit the install script.
47
48 @param rcode result code to report back (integer)
49 """
50 global currDir
51
52 if sys.platform.startswith("win"):
53 # different meaning of input between Py2 and Py3
54 try:
55 input("Press enter to continue...")
56 except (EOFError, SyntaxError):
57 pass
58
59 os.chdir(currDir)
60
61 sys.exit(rcode)
62
63
64 def usage(rcode=2):
65 """
66 Display a usage message and exit.
67
68 @param rcode the return code passed back to the calling process.
69 """
70 global progName, modDir, distDir
71
72 print()
73 print("Usage:")
74 if sys.platform == "darwin":
75 print(" {0} [-chz] [-d dir] [-i dir]".format(progName))
76 elif sys.platform.startswith("win"):
77 print(" {0} [-chz] [-d dir]".format(progName))
78 else:
79 print(" {0} [-chz][-d dir] [-i dir]".format(progName))
80 print("where:")
81 print(" -h, --help display this help message")
82 print(" -d dir where eric6 debug client files will be installed")
83 print(" (default: {0})".format(modDir))
84 if not sys.platform.startswith("win"):
85 print(" -i dir temporary install prefix")
86 print(" (default: {0})".format(distDir))
87 print(" -c don't cleanup old installation first")
88 print(" -z don't compile the installed python files")
89
90 exit(rcode)
91
92
93 def initGlobals():
94 """
95 Module function to set the values of globals that need more than a
96 simple assignment.
97 """
98 global modDir, pyModDir
99
100 modDir = distutils.sysconfig.get_python_lib(True)
101 pyModDir = modDir
102
103
104 def copyTree(src, dst, filters, excludeDirs=[], excludePatterns=[]):
105 """
106 Copy files of a directory tree.
107
108 @param src name of the source directory
109 @param dst name of the destination directory
110 @param filters list of filter pattern determining the files to be copied
111 @param excludeDirs list of (sub)directories to exclude from copying
112 @keyparam excludePatterns list of filter pattern determining the files to
113 be skipped
114 """
115 try:
116 names = os.listdir(src)
117 except OSError:
118 # ignore missing directories
119 return
120
121 for name in names:
122 skipIt = False
123 for excludePattern in excludePatterns:
124 if fnmatch.fnmatch(name, excludePattern):
125 skipIt = True
126 break
127 if not skipIt:
128 srcname = os.path.join(src, name)
129 dstname = os.path.join(dst, name)
130 for filter in filters:
131 if fnmatch.fnmatch(srcname, filter):
132 if not os.path.isdir(dst):
133 os.makedirs(dst)
134 shutil.copy2(srcname, dstname)
135 os.chmod(dstname, 0o644)
136 break
137 else:
138 if os.path.isdir(srcname) and srcname not in excludeDirs:
139 copyTree(srcname, dstname, filters,
140 excludePatterns=excludePatterns)
141
142
143 def cleanupSource(dirName):
144 """
145 Cleanup the sources directory to get rid of leftover files
146 and directories.
147
148 @param dirName name of the directory to prune (string)
149 """
150 # step 1: delete the __pycache__ directory and all *.pyc files
151 if os.path.exists(os.path.join(dirName, "__pycache__")):
152 shutil.rmtree(os.path.join(dirName, "__pycache__"))
153 for name in [f for f in os.listdir(dirName)
154 if fnmatch.fnmatch(f, "*.pyc")]:
155 os.remove(os.path.join(dirName, name))
156
157 # step 2: descent into subdirectories and delete them if empty
158 for name in os.listdir(dirName):
159 name = os.path.join(dirName, name)
160 if os.path.isdir(name):
161 cleanupSource(name)
162 if len(os.listdir(name)) == 0:
163 os.rmdir(name)
164
165
166 def cleanUp():
167 """
168 Uninstall the old eric debug client files.
169 """
170 global pyModDir
171
172 try:
173 # Cleanup the install directories
174 dirname = os.path.join(pyModDir, installPackage)
175 if os.path.exists(dirname):
176 shutil.rmtree(dirname, True)
177 except (IOError, OSError) as msg:
178 sys.stderr.write(
179 'Error: {0}\nTry install with admin rights.\n'.format(msg))
180 exit(7)
181
182
183 def shutilCopy(src, dst, perm=0o644):
184 """
185 Wrapper function around shutil.copy() to ensure the permissions.
186
187 @param src source file name (string)
188 @param dst destination file name or directory name (string)
189 @keyparam perm permissions to be set (integer)
190 """
191 shutil.copy(src, dst)
192 if os.path.isdir(dst):
193 dst = os.path.join(dst, os.path.basename(src))
194 os.chmod(dst, perm)
195
196
197 def installEricDebugClients():
198 """
199 Actually perform the installation steps.
200
201 @return result code (integer)
202 """
203 global distDir, doCleanup, sourceDir, modDir
204
205 # set install prefix, if not None
206 if distDir:
207 targetDir = os.path.normpath(os.path.join(distDir, installPackage))
208 else:
209 targetDir = os.path.join(modDir, installPackage)
210
211 try:
212 # Install the files
213 # copy the various parts of eric6 debug clients
214 copyTree(
215 os.path.join(sourceDir, "DebugClients"), targetDir,
216 ['*.py', '*.pyc', '*.pyo', '*.pyw'],
217 ['{1}{0}.ropeproject'.format(os.sep, sourceDir)],
218 excludePatterns=["eric6config.py*"])
219 copyTree(
220 os.path.join(sourceDir, "DebugClients"), targetDir,
221 ['*.rb'],
222 ['{1}{0}Examples'.format(os.sep, sourceDir)])
223
224 # copy the license file
225 shutilCopy(
226 '{1}{0}LICENSE.GPL3'.format(os.sep, sourceDir), targetDir)
227
228 except (IOError, OSError) as msg:
229 sys.stderr.write(
230 'Error: {0}\nTry install with admin rights.\n'.format(msg))
231 return(7)
232
233 return 0
234
235
236 def main(argv):
237 """
238 The main function of the script.
239
240 @param argv the list of command line arguments.
241 """
242 import getopt
243
244 # Parse the command line.
245 global progName, modDir, doCleanup, doCompile, distDir
246 global sourceDir
247
248 if sys.version_info < (2, 7, 0) or sys.version_info > (3, 9, 9):
249 print('Sorry, eric6 requires at least Python 2.7 or '
250 'Python 3 for running.')
251 exit(5)
252
253 progName = os.path.basename(argv[0])
254
255 if os.path.dirname(argv[0]):
256 os.chdir(os.path.dirname(argv[0]))
257
258 initGlobals()
259
260 try:
261 if sys.platform.startswith("win"):
262 optlist, args = getopt.getopt(
263 argv[1:], "chzd:", ["help"])
264 elif sys.platform == "darwin":
265 optlist, args = getopt.getopt(
266 argv[1:], "chzd:i:", ["help"])
267 else:
268 optlist, args = getopt.getopt(
269 argv[1:], "chzd:i:", ["help"])
270 except getopt.GetoptError as err:
271 print(err)
272 usage()
273
274 for opt, arg in optlist:
275 if opt in ["-h", "--help"]:
276 usage(0)
277 elif opt == "-d":
278 modDir = arg
279 elif opt == "-i":
280 distDir = os.path.normpath(arg)
281 elif opt == "-c":
282 doCleanup = False
283 elif opt == "-z":
284 doCompile = False
285
286 installFromSource = not os.path.isdir(sourceDir)
287 if installFromSource:
288 sourceDir = os.path.dirname(__file__) or "."
289
290 # cleanup source if installing from source
291 if installFromSource:
292 print("Cleaning up source ...")
293 cleanupSource(os.path.join(sourceDir, "DebugClients"))
294 print()
295
296 # cleanup old installation
297 try:
298 if doCleanup:
299 print("Cleaning up old installation ...")
300 if distDir:
301 shutil.rmtree(distDir, True)
302 else:
303 cleanUp()
304 except (IOError, OSError) as msg:
305 sys.stderr.write('Error: {0}\nTry install as root.\n'.format(msg))
306 exit(7)
307
308 if doCompile:
309 print("\nCompiling source files ...")
310 if sys.version_info[0] == 3:
311 skipRe = re.compile(r"DebugClients[\\/]Python[\\/]")
312 else:
313 skipRe = re.compile(r"DebugClients[\\/]Python3[\\/]")
314 # Hide compile errors (mainly because of Py2/Py3 differences)
315 sys.stdout = io.StringIO()
316 if distDir:
317 compileall.compile_dir(
318 os.path.join(sourceDir, "DebugClients"),
319 ddir=os.path.join(distDir, modDir, installPackage),
320 rx=skipRe,
321 quiet=True)
322 else:
323 compileall.compile_dir(
324 os.path.join(sourceDir, "DebugClients"),
325 ddir=os.path.join(modDir, installPackage),
326 rx=skipRe,
327 quiet=True)
328 sys.stdout = sys.__stdout__
329 print("\nInstalling eric6 debug clients ...")
330 res = installEricDebugClients()
331
332 print("\nInstallation complete.")
333 print()
334
335 exit(res)
336
337
338 if __name__ == "__main__":
339 try:
340 main(sys.argv)
341 except SystemExit:
342 raise
343 except Exception:
344 print("""An internal error occured. Please report all the output"""
345 """ of the program,\nincluding the following traceback, to"""
346 """ eric-bugs@eric-ide.python-projects.org.\n""")
347 raise
348
349 #
350 # eflag: noqa = M801

eric ide

mercurial