scripts/install.py

branch
without_py2_and_pyqt4
changeset 7192
a22eee00b052
parent 7185
af8e89a7a51d
child 7203
2079ccbfa335
equal deleted inserted replaced
7191:960850ec284c 7192:a22eee00b052
8 """ 8 """
9 Installation script for the eric6 IDE and all eric6 related tools. 9 Installation script for the eric6 IDE and all eric6 related tools.
10 """ 10 """
11 11
12 from __future__ import unicode_literals, print_function 12 from __future__ import unicode_literals, print_function
13 try:
14 # Python2 only
15 import cStringIO as io
16 try:
17 from PyQt5 import sip
18 except ImportError:
19 import sip
20 sip.setapi('QString', 2)
21 sip.setapi('QVariant', 2)
22 sip.setapi('QTextStream', 2)
23 input = raw_input # __IGNORE_WARNING__
24 except (ImportError):
25 import io # __IGNORE_WARNING__
26 13
27 import sys 14 import sys
28 import os 15 import os
29 import re 16 import re
30 import compileall 17 import compileall
31 import py_compile 18 import py_compile
32 import glob 19 import glob
33 import shutil 20 import shutil
34 import fnmatch 21 import fnmatch
35 import codecs
36 import subprocess 22 import subprocess
37 import time 23 import time
24 import io
38 25
39 # Define the globals. 26 # Define the globals.
40 progName = None 27 progName = None
41 currDir = os.getcwd() 28 currDir = os.getcwd()
42 modDir = None 29 modDir = None
48 installApis = True 35 installApis = True
49 doCleanup = True 36 doCleanup = True
50 doCleanDesktopLinks = False 37 doCleanDesktopLinks = False
51 forceCleanDesktopLinks = False 38 forceCleanDesktopLinks = False
52 doCompile = True 39 doCompile = True
53 includePythonVariant = False
54 cfg = {} 40 cfg = {}
55 progLanguages = ["Python", "Ruby", "QSS"] 41 progLanguages = ["Python", "Ruby", "QSS"]
56 sourceDir = "eric" 42 sourceDir = "eric"
57 eric6SourceDir = os.path.join(sourceDir, "eric6") 43 eric6SourceDir = os.path.join(sourceDir, "eric6")
58 configName = 'eric6config.py' 44 configName = 'eric6config.py'
61 defaultMacPythonExe = "{0}/Resources/Python.app/Contents/MacOS/Python".format( 47 defaultMacPythonExe = "{0}/Resources/Python.app/Contents/MacOS/Python".format(
62 sys.exec_prefix) 48 sys.exec_prefix)
63 macAppBundleName = defaultMacAppBundleName 49 macAppBundleName = defaultMacAppBundleName
64 macAppBundlePath = defaultMacAppBundlePath 50 macAppBundlePath = defaultMacAppBundlePath
65 macPythonExe = defaultMacPythonExe 51 macPythonExe = defaultMacPythonExe
66 pyqtVariant = ""
67 pyqtOverride = False
68 52
69 # Define blacklisted versions of the prerequisites 53 # Define blacklisted versions of the prerequisites
70 BlackLists = { 54 BlackLists = {
71 "sip": [], 55 "sip": [],
72 "PyQt4": [],
73 "PyQt5": [], 56 "PyQt5": [],
74 "QScintilla2": [], 57 "QScintilla2": [],
75 } 58 }
76 PlatformsBlackLists = { 59 PlatformsBlackLists = {
77 "windows": { 60 "windows": {
78 "sip": [], 61 "sip": [],
79 "PyQt4": [],
80 "PyQt5": [], 62 "PyQt5": [],
81 "QScintilla2": [], 63 "QScintilla2": [],
82 }, 64 },
83 65
84 "linux": { 66 "linux": {
85 "sip": [], 67 "sip": [],
86 "PyQt4": [],
87 "PyQt5": [], 68 "PyQt5": [],
88 "QScintilla2": [], 69 "QScintilla2": [],
89 }, 70 },
90 71
91 "mac": { 72 "mac": {
92 "sip": [], 73 "sip": [],
93 "PyQt4": [],
94 "PyQt5": [], 74 "PyQt5": [],
95 "QScintilla2": [], 75 "QScintilla2": [],
96 }, 76 },
97 } 77 }
98 78
99 # Define file name markers for Python variants
100 PythonMarkers = {
101 2: "_py2",
102 3: "_py3",
103 }
104 # Define a mapping of markers to full text
105 PythonTextMarkers = {
106 "_py2": "Python 2",
107 "_py3": "Python 3",
108 }
109
110 79
111 def exit(rcode=0): 80 def exit(rcode=0):
112 """ 81 """
113 Exit the install script. 82 Exit the install script.
114 83
117 global currDir 86 global currDir
118 87
119 print() 88 print()
120 89
121 if sys.platform.startswith(("win", "cygwin")): 90 if sys.platform.startswith(("win", "cygwin")):
122 # different meaning of input between Py2 and Py3
123 try: 91 try:
124 input("Press enter to continue...") 92 input("Press enter to continue...")
125 except (EOFError, SyntaxError): 93 except (EOFError, SyntaxError):
126 pass 94 pass
127 95
136 104
137 @param rcode the return code passed back to the calling process. 105 @param rcode the return code passed back to the calling process.
138 """ 106 """
139 global progName, modDir, distDir, apisDir 107 global progName, modDir, distDir, apisDir
140 global macAppBundleName, macAppBundlePath, macPythonExe 108 global macAppBundleName, macAppBundlePath, macPythonExe
141 global pyqtVariant
142 109
143 print() 110 print()
144 print("Usage:") 111 print("Usage:")
145 if sys.platform == "darwin": 112 if sys.platform == "darwin":
146 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]" 113 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
147 " [-m name] [-n path] [-p python] [--no-apis] [--pyqt=version]" 114 " [-m name] [-n path] [-p python] [--no-apis]"
148 .format(progName)) 115 .format(progName))
149 elif sys.platform.startswith(("win", "cygwin")): 116 elif sys.platform.startswith(("win", "cygwin")):
150 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file]" 117 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file]"
151 " [--clean-desktop] [--no-apis] [--pyqt=version]" 118 " [--clean-desktop] [--no-apis]"
152 .format(progName)) 119 .format(progName))
153 else: 120 else:
154 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]" 121 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
155 " [--no-apis] [--pyqt=version]" 122 " [--no-apis]"
156 .format(progName)) 123 .format(progName))
157 print("where:") 124 print("where:")
158 print(" -h, --help display this help message") 125 print(" -h, --help display this help message")
159 print(" -a dir where the API files will be installed") 126 print(" -a dir where the API files will be installed")
160 if apisDir: 127 if apisDir:
182 print(" -c don't cleanup old installation first") 149 print(" -c don't cleanup old installation first")
183 if sys.platform.startswith(("win", "cygwin")): 150 if sys.platform.startswith(("win", "cygwin")):
184 (" --clean-desktop delete desktop links before installation") 151 (" --clean-desktop delete desktop links before installation")
185 print(" -x don't perform dependency checks (use on your own" 152 print(" -x don't perform dependency checks (use on your own"
186 " risk)") 153 " risk)")
187 print(" -y add the Python variant to the executable names")
188 print(" -z don't compile the installed python files") 154 print(" -z don't compile the installed python files")
189 print(" --pyqt=version version of PyQt to be used (one of 4 or 5)")
190 if pyqtVariant:
191 print(" (default: {0})".format(pyqtVariant[-1]))
192 else:
193 print(" (no PyQt variant found)")
194 print() 155 print()
195 print("The file given to the -f option must be valid Python code" 156 print("The file given to the -f option must be valid Python code"
196 " defining a") 157 " defining a")
197 print("dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir'," 158 print("dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir',"
198 " 'ericIconDir',") 159 " 'ericIconDir',")
204 " parts of eric6.") 165 " parts of eric6.")
205 166
206 exit(rcode) 167 exit(rcode)
207 168
208 169
209 def determinePyQtVariant():
210 """
211 Module function to determine the PyQt variant to be used.
212 """
213 global pyqtVariant, pyqtOverride
214
215 pyqtVariant = ""
216 # need to handle the --pyqt= option here
217 if "--pyqt=4" in sys.argv:
218 pyqtVariant = "PyQt4"
219 pyqtOverride = True
220 elif "--pyqt=5" in sys.argv:
221 pyqtVariant = "PyQt5"
222 pyqtOverride = True
223 else:
224 try:
225 import PyQt5 # __IGNORE_WARNING__
226 pyqtVariant = "PyQt5"
227 del sys.modules["PyQt5"]
228 except ImportError:
229 try:
230 import PyQt4 # __IGNORE_WARNING__
231 pyqtVariant = "PyQt4"
232 del sys.modules["PyQt4"]
233 except ImportError:
234 # default to PyQt5, installation will be asked for
235 pyqtVariant = "PyQt5"
236
237
238 def initGlobals(): 170 def initGlobals():
239 """ 171 """
240 Module function to set the values of globals that need more than a 172 Module function to set the values of globals that need more than a
241 simple assignment. 173 simple assignment.
242 """ 174 """
243 global platBinDir, modDir, pyModDir, apisDir, pyqtVariant, platBinDirOld 175 global platBinDir, modDir, pyModDir, apisDir, platBinDirOld
244 176
245 try: 177 try:
246 import distutils.sysconfig 178 import distutils.sysconfig
247 except ImportError: 179 except ImportError:
248 print("Please install the 'distutils' package first.") 180 print("Please install the 'distutils' package first.")
269 platBinDirOld = "/usr/local/bin" 201 platBinDirOld = "/usr/local/bin"
270 202
271 modDir = distutils.sysconfig.get_python_lib(True) 203 modDir = distutils.sysconfig.get_python_lib(True)
272 pyModDir = modDir 204 pyModDir = modDir
273 205
274 pyqtDataDir = os.path.join(modDir, pyqtVariant) 206 pyqtDataDir = os.path.join(modDir, "PyQt5")
275 if os.path.exists(os.path.join(pyqtDataDir, "qsci")): 207 if os.path.exists(os.path.join(pyqtDataDir, "qsci")):
276 # it's the installer 208 # it's the installer
277 qtDataDir = pyqtDataDir 209 qtDataDir = pyqtDataDir
278 elif os.path.exists(os.path.join(pyqtDataDir, "Qt", "qsci")): 210 elif os.path.exists(os.path.join(pyqtDataDir, "Qt", "qsci")):
279 # it's the wheel 211 # it's the wheel
280 qtDataDir = os.path.join(pyqtDataDir, "Qt") 212 qtDataDir = os.path.join(pyqtDataDir, "Qt")
281 else: 213 else:
282 # determine dynamically 214 # determine dynamically
283 try: 215 try:
284 if pyqtVariant == "PyQt4": 216 from PyQt5.QtCore import QLibraryInfo
285 from PyQt4.QtCore import QLibraryInfo
286 else:
287 from PyQt5.QtCore import QLibraryInfo
288 qtDataDir = QLibraryInfo.location(QLibraryInfo.DataPath) 217 qtDataDir = QLibraryInfo.location(QLibraryInfo.DataPath)
289 except ImportError: 218 except ImportError:
290 qtDataDir = None 219 qtDataDir = None
291 if qtDataDir: 220 if qtDataDir:
292 apisDir = os.path.join(qtDataDir, "qsci", "api") 221 apisDir = os.path.join(qtDataDir, "qsci", "api")
300 229
301 @param name the name of the file. 230 @param name the name of the file.
302 @param text the contents to copy to the file. 231 @param text the contents to copy to the file.
303 """ 232 """
304 f = open(name, "w") 233 f = open(name, "w")
305 if sys.version_info[0] == 2:
306 text = codecs.encode(text, "utf-8")
307 f.write(text) 234 f.write(text)
308 f.close() 235 f.close()
309 236
310 237
311 def copyDesktopFile(src, dst, marker): 238 def copyDesktopFile(src, dst):
312 """ 239 """
313 Modify a desktop file and write it to its destination. 240 Modify a desktop file and write it to its destination.
314 241
315 @param src source file name (string) 242 @param src source file name (string)
316 @param dst destination file name (string) 243 @param dst destination file name (string)
317 @param marker marker to be used (string)
318 """ 244 """
319 global cfg, platBinDir 245 global cfg, platBinDir
320 246
321 if sys.version_info[0] == 2: 247 f = open(src, "r", encoding="utf-8")
322 f = codecs.open(src, "r", "utf-8")
323 else:
324 f = open(src, "r", encoding="utf-8")
325 text = f.read() 248 text = f.read()
326 f.close() 249 f.close()
327 250
328 text = text.replace("@BINDIR@", platBinDir) 251 text = text.replace("@BINDIR@", platBinDir)
329 text = text.replace("@MARKER@", marker) 252 text = text.replace("@MARKER@", "")
330 if marker: 253 text = text.replace("@PY_MARKER@", "")
331 t_marker = " ({0})".format(PythonTextMarkers[marker]) 254
332 else: 255 f = open(dst, "w", encoding="utf-8")
333 t_marker = ""
334 text = text.replace("@PY_MARKER@", t_marker)
335
336 if sys.version_info[0] == 2:
337 f = codecs.open(dst, "w", "utf-8")
338 else:
339 f = open(dst, "w", encoding="utf-8")
340 f.write(text) 256 f.write(text)
341 f.close() 257 f.close()
342 os.chmod(dst, 0o644) 258 os.chmod(dst, 0o644)
343 259
344 260
345 def copyAppStreamFile(src, dst, marker): 261 def copyAppStreamFile(src, dst):
346 """ 262 """
347 Modify an appstream file and write it to its destination. 263 Modify an appstream file and write it to its destination.
348 264
349 @param src source file name (string) 265 @param src source file name (string)
350 @param dst destination file name (string) 266 @param dst destination file name (string)
351 @param marker marker to be used (string)
352 """ 267 """
353 if os.path.exists(os.path.join("eric", "eric6", "UI", "Info.py")): 268 if os.path.exists(os.path.join("eric", "eric6", "UI", "Info.py")):
354 # Installing from archive 269 # Installing from archive
355 from eric.eric6.UI.Info import Version 270 from eric.eric6.UI.Info import Version
356 elif os.path.exists(os.path.join("eric6", "UI", "Info.py")): 271 elif os.path.exists(os.path.join("eric6", "UI", "Info.py")):
357 # Installing from source tree 272 # Installing from source tree
358 from eric6.UI.Info import Version 273 from eric6.UI.Info import Version
359 else: 274 else:
360 Version = "Unknown" 275 Version = "Unknown"
361 276
362 if sys.version_info[0] == 2: 277 f = open(src, "r", encoding="utf-8")
363 f = codecs.open(src, "r", "utf-8")
364 else:
365 f = open(src, "r", encoding="utf-8")
366 text = f.read() 278 text = f.read()
367 f.close() 279 f.close()
368 280
369 text = text.replace("@MARKER@", marker)\ 281 text = text.replace("@MARKER@", "")\
370 .replace("@VERSION@", Version.split(None, 1)[0])\ 282 .replace("@VERSION@", Version.split(None, 1)[0])\
371 .replace("@DATE@", time.strftime("%Y-%m-%d")) 283 .replace("@DATE@", time.strftime("%Y-%m-%d"))
372 284
373 if sys.version_info[0] == 2: 285 f = open(dst, "w", encoding="utf-8")
374 f = codecs.open(dst, "w", "utf-8")
375 else:
376 f = open(dst, "w", encoding="utf-8")
377 f.write(text) 286 f.write(text)
378 f.close() 287 f.close()
379 os.chmod(dst, 0o644) 288 os.chmod(dst, 0o644)
380 289
381 290
406 @param saveDir directory to save the file into (string) 315 @param saveDir directory to save the file into (string)
407 @param isGuiScript flag indicating a wrapper script for a GUI 316 @param isGuiScript flag indicating a wrapper script for a GUI
408 application (boolean) 317 application (boolean)
409 @return the platform specific name of the wrapper (string) 318 @return the platform specific name of the wrapper (string)
410 """ 319 """
411 global includePythonVariant, pyqtVariant, pyqtOverride
412
413 if includePythonVariant:
414 marker = PythonMarkers[sys.version_info.major]
415 else:
416 marker = ""
417
418 if pyqtOverride and pyqtVariant == "PyQt4":
419 pyqt4opt = " --pyqt4"
420 else:
421 pyqt4opt = ""
422
423 # all kinds of Windows systems 320 # all kinds of Windows systems
424 if sys.platform.startswith(("win", "cygwin")): 321 if sys.platform.startswith(("win", "cygwin")):
425 wname = wfile + marker + ".cmd" 322 wname = wfile + ".cmd"
426 if isGuiScript: 323 if isGuiScript:
427 wrapper = \ 324 wrapper = \
428 '''@echo off\n''' \ 325 '''@echo off\n''' \
429 '''start "" "{2}\\pythonw.exe"''' \ 326 '''start "" "{2}\\pythonw.exe"''' \
430 ''' "{0}\\{1}.pyw"{3}''' \ 327 ''' "{0}\\{1}.pyw"''' \
431 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format( 328 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format(
432 pydir, wfile, sys.exec_prefix, pyqt4opt) 329 pydir, wfile, sys.exec_prefix)
433 else: 330 else:
434 wrapper = \ 331 wrapper = \
435 '''@"{0}\\python" "{1}\\{2}.py"{3}''' \ 332 '''@"{0}\\python" "{1}\\{2}.py"''' \
436 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format( 333 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format(
437 sys.exec_prefix, pydir, wfile, pyqt4opt) 334 sys.exec_prefix, pydir, wfile)
438 335
439 # Mac OS X 336 # Mac OS X
440 elif sys.platform == "darwin": 337 elif sys.platform == "darwin":
441 major = sys.version_info.major 338 major = sys.version_info.major
442 pyexec = "{0}/bin/pythonw{1}".format(sys.exec_prefix, major) 339 pyexec = "{0}/bin/pythonw{1}".format(sys.exec_prefix, major)
443 if not os.path.exists(pyexec): 340 if not os.path.exists(pyexec):
444 pyexec = "{0}/bin/python{1}".format(sys.exec_prefix, major) 341 pyexec = "{0}/bin/python{1}".format(sys.exec_prefix, major)
445 wname = wfile + marker 342 wname = wfile
446 wrapper = ('''#!/bin/sh\n''' 343 wrapper = ('''#!/bin/sh\n'''
447 '''\n''' 344 '''\n'''
448 '''exec "{0}" "{1}/{2}.py"{3} "$@"\n''' 345 '''exec "{0}" "{1}/{2}.py" "$@"\n'''
449 .format(pyexec, pydir, wfile, pyqt4opt)) 346 .format(pyexec, pydir, wfile))
450 347
451 # *nix systems 348 # *nix systems
452 else: 349 else:
453 wname = wfile + marker 350 wname = wfile
454 wrapper = ('''#!/bin/sh\n''' 351 wrapper = ('''#!/bin/sh\n'''
455 '''\n''' 352 '''\n'''
456 '''exec "{0}" "{1}/{2}.py"{3} "$@"\n''' 353 '''exec "{0}" "{1}/{2}.py" "$@"\n'''
457 .format(sys.executable, pydir, wfile, pyqt4opt)) 354 .format(sys.executable, pydir, wfile))
458 355
459 wname = os.path.join(saveDir, wname) 356 wname = os.path.join(saveDir, wname)
460 copyToFile(wname, wrapper) 357 copyToFile(wname, wrapper)
461 os.chmod(wname, 0o755) 358 os.chmod(wname, 0o755)
462 359
572 469
573 def cleanUp(): 470 def cleanUp():
574 """ 471 """
575 Uninstall the old eric files. 472 Uninstall the old eric files.
576 """ 473 """
577 global platBinDir, platBinDirOld, includePythonVariant 474 global platBinDir, platBinDirOld
578 475
579 try: 476 try:
580 from eric6config import getConfig 477 from eric6config import getConfig
581 except ImportError: 478 except ImportError:
582 # eric6 wasn't installed previously 479 # eric6 wasn't installed previously
600 "eric6_trpreviewer", "eric6_uipreviewer", 497 "eric6_trpreviewer", "eric6_uipreviewer",
601 "eric6_unittest", "eric6", 498 "eric6_unittest", "eric6",
602 "eric6_tray", "eric6_editor", 499 "eric6_tray", "eric6_editor",
603 "eric6_plugininstall", "eric6_pluginuninstall", 500 "eric6_plugininstall", "eric6_pluginuninstall",
604 "eric6_pluginrepository", "eric6_sqlbrowser", 501 "eric6_pluginrepository", "eric6_sqlbrowser",
605 "eric6_webbrowser", "eric6_iconeditor", 502 "eric6_iconeditor", "eric6_snap", "eric6_hexeditor",
606 "eric6_snap", "eric6_hexeditor", "eric6_browser", 503 "eric6_browser", "eric6_shell",
607 "eric6_shell",
608 ] 504 ]
609 if includePythonVariant:
610 marker = PythonMarkers[sys.version_info.major]
611 rem_wnames = [n + marker for n in rem_wnames]
612 505
613 try: 506 try:
614 dirs = [platBinDir, getConfig('bindir')] 507 dirs = [platBinDir, getConfig('bindir')]
615 if platBinDirOld: 508 if platBinDirOld:
616 dirs.append(platBinDirOld) 509 dirs.append(platBinDirOld)
675 if os.getuid() == 0: 568 if os.getuid() == 0:
676 for name in ["/usr/share/pixmaps/eric.png", 569 for name in ["/usr/share/pixmaps/eric.png",
677 "/usr/share/pixmaps/ericWeb.png"]: 570 "/usr/share/pixmaps/ericWeb.png"]:
678 if os.path.exists(name): 571 if os.path.exists(name):
679 os.remove(name) 572 os.remove(name)
680 if includePythonVariant:
681 marker = PythonMarkers[sys.version_info.major]
682 else:
683 marker = ""
684 for name in [ 573 for name in [
685 "/usr/share/applications/eric6" + marker + ".desktop", 574 "/usr/share/applications/eric6.desktop",
686 "/usr/share/appdata/eric6" + marker + ".appdata.xml", 575 "/usr/share/appdata/eric6.appdata.xml",
687 "/usr/share/metainfo/eric6" + marker + ".appdata.xml", 576 "/usr/share/metainfo/eric6.appdata.xml",
688 "/usr/share/applications/eric6_webbrowser" + marker + 577 "/usr/share/applications/eric6_browser.desktop",
689 ".desktop", 578 "/usr/share/pixmaps/eric.png",
690 "/usr/share/applications/eric6_browser" + marker + 579 "/usr/share/pixmaps/ericWeb.png",
691 ".desktop",
692 "/usr/share/pixmaps/eric" + marker + ".png",
693 "/usr/share/pixmaps/ericWeb" + marker + ".png",
694 ]: 580 ]:
695 if os.path.exists(name): 581 if os.path.exists(name):
696 os.remove(name) 582 os.remove(name)
697 elif os.getuid() >= 1000: 583 elif os.getuid() >= 1000:
698 # it is assumed that user ids start at 1000 584 # it is assumed that user ids start at 1000
699 for name in ["~/.local/share/pixmaps/eric.png", 585 for name in ["~/.local/share/pixmaps/eric.png",
700 "~/.local/share/pixmaps/ericWeb.png"]: 586 "~/.local/share/pixmaps/ericWeb.png"]:
701 path = os.path.expanduser(name) 587 path = os.path.expanduser(name)
702 if os.path.exists(path): 588 if os.path.exists(path):
703 os.remove(path) 589 os.remove(path)
704 if includePythonVariant:
705 marker = PythonMarkers[sys.version_info.major]
706 else:
707 marker = ""
708 for name in [ 590 for name in [
709 "~/.local/share/applications/eric6" + marker + ".desktop", 591 "~/.local/share/applications/eric6.desktop",
710 "~/.local/share/appdata/eric6" + marker + ".appdata.xml", 592 "~/.local/share/appdata/eric6.appdata.xml",
711 "~/.local/share/metainfo/eric6" + marker + ".appdata.xml", 593 "~/.local/share/metainfo/eric6.appdata.xml",
712 "~/.local/share/applications/eric6_webbrowser" + marker + 594 "~/.local/share/applications/eric6_browser.desktop",
713 ".desktop", 595 "~/.local/share/pixmaps/eric.png",
714 "~/.local/share/applications/eric6_browser" + marker + 596 "~/.local/share/pixmaps/ericWeb.png",
715 ".desktop",
716 "~/.local/share/pixmaps/eric" + marker + ".png",
717 "~/.local/share/pixmaps/ericWeb" + marker + ".png",
718 ]: 597 ]:
719 path = os.path.expanduser(name) 598 path = os.path.expanduser(name)
720 if os.path.exists(path): 599 if os.path.exists(path):
721 os.remove(path) 600 os.remove(path)
722 601
804 Actually perform the installation steps. 683 Actually perform the installation steps.
805 684
806 @return result code (integer) 685 @return result code (integer)
807 """ 686 """
808 global distDir, doCleanup, cfg, progLanguages, sourceDir, configName 687 global distDir, doCleanup, cfg, progLanguages, sourceDir, configName
809 global includePythonVariant, installApis 688 global installApis
810 689
811 # Create the platform specific wrappers. 690 # Create the platform specific wrappers.
812 scriptsDir = "install_scripts" 691 scriptsDir = "install_scripts"
813 if not os.path.isdir(scriptsDir): 692 if not os.path.isdir(scriptsDir):
814 os.mkdir(scriptsDir) 693 os.mkdir(scriptsDir)
819 "eric6_editor", "eric6_hexeditor", "eric6_iconeditor", 698 "eric6_editor", "eric6_hexeditor", "eric6_iconeditor",
820 "eric6_plugininstall", "eric6_pluginrepository", 699 "eric6_plugininstall", "eric6_pluginrepository",
821 "eric6_pluginuninstall", "eric6_qregexp", 700 "eric6_pluginuninstall", "eric6_qregexp",
822 "eric6_qregularexpression", "eric6_re", "eric6_snap", 701 "eric6_qregularexpression", "eric6_re", "eric6_snap",
823 "eric6_sqlbrowser", "eric6_tray", "eric6_trpreviewer", 702 "eric6_sqlbrowser", "eric6_tray", "eric6_trpreviewer",
824 "eric6_uipreviewer", "eric6_unittest", "eric6_webbrowser", 703 "eric6_uipreviewer", "eric6_unittest", "eric6_browser",
825 "eric6_browser", "eric6_shell", "eric6"]: 704 "eric6_shell", "eric6"]:
826 wnames.append(createPyWrapper(cfg['ericDir'], name, scriptsDir)) 705 wnames.append(createPyWrapper(cfg['ericDir'], name, scriptsDir))
827 706
828 # set install prefix, if not None 707 # set install prefix, if not None
829 if distDir: 708 if distDir:
830 for key in list(cfg.keys()): 709 for key in list(cfg.keys()):
1011 890
1012 def createLinuxSpecifics(): 891 def createLinuxSpecifics():
1013 """ 892 """
1014 Install Linux specific files. 893 Install Linux specific files.
1015 """ 894 """
1016 global distDir, sourceDir, includePythonVariant 895 global distDir, sourceDir
1017 896
1018 if includePythonVariant:
1019 marker = PythonMarkers[sys.version_info.major]
1020 else:
1021 marker = ""
1022
1023 if distDir: 897 if distDir:
1024 dst = os.path.normpath(os.path.join(distDir, "usr/share/pixmaps")) 898 dst = os.path.normpath(os.path.join(distDir, "usr/share/pixmaps"))
1025 if not os.path.exists(dst): 899 if not os.path.exists(dst):
1026 os.makedirs(dst) 900 os.makedirs(dst)
1027 shutilCopy( 901 shutilCopy(
1028 os.path.join(eric6SourceDir, "icons", "default", "eric.png"), 902 os.path.join(eric6SourceDir, "icons", "default", "eric.png"),
1029 os.path.join(dst, "eric" + marker + ".png")) 903 os.path.join(dst, "eric.png"))
1030 shutilCopy( 904 shutilCopy(
1031 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"), 905 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"),
1032 os.path.join(dst, "ericWeb" + marker + ".png")) 906 os.path.join(dst, "ericWeb.png"))
1033 dst = os.path.normpath( 907 dst = os.path.normpath(
1034 os.path.join(distDir, "usr/share/applications")) 908 os.path.join(distDir, "usr/share/applications"))
1035 if not os.path.exists(dst): 909 if not os.path.exists(dst):
1036 os.makedirs(dst) 910 os.makedirs(dst)
1037 copyDesktopFile(os.path.join(sourceDir, "linux", "eric6.desktop.in"), 911 copyDesktopFile(os.path.join(sourceDir, "linux", "eric6.desktop.in"),
1038 os.path.join(dst, "eric6" + marker + ".desktop"), 912 os.path.join(dst, "eric6.desktop"))
1039 marker)
1040 copyDesktopFile(
1041 os.path.join(sourceDir, "linux", "eric6_webbrowser.desktop.in"),
1042 os.path.join(dst, "eric6_webbrowser" + marker + ".desktop"),
1043 marker)
1044 copyDesktopFile( 913 copyDesktopFile(
1045 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"), 914 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"),
1046 os.path.join(dst, "eric6_browser" + marker + ".desktop"), 915 os.path.join(dst, "eric6_browser.desktop"))
1047 marker)
1048 dst = os.path.normpath( 916 dst = os.path.normpath(
1049 os.path.join(distDir, "usr/share/metainfo")) 917 os.path.join(distDir, "usr/share/metainfo"))
1050 if not os.path.exists(dst): 918 if not os.path.exists(dst):
1051 os.makedirs(dst) 919 os.makedirs(dst)
1052 copyAppStreamFile( 920 copyAppStreamFile(
1053 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 921 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1054 os.path.join(dst, "eric6" + marker + ".appdata.xml"), 922 os.path.join(dst, "eric6.appdata.xml"))
1055 marker)
1056 elif os.getuid() == 0: 923 elif os.getuid() == 0:
1057 shutilCopy(os.path.join( 924 shutilCopy(os.path.join(
1058 eric6SourceDir, "icons", "default", "eric.png"), 925 eric6SourceDir, "icons", "default", "eric.png"),
1059 "/usr/share/pixmaps/eric" + marker + ".png") 926 "/usr/share/pixmaps/eric.png")
1060 copyDesktopFile( 927 copyDesktopFile(
1061 os.path.join(sourceDir, "linux", "eric6.desktop.in"), 928 os.path.join(sourceDir, "linux", "eric6.desktop.in"),
1062 "/usr/share/applications/eric6" + marker + ".desktop", 929 "/usr/share/applications/eric6.desktop")
1063 marker)
1064 if os.path.exists("/usr/share/metainfo"): 930 if os.path.exists("/usr/share/metainfo"):
1065 copyAppStreamFile( 931 copyAppStreamFile(
1066 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 932 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1067 "/usr/share/metainfo/eric6" + marker + ".appdata.xml", 933 "/usr/share/metainfo/eric6.appdata.xml")
1068 marker)
1069 elif os.path.exists("/usr/share/appdata"): 934 elif os.path.exists("/usr/share/appdata"):
1070 copyAppStreamFile( 935 copyAppStreamFile(
1071 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 936 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1072 "/usr/share/appdata/eric6" + marker + ".appdata.xml", 937 "/usr/share/appdata/eric6.appdata.xml")
1073 marker)
1074 shutilCopy(os.path.join( 938 shutilCopy(os.path.join(
1075 eric6SourceDir, "icons", "default", "ericWeb48.png"), 939 eric6SourceDir, "icons", "default", "ericWeb48.png"),
1076 "/usr/share/pixmaps/ericWeb" + marker + ".png") 940 "/usr/share/pixmaps/ericWeb.png")
1077 copyDesktopFile(
1078 os.path.join(sourceDir, "linux", "eric6_webbrowser.desktop.in"),
1079 "/usr/share/applications/eric6_webbrowser" + marker +
1080 ".desktop",
1081 marker)
1082 copyDesktopFile( 941 copyDesktopFile(
1083 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"), 942 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"),
1084 "/usr/share/applications/eric6_browser" + marker + 943 "/usr/share/applications/eric6_browser.desktop")
1085 ".desktop",
1086 marker)
1087 elif os.getuid() >= 1000: 944 elif os.getuid() >= 1000:
1088 # it is assumed, that user ids start at 1000 945 # it is assumed, that user ids start at 1000
1089 localPath = os.path.join(os.path.expanduser("~"), 946 localPath = os.path.join(os.path.expanduser("~"),
1090 ".local", "share") 947 ".local", "share")
1091 # create directories first 948 # create directories first
1095 if not os.path.isdir(directory): 952 if not os.path.isdir(directory):
1096 os.makedirs(directory) 953 os.makedirs(directory)
1097 # now copy the files 954 # now copy the files
1098 shutilCopy( 955 shutilCopy(
1099 os.path.join(eric6SourceDir, "icons", "default", "eric.png"), 956 os.path.join(eric6SourceDir, "icons", "default", "eric.png"),
1100 os.path.join(localPath, "pixmaps", "eric" + marker + ".png")) 957 os.path.join(localPath, "pixmaps", "eric.png"))
1101 copyDesktopFile( 958 copyDesktopFile(
1102 os.path.join(sourceDir, "linux", "eric6.desktop.in"), 959 os.path.join(sourceDir, "linux", "eric6.desktop.in"),
1103 os.path.join(localPath, "applications", 960 os.path.join(localPath, "applications", "eric6.desktop"))
1104 "eric6" + marker + ".desktop"),
1105 marker)
1106 copyAppStreamFile( 961 copyAppStreamFile(
1107 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 962 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1108 os.path.join(localPath, "metainfo", 963 os.path.join(localPath, "metainfo", "eric6.appdata.xml"))
1109 "eric6" + marker + ".appdata.xml"),
1110 marker)
1111 copyAppStreamFile( 964 copyAppStreamFile(
1112 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 965 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1113 os.path.join(localPath, "appdata", 966 os.path.join(localPath, "appdata", "eric6.appdata.xml"))
1114 "eric6" + marker + ".appdata.xml"),
1115 marker)
1116 shutilCopy( 967 shutilCopy(
1117 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"), 968 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"),
1118 os.path.join(localPath, "pixmaps", 969 os.path.join(localPath, "pixmaps", "ericWeb.png"))
1119 "ericWeb" + marker + ".png"))
1120 copyDesktopFile(
1121 os.path.join(sourceDir, "linux", "eric6_webbrowser.desktop.in"),
1122 os.path.join(localPath, "applications",
1123 "eric6_webbrowser" + marker + ".desktop"),
1124 marker)
1125 copyDesktopFile( 970 copyDesktopFile(
1126 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"), 971 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"),
1127 os.path.join(localPath, "applications", 972 os.path.join(localPath, "applications", "eric6_browser.desktop"))
1128 "eric6_browser" + marker + ".desktop"),
1129 marker)
1130 973
1131 974
1132 def createWindowsLinks(): 975 def createWindowsLinks():
1133 """ 976 """
1134 Create Desktop and Start Menu links. 977 Create Desktop and Start Menu links.
1147 args = [ 990 args = [
1148 sys.executable, 991 sys.executable,
1149 os.path.join(os.path.dirname(__file__), 992 os.path.join(os.path.dirname(__file__),
1150 "create_windows_links.py"), 993 "create_windows_links.py"),
1151 ] 994 ]
1152 if includePythonVariant:
1153 args.append("-y")
1154 subprocess.call(args) 995 subprocess.call(args)
1155 else: 996 else:
1156 print( 997 print(
1157 "\nThe Python package 'pywin32' is not installed. Desktop and" 998 "\nThe Python package 'pywin32' is not installed. Desktop and"
1158 " Start Menu entries will not be created." 999 " Start Menu entries will not be created."
1194 1035
1195 @param pydir the name of the directory where the Python script will 1036 @param pydir the name of the directory where the Python script will
1196 eventually be installed 1037 eventually be installed
1197 @type str 1038 @type str
1198 """ 1039 """
1199 global cfg, macAppBundleName, macPythonExe, macAppBundlePath, pyqtVariant 1040 global cfg, macAppBundleName, macPythonExe, macAppBundlePath
1200 1041
1201 directories = { 1042 directories = {
1202 "contents": "{0}/{1}/Contents/".format( 1043 "contents": "{0}/{1}/Contents/".format(
1203 macAppBundlePath, macAppBundleName), 1044 macAppBundlePath, macAppBundleName),
1204 "exe": "{0}/{1}/Contents/MacOS".format( 1045 "exe": "{0}/{1}/Contents/MacOS".format(
1219 wname = os.path.join(directories["exe"], "eric6") 1060 wname = os.path.join(directories["exe"], "eric6")
1220 1061
1221 # determine entry for DYLD_FRAMEWORK_PATH 1062 # determine entry for DYLD_FRAMEWORK_PATH
1222 dyldLine = "" 1063 dyldLine = ""
1223 try: 1064 try:
1224 if pyqtVariant == "PyQt4": 1065 from PyQt5.QtCore import QLibraryInfo
1225 from PyQt4.QtCore import QLibraryInfo
1226 else:
1227 from PyQt5.QtCore import QLibraryInfo
1228 qtLibraryDir = QLibraryInfo.location(QLibraryInfo.LibrariesPath) 1066 qtLibraryDir = QLibraryInfo.location(QLibraryInfo.LibrariesPath)
1229 except ImportError: 1067 except ImportError:
1230 qtLibraryDir = "" 1068 qtLibraryDir = ""
1231 if qtLibraryDir: 1069 if qtLibraryDir:
1232 dyldLine = "DYLD_FRAMEWORK_PATH={0}\n".format(qtLibraryDir) 1070 dyldLine = "DYLD_FRAMEWORK_PATH={0}\n".format(qtLibraryDir)
1432 @rtype bool 1270 @rtype bool
1433 """ 1271 """
1434 ok = False 1272 ok = False
1435 print("{0}\n\nShall '{1}' be installed using pip? (Y/n)" 1273 print("{0}\n\nShall '{1}' be installed using pip? (Y/n)"
1436 .format(message, packageName), end=" ") 1274 .format(message, packageName), end=" ")
1437 if sys.version_info[0] == 2: 1275 answer = input()
1438 answer = raw_input() # __IGNORE_WARNING__
1439 else:
1440 answer = input()
1441 if answer in ("", "Y", "y"): 1276 if answer in ("", "Y", "y"):
1442 exitCode = subprocess.call( 1277 exitCode = subprocess.call(
1443 [sys.executable, "-m", "pip", "install", packageName]) 1278 [sys.executable, "-m", "pip", "install", packageName])
1444 ok = (exitCode == 0) 1279 ok = (exitCode == 0)
1445 1280
1452 """ 1287 """
1453 print('Checking dependencies') 1288 print('Checking dependencies')
1454 1289
1455 # perform dependency checks 1290 # perform dependency checks
1456 print("Python Version: {0:d}.{1:d}.{2:d}".format(*sys.version_info[:3])) 1291 print("Python Version: {0:d}.{1:d}.{2:d}".format(*sys.version_info[:3]))
1457 if sys.version_info < (2, 7, 10): 1292 if sys.version_info < (3, 5, 0):
1458 print('Sorry, you must have Python 2.7.10 or higher or '
1459 'Python 3.5.0 or higher.')
1460 exit(5)
1461 elif sys.version_info < (3, 5, 0) and sys.version_info[0] == 3:
1462 print('Sorry, you must have Python 3.5.0 or higher.') 1293 print('Sorry, you must have Python 3.5.0 or higher.')
1463 exit(5) 1294 exit(5)
1464 if sys.version_info[0] > 3: 1295 if sys.version_info[0] > 3:
1465 print('Sorry, eric6 requires Python 3 or Python 2 for running.') 1296 print('Sorry, eric6 requires Python 3 for running.')
1466 exit(5) 1297 exit(5)
1467 1298
1468 try: 1299 try:
1469 import xml.etree # __IGNORE_WARNING__ 1300 import xml.etree # __IGNORE_WARNING__
1470 except ImportError: 1301 except ImportError:
1471 print('Your Python installation is missing the XML module.') 1302 print('Your Python installation is missing the XML module.')
1472 print('Please install it and try again.') 1303 print('Please install it and try again.')
1473 exit(5) 1304 exit(5)
1474 1305
1475 if pyqtVariant == "PyQt4": 1306 try:
1476 try: 1307 from PyQt5.QtCore import qVersion
1477 from PyQt4.QtCore import qVersion 1308 except ImportError as msg:
1478 except ImportError as msg: 1309 installed = pipInstall(
1479 print('Sorry, please install PyQt4.') 1310 "PyQt5",
1480 print('Error: {0}'.format(msg)) 1311 "PyQt5 could not be detected.\nError: {0}".format(msg)
1481 exit(1) 1312 )
1482 print("Found PyQt4") 1313 if installed:
1483 else: 1314 # try to import it again
1484 try: 1315 try:
1485 from PyQt5.QtCore import qVersion 1316 from PyQt5.QtCore import qVersion
1486 except ImportError as msg: 1317 except ImportError as msg:
1487 if sys.version_info[0] == 2:
1488 # no PyQt5 wheels available for Python 2
1489 installed = False
1490 else:
1491 installed = pipInstall(
1492 "PyQt5",
1493 "PyQt5 could not be detected.\nError: {0}".format(msg)
1494 )
1495 if installed:
1496 # try to import it again
1497 try:
1498 from PyQt5.QtCore import qVersion
1499 except ImportError as msg:
1500 print('Sorry, please install PyQt5.')
1501 print('Error: {0}'.format(msg))
1502 exit(1)
1503 else:
1504 print('Sorry, please install PyQt5.') 1318 print('Sorry, please install PyQt5.')
1505 print('Error: {0}'.format(msg)) 1319 print('Error: {0}'.format(msg))
1506 exit(1) 1320 exit(1)
1507 print("Found PyQt5")
1508
1509 try:
1510 if pyqtVariant == "PyQt4":
1511 pyuic = "pyuic4"
1512 from PyQt4 import uic # __IGNORE_WARNING__
1513 else: 1321 else:
1514 pyuic = "pyuic5" 1322 print('Sorry, please install PyQt5.')
1515 from PyQt5 import uic # __IGNORE_WARNING__ 1323 print('Error: {0}'.format(msg))
1324 exit(1)
1325 print("Found PyQt5")
1326
1327 try:
1328 pyuic = "pyuic5"
1329 from PyQt5 import uic # __IGNORE_WARNING__
1516 except ImportError as msg: 1330 except ImportError as msg:
1517 print("Sorry, {0} is not installed.".format(pyuic)) 1331 print("Sorry, {0} is not installed.".format(pyuic))
1518 print('Error: {0}'.format(msg)) 1332 print('Error: {0}'.format(msg))
1519 exit(1) 1333 exit(1)
1520 print("Found {0}".format(pyuic)) 1334 print("Found {0}".format(pyuic))
1521 1335
1522 if pyqtVariant != "PyQt4": 1336 try:
1523 try: 1337 from PyQt5 import QtWebEngineWidgets # __IGNORE_WARNING__
1524 from PyQt5 import QtWebEngineWidgets # __IGNORE_WARNING__ 1338 except ImportError as msg:
1525 except ImportError as msg: 1339 from PyQt5.QtCore import PYQT_VERSION
1526 from PyQt5.QtCore import PYQT_VERSION 1340 if PYQT_VERSION >= 0x50c00:
1527 if PYQT_VERSION >= 0x50c00: 1341 # PyQt 5.12 separated QtWebEngine into a separate wheel
1528 # PyQt 5.12 separated QtWebEngine into a separate wheel
1529 installed = pipInstall(
1530 "PyQtWebEngine",
1531 "PyQtWebEngine could not be detected.\nError: {0}"
1532 .format(msg)
1533 )
1534
1535 try:
1536 from PyQt5 import QtChart # __IGNORE_WARNING__
1537 except ImportError as msg:
1538 installed = pipInstall( 1342 installed = pipInstall(
1539 "PyQtChart", 1343 "PyQtWebEngine",
1540 "PyQtChart could not be detected.\nError: {0}" 1344 "PyQtWebEngine could not be detected.\nError: {0}"
1541 .format(msg) 1345 .format(msg)
1542 ) 1346 )
1543 1347
1544 try: 1348 try:
1545 if pyqtVariant == "PyQt4": 1349 from PyQt5 import QtChart # __IGNORE_WARNING__
1546 from PyQt4 import Qsci # __IGNORE_WARNING__ 1350 except ImportError as msg:
1351 installed = pipInstall(
1352 "PyQtChart",
1353 "PyQtChart could not be detected.\nError: {0}"
1354 .format(msg)
1355 )
1356
1357 try:
1358 from PyQt5 import Qsci # __IGNORE_WARNING__
1359 except ImportError as msg:
1360 installed = pipInstall(
1361 "QScintilla",
1362 "QScintilla could not be detected.\nError: {0}".format(msg)
1363 )
1364 if installed:
1365 # try to import it again
1366 try:
1367 from PyQt5 import Qsci # __IGNORE_WARNING__
1368 message = None
1369 except ImportError as msg:
1370 message = str(msg)
1547 else: 1371 else:
1548 from PyQt5 import Qsci # __IGNORE_WARNING__ 1372 message = "QScintilla could not be installed."
1549 except ImportError as msg:
1550 if pyqtVariant == "PyQt4":
1551 message = str(msg)
1552 else:
1553 installed = pipInstall(
1554 "QScintilla",
1555 "QScintilla could not be detected.\nError: {0}".format(msg)
1556 )
1557 if installed:
1558 # try to import it again
1559 try:
1560 from PyQt5 import Qsci # __IGNORE_WARNING__
1561 message = None
1562 except ImportError as msg:
1563 message = str(msg)
1564 else:
1565 message = "QScintilla could not be installed."
1566 if message: 1373 if message:
1567 print("Sorry, please install QScintilla2 and") 1374 print("Sorry, please install QScintilla2 and")
1568 print("its PyQt5/PyQt4 wrapper.") 1375 print("its PyQt5 wrapper.")
1569 print('Error: {0}'.format(message)) 1376 print('Error: {0}'.format(message))
1570 exit(1) 1377 exit(1)
1571 print("Found QScintilla2") 1378 print("Found QScintilla2")
1572 1379
1573 if pyqtVariant == "PyQt4": 1380 impModulesList = [
1574 impModulesList = [ 1381 "PyQt5.QtGui", "PyQt5.QtNetwork", "PyQt5.QtPrintSupport",
1575 "PyQt4.QtGui", "PyQt4.QtNetwork", "PyQt4.QtSql", 1382 "PyQt5.QtSql", "PyQt5.QtSvg", "PyQt5.QtWidgets",
1576 "PyQt4.QtSvg", "PyQt4.QtWebKit", 1383 ]
1577 ] 1384 altModulesList = [
1578 altModulesList = [] 1385 # Tuple with alternatives, flag indicating it's ok to not be
1579 else: 1386 # available (e.g. for 32-Bit Windows)
1580 impModulesList = [ 1387 (("PyQt5.QtWebEngineWidgets", ), sys.maxsize <= 2**32),
1581 "PyQt5.QtGui", "PyQt5.QtNetwork", "PyQt5.QtPrintSupport", 1388 ]
1582 "PyQt5.QtSql", "PyQt5.QtSvg", "PyQt5.QtWidgets",
1583 ]
1584 altModulesList = [
1585 # Tuple with alternatives, flag indicating it's ok to not be
1586 # available (e.g. for 32-Bit Windows)
1587 (("PyQt5.QtWebEngineWidgets", "PyQt5.QtWebKitWidgets"),
1588 sys.maxsize <= 2**32),
1589 ]
1590 # check mandatory modules 1389 # check mandatory modules
1591 modulesOK = True 1390 modulesOK = True
1592 for impModule in impModulesList: 1391 for impModule in impModulesList:
1593 name = impModule.split(".")[1] 1392 name = impModule.split(".")[1]
1594 try: 1393 try:
1631 1430
1632 # check version of Qt 1431 # check version of Qt
1633 qtMajor = int(qVersion().split('.')[0]) 1432 qtMajor = int(qVersion().split('.')[0])
1634 qtMinor = int(qVersion().split('.')[1]) 1433 qtMinor = int(qVersion().split('.')[1])
1635 print("Qt Version: {0}".format(qVersion().strip())) 1434 print("Qt Version: {0}".format(qVersion().strip()))
1636 if qtMajor < 4 or \ 1435 if qtMajor == 5 and qtMinor < 9:
1637 (qtMajor == 4 and qtMinor < 8) or \ 1436 print('Sorry, you must have Qt version 5.9.0 or better.')
1638 (qtMajor == 5 and qtMinor < 9):
1639 print('Sorry, you must have Qt version 4.8.0 or better or')
1640 print('5.9.0 or better.')
1641 exit(2) 1437 exit(2)
1642 1438
1643 # check version of sip 1439 # check version of sip
1644 try: 1440 try:
1645 try: 1441 try:
1671 exit(3) 1467 exit(3)
1672 except (ImportError, AttributeError): 1468 except (ImportError, AttributeError):
1673 pass 1469 pass
1674 1470
1675 # check version of PyQt 1471 # check version of PyQt
1676 if pyqtVariant == "PyQt4": 1472 from PyQt5.QtCore import PYQT_VERSION_STR
1677 from PyQt4.QtCore import PYQT_VERSION_STR
1678 else:
1679 from PyQt5.QtCore import PYQT_VERSION_STR
1680 pyqtVersion = PYQT_VERSION_STR 1473 pyqtVersion = PYQT_VERSION_STR
1681 print("PyQt Version:", pyqtVersion.strip()) 1474 print("PyQt Version:", pyqtVersion.strip())
1682 # always assume, that snapshots or dev versions are new enough 1475 # always assume, that snapshots or dev versions are new enough
1683 if "snapshot" not in pyqtVersion and "dev" not in pyqtVersion: 1476 if "snapshot" not in pyqtVersion and "dev" not in pyqtVersion:
1684 while pyqtVersion.count('.') < 2: 1477 while pyqtVersion.count('.') < 2:
1685 pyqtVersion += '.0' 1478 pyqtVersion += '.0'
1686 (major, minor, pat) = pyqtVersion.split('.') 1479 (major, minor, pat) = pyqtVersion.split('.')
1687 major = int(major) 1480 major = int(major)
1688 minor = int(minor) 1481 minor = int(minor)
1689 pat = int(pat) 1482 pat = int(pat)
1690 if major < 4 or \ 1483 if major == 5 and minor < 9:
1691 (major == 4 and minor < 10) or \ 1484 print('Sorry, you must have PyQt 5.9.0 or better or'
1692 (major == 5 and minor < 9):
1693 print('Sorry, you must have PyQt 4.10.0 or better or')
1694 print('PyQt 5.9.0 or better or'
1695 ' a recent snapshot release.') 1485 ' a recent snapshot release.')
1696 exit(4) 1486 exit(4)
1697 # check for blacklisted versions 1487 # check for blacklisted versions
1698 for vers in BlackLists[pyqtVariant] + PlatformBlackLists[pyqtVariant]: 1488 for vers in BlackLists["PyQt5"] + PlatformBlackLists["PyQt5"]:
1699 if vers == pyqtVersion: 1489 if vers == pyqtVersion:
1700 print('Sorry, PyQt version {0} is not compatible with eric6.' 1490 print('Sorry, PyQt version {0} is not compatible with eric6.'
1701 .format(vers)) 1491 .format(vers))
1702 print('Please install another version.') 1492 print('Please install another version.')
1703 exit(4) 1493 exit(4)
1704 1494
1705 # check version of QScintilla 1495 # check version of QScintilla
1706 if pyqtVariant == "PyQt4": 1496 from PyQt5.Qsci import QSCINTILLA_VERSION_STR
1707 from PyQt4.Qsci import QSCINTILLA_VERSION_STR
1708 else:
1709 from PyQt5.Qsci import QSCINTILLA_VERSION_STR
1710 scintillaVersion = QSCINTILLA_VERSION_STR 1497 scintillaVersion = QSCINTILLA_VERSION_STR
1711 print("QScintilla Version:", QSCINTILLA_VERSION_STR.strip()) 1498 print("QScintilla Version:", QSCINTILLA_VERSION_STR.strip())
1712 # always assume, that snapshots or dev versions are new enough 1499 # always assume, that snapshots or dev versions are new enough
1713 if "snapshot" not in scintillaVersion and "dev" not in scintillaVersion: 1500 if "snapshot" not in scintillaVersion and "dev" not in scintillaVersion:
1714 while scintillaVersion.count('.') < 2: 1501 while scintillaVersion.count('.') < 2:
1749 1536
1750 def compileUiFiles(): 1537 def compileUiFiles():
1751 """ 1538 """
1752 Compile the .ui files to Python sources. 1539 Compile the .ui files to Python sources.
1753 """ 1540 """
1754 if pyqtVariant == "PyQt4": 1541 from PyQt5.uic import compileUiDir
1755 from PyQt4.uic import compileUiDir
1756 else:
1757 from PyQt5.uic import compileUiDir
1758 compileUiDir(eric6SourceDir, True, __pyName) 1542 compileUiDir(eric6SourceDir, True, __pyName)
1759 1543
1760 1544
1761 def prepareInfoFile(fileName): 1545 def prepareInfoFile(fileName):
1762 """ 1546 """
1771 os.rename(fileName, fileName + ".orig") 1555 os.rename(fileName, fileName + ".orig")
1772 except EnvironmentError: 1556 except EnvironmentError:
1773 pass 1557 pass
1774 try: 1558 try:
1775 hgOut = subprocess.check_output(["hg", "identify", "-i"]) 1559 hgOut = subprocess.check_output(["hg", "identify", "-i"])
1776 if sys.version_info[0] == 3: 1560 hgOut = hgOut.decode()
1777 hgOut = hgOut.decode()
1778 except (OSError, subprocess.CalledProcessError): 1561 except (OSError, subprocess.CalledProcessError):
1779 hgOut = "" 1562 hgOut = ""
1780 if hgOut: 1563 if hgOut:
1781 hgOut = hgOut.strip() 1564 hgOut = hgOut.strip()
1782 if hgOut.endswith("+"): 1565 if hgOut.endswith("+"):
1783 hgOut = hgOut[:-1] 1566 hgOut = hgOut[:-1]
1784 if sys.version_info[0] == 2: 1567 f = open(fileName + ".orig", "r", encoding="utf-8")
1785 f = codecs.open(fileName + ".orig", "r", "utf-8")
1786 else:
1787 f = open(fileName + ".orig", "r", encoding="utf-8")
1788 text = f.read() 1568 text = f.read()
1789 f.close() 1569 f.close()
1790 text = text.replace("@@REVISION@@", hgOut)\ 1570 text = text.replace("@@REVISION@@", hgOut)\
1791 .replace("@@VERSION@@", "rev_" + hgOut) 1571 .replace("@@VERSION@@", "rev_" + hgOut)
1792 copyToFile(fileName, text) 1572 copyToFile(fileName, text)
1804 @type str 1584 @type str
1805 @return value of requested registry variable 1585 @return value of requested registry variable
1806 @rtype any 1586 @rtype any
1807 """ 1587 """
1808 try: 1588 try:
1809 import _winreg as winreg 1589 import winreg
1810 except ImportError: 1590 except ImportError:
1811 try: 1591 return None
1812 import winreg
1813 except ImportError:
1814 return None
1815 1592
1816 try: 1593 try:
1817 registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, 1594 registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0,
1818 winreg.KEY_READ) 1595 winreg.KEY_READ)
1819 value, _ = winreg.QueryValueEx(registryKey, name) 1596 value, _ = winreg.QueryValueEx(registryKey, name)
1865 1642
1866 @return list of tuples containing the desktop link name, 1643 @return list of tuples containing the desktop link name,
1867 the link target and the icon target 1644 the link target and the icon target
1868 @rtype list of tuples of (str, str, str) 1645 @rtype list of tuples of (str, str, str)
1869 """ 1646 """
1870 global cfg, includePythonVariant 1647 global cfg
1871
1872 if includePythonVariant:
1873 marker = PythonMarkers[sys.version_info.major]
1874 else:
1875 marker = ""
1876 1648
1877 majorVersion, minorVersion = sys.version_info[:2] 1649 majorVersion, minorVersion = sys.version_info[:2]
1878 entriesTemplates = [ 1650 entriesTemplates = [
1879 ("eric6 (Python {0}.{1}).lnk", 1651 ("eric6 (Python {0}.{1}).lnk",
1880 os.path.join(cfg["bindir"], "eric6" + marker + ".cmd"), 1652 os.path.join(cfg["bindir"], "eric6.cmd"),
1881 os.path.join(cfg["ericPixDir"], "eric6.ico")), 1653 os.path.join(cfg["ericPixDir"], "eric6.ico")),
1654 ("eric6 Browser (Python {0}.{1}).lnk",
1655 os.path.join(cfg["bindir"], "eric6_browse.cmd"),
1656 os.path.join(cfg["ericPixDir"], "ericWeb48.ico")),
1882 ] 1657 ]
1883 if sys.version_info.major == 2:
1884 entriesTemplates.append((
1885 "eric6 Browser (Python {0}.{1}).lnk",
1886 os.path.join(cfg["bindir"], "eric6_webbrowser" + marker + ".cmd"),
1887 os.path.join(cfg["ericPixDir"], "ericWeb48.ico")
1888 ))
1889 else:
1890 entriesTemplates.append((
1891 "eric6 Browser (Python {0}.{1}).lnk",
1892 os.path.join(cfg["bindir"], "eric6_browser" + marker + ".cmd"),
1893 os.path.join(cfg["ericPixDir"], "ericWeb48.ico")
1894 ))
1895 1658
1896 return [ 1659 return [
1897 (e[0].format(majorVersion, minorVersion), e[1], e[2]) 1660 (e[0].format(majorVersion, minorVersion), e[1], e[2])
1898 for e in entriesTemplates 1661 for e in entriesTemplates
1899 ] 1662 ]
1904 Function to generate the name of the Start Menu top entry. 1667 Function to generate the name of the Start Menu top entry.
1905 1668
1906 @return name of the Start Menu top entry 1669 @return name of the Start Menu top entry
1907 @rtype str 1670 @rtype str
1908 """ 1671 """
1909 majorVersion, minorVersion = sys.version_info[:2] 1672 return "eric6"
1910 return "eric6 (Python {0}.{1})".format(majorVersion, minorVersion)
1911 1673
1912 1674
1913 def main(argv): 1675 def main(argv):
1914 """ 1676 """
1915 The main function of the script. 1677 The main function of the script.
1919 """ 1681 """
1920 import getopt 1682 import getopt
1921 1683
1922 # Parse the command line. 1684 # Parse the command line.
1923 global progName, modDir, doCleanup, doCompile, distDir, cfg, apisDir 1685 global progName, modDir, doCleanup, doCompile, distDir, cfg, apisDir
1924 global sourceDir, eric6SourceDir, configName, includePythonVariant 1686 global sourceDir, eric6SourceDir, configName
1925 global macAppBundlePath, macAppBundleName, macPythonExe 1687 global macAppBundlePath, macAppBundleName, macPythonExe
1926 global pyqtVariant, pyqtOverride, installApis, doCleanDesktopLinks 1688 global installApis, doCleanDesktopLinks
1927 1689
1928 if sys.version_info < (2, 7, 0) or sys.version_info > (3, 9, 9): 1690 if sys.version_info < (3, 5, 0) or sys.version_info > (3, 99, 99):
1929 print('Sorry, eric6 requires at least Python 2.7 or ' 1691 print('Sorry, eric6 requires at least Python 3.5 for running.')
1930 'Python 3 for running.')
1931 exit(5) 1692 exit(5)
1932 1693
1933 progName = os.path.basename(argv[0]) 1694 progName = os.path.basename(argv[0])
1934 1695
1935 if os.path.dirname(argv[0]): 1696 if os.path.dirname(argv[0]):
1936 os.chdir(os.path.dirname(argv[0])) 1697 os.chdir(os.path.dirname(argv[0]))
1937 1698
1938 determinePyQtVariant()
1939 initGlobals() 1699 initGlobals()
1940 1700
1941 try: 1701 try:
1942 if sys.platform.startswith(("win", "cygwin")): 1702 if sys.platform.startswith(("win", "cygwin")):
1943 optlist, args = getopt.getopt( 1703 optlist, args = getopt.getopt(
1944 argv[1:], "chxyza:b:d:f:", 1704 argv[1:], "chxza:b:d:f:",
1945 ["help", "pyqt=", "no-apis"]) 1705 ["help", "no-apis"])
1946 elif sys.platform == "darwin": 1706 elif sys.platform == "darwin":
1947 optlist, args = getopt.getopt( 1707 optlist, args = getopt.getopt(
1948 argv[1:], "chxyza:b:d:f:i:m:n:p:", 1708 argv[1:], "chxza:b:d:f:i:m:n:p:",
1949 ["help", "pyqt=", "no-apis"]) 1709 ["help", "no-apis"])
1950 else: 1710 else:
1951 optlist, args = getopt.getopt( 1711 optlist, args = getopt.getopt(
1952 argv[1:], "chxyza:b:d:f:i:", 1712 argv[1:], "chxza:b:d:f:i:",
1953 ["help", "pyqt=", "no-apis"]) 1713 ["help", "no-apis"])
1954 except getopt.GetoptError as err: 1714 except getopt.GetoptError as err:
1955 print(err) 1715 print(err)
1956 usage() 1716 usage()
1957 1717
1958 global platBinDir 1718 global platBinDir
1974 depChecks = False 1734 depChecks = False
1975 elif opt == "-c": 1735 elif opt == "-c":
1976 doCleanup = False 1736 doCleanup = False
1977 elif opt == "-z": 1737 elif opt == "-z":
1978 doCompile = False 1738 doCompile = False
1979 elif opt == "-y":
1980 includePythonVariant = True
1981 elif opt == "-f": 1739 elif opt == "-f":
1982 try: 1740 try:
1983 exec(compile(open(arg).read(), arg, 'exec'), globals()) 1741 exec(compile(open(arg).read(), arg, 'exec'), globals())
1984 if len(cfg) != configLength: 1742 if len(cfg) != configLength:
1985 print("The configuration dictionary in '{0}' is incorrect." 1743 print("The configuration dictionary in '{0}' is incorrect."
1991 macAppBundleName = arg 1749 macAppBundleName = arg
1992 elif opt == "-n": 1750 elif opt == "-n":
1993 macAppBundlePath = arg 1751 macAppBundlePath = arg
1994 elif opt == "-p": 1752 elif opt == "-p":
1995 macPythonExe = arg 1753 macPythonExe = arg
1996 elif opt == "--pyqt":
1997 if arg not in ["4", "5"]:
1998 print("Invalid PyQt version given; should be 4 or 5. Aborting")
1999 exit(6)
2000 pyqtVariant = "PyQt{0}".format(arg)
2001 pyqtOverride = True
2002 elif opt == "--no-apis": 1754 elif opt == "--no-apis":
2003 installApis = False 1755 installApis = False
2004 elif opt == "--clean-desktop": 1756 elif opt == "--clean-desktop":
2005 doCleanDesktopLinks = True 1757 doCleanDesktopLinks = True
2006 1758
2067 # step 2: compile the forms 1819 # step 2: compile the forms
2068 compileUiFiles() 1820 compileUiFiles()
2069 1821
2070 if doCompile: 1822 if doCompile:
2071 print("\nCompiling source files ...") 1823 print("\nCompiling source files ...")
2072 # Hide compile errors (mainly because of Py2/Py3 differences)
2073 skipRe = re.compile(r"DebugClients[\\/]Python[\\/]") 1824 skipRe = re.compile(r"DebugClients[\\/]Python[\\/]")
2074 sys.stdout = io.StringIO() 1825 sys.stdout = io.StringIO()
2075 if distDir: 1826 if distDir:
2076 compileall.compile_dir( 1827 compileall.compile_dir(
2077 eric6SourceDir, 1828 eric6SourceDir,

eric ide

mercurial