scripts/install-debugclients.py

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

eric ide

mercurial