scripts/install.py

branch
maintenance
changeset 7286
7eb04391adf7
parent 7226
babe80d84a3e
parent 7257
c4d0cac9b5c9
child 7322
cd8ee889589f
equal deleted inserted replaced
7226:babe80d84a3e 7286:7eb04391adf7
6 # This is the install script for eric6. 6 # This is the install script for eric6.
7 7
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
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 11
27 import sys 12 import sys
28 import os 13 import os
29 import re 14 import re
30 import compileall 15 import compileall
31 import py_compile 16 import py_compile
32 import glob 17 import glob
33 import shutil 18 import shutil
34 import fnmatch 19 import fnmatch
35 import codecs
36 import subprocess 20 import subprocess
37 import time 21 import time
22 import io
38 23
39 # Define the globals. 24 # Define the globals.
40 progName = None 25 progName = None
41 currDir = os.getcwd() 26 currDir = os.getcwd()
42 modDir = None 27 modDir = None
48 installApis = True 33 installApis = True
49 doCleanup = True 34 doCleanup = True
50 doCleanDesktopLinks = False 35 doCleanDesktopLinks = False
51 forceCleanDesktopLinks = False 36 forceCleanDesktopLinks = False
52 doCompile = True 37 doCompile = True
53 includePythonVariant = False
54 cfg = {} 38 cfg = {}
55 progLanguages = ["Python", "Ruby", "QSS"] 39 progLanguages = ["Python", "Ruby", "QSS"]
56 sourceDir = "eric" 40 sourceDir = "eric"
57 eric6SourceDir = os.path.join(sourceDir, "eric6") 41 eric6SourceDir = os.path.join(sourceDir, "eric6")
58 configName = 'eric6config.py' 42 configName = 'eric6config.py'
61 defaultMacPythonExe = "{0}/Resources/Python.app/Contents/MacOS/Python".format( 45 defaultMacPythonExe = "{0}/Resources/Python.app/Contents/MacOS/Python".format(
62 sys.exec_prefix) 46 sys.exec_prefix)
63 macAppBundleName = defaultMacAppBundleName 47 macAppBundleName = defaultMacAppBundleName
64 macAppBundlePath = defaultMacAppBundlePath 48 macAppBundlePath = defaultMacAppBundlePath
65 macPythonExe = defaultMacPythonExe 49 macPythonExe = defaultMacPythonExe
66 pyqtVariant = ""
67 pyqtOverride = False
68 50
69 # Define blacklisted versions of the prerequisites 51 # Define blacklisted versions of the prerequisites
70 BlackLists = { 52 BlackLists = {
71 "sip": [], 53 "sip": [],
72 "PyQt4": [],
73 "PyQt5": [], 54 "PyQt5": [],
74 "QScintilla2": [], 55 "QScintilla2": [],
75 } 56 }
76 PlatformsBlackLists = { 57 PlatformsBlackLists = {
77 "windows": { 58 "windows": {
78 "sip": [], 59 "sip": [],
79 "PyQt4": [],
80 "PyQt5": [], 60 "PyQt5": [],
81 "QScintilla2": [], 61 "QScintilla2": [],
82 }, 62 },
83 63
84 "linux": { 64 "linux": {
85 "sip": [], 65 "sip": [],
86 "PyQt4": [],
87 "PyQt5": [], 66 "PyQt5": [],
88 "QScintilla2": [], 67 "QScintilla2": [],
89 }, 68 },
90 69
91 "mac": { 70 "mac": {
92 "sip": [], 71 "sip": [],
93 "PyQt4": [],
94 "PyQt5": [], 72 "PyQt5": [],
95 "QScintilla2": [], 73 "QScintilla2": [],
96 }, 74 },
97 } 75 }
98 76
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 77
111 def exit(rcode=0): 78 def exit(rcode=0):
112 """ 79 """
113 Exit the install script. 80 Exit the install script.
114 81
117 global currDir 84 global currDir
118 85
119 print() 86 print()
120 87
121 if sys.platform.startswith(("win", "cygwin")): 88 if sys.platform.startswith(("win", "cygwin")):
122 # different meaning of input between Py2 and Py3
123 try: 89 try:
124 input("Press enter to continue...") 90 input("Press enter to continue...")
125 except (EOFError, SyntaxError): 91 except (EOFError, SyntaxError):
126 pass 92 pass
127 93
136 102
137 @param rcode the return code passed back to the calling process. 103 @param rcode the return code passed back to the calling process.
138 """ 104 """
139 global progName, modDir, distDir, apisDir 105 global progName, modDir, distDir, apisDir
140 global macAppBundleName, macAppBundlePath, macPythonExe 106 global macAppBundleName, macAppBundlePath, macPythonExe
141 global pyqtVariant
142 107
143 print() 108 print()
144 print("Usage:") 109 print("Usage:")
145 if sys.platform == "darwin": 110 if sys.platform == "darwin":
146 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]" 111 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
147 " [-m name] [-n path] [-p python] [--no-apis] [--pyqt=version]" 112 " [-m name] [-n path] [-p python] [--no-apis]"
148 .format(progName)) 113 .format(progName))
149 elif sys.platform.startswith(("win", "cygwin")): 114 elif sys.platform.startswith(("win", "cygwin")):
150 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file]" 115 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file]"
151 " [--clean-desktop] [--no-apis] [--pyqt=version]" 116 " [--clean-desktop] [--no-apis]"
152 .format(progName)) 117 .format(progName))
153 else: 118 else:
154 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]" 119 print(" {0} [-chxyz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]"
155 " [--no-apis] [--pyqt=version]" 120 " [--no-apis]"
156 .format(progName)) 121 .format(progName))
157 print("where:") 122 print("where:")
158 print(" -h, --help display this help message") 123 print(" -h, --help display this help message")
159 print(" -a dir where the API files will be installed") 124 print(" -a dir where the API files will be installed")
160 if apisDir: 125 if apisDir:
182 print(" -c don't cleanup old installation first") 147 print(" -c don't cleanup old installation first")
183 if sys.platform.startswith(("win", "cygwin")): 148 if sys.platform.startswith(("win", "cygwin")):
184 (" --clean-desktop delete desktop links before installation") 149 (" --clean-desktop delete desktop links before installation")
185 print(" -x don't perform dependency checks (use on your own" 150 print(" -x don't perform dependency checks (use on your own"
186 " risk)") 151 " risk)")
187 print(" -y add the Python variant to the executable names")
188 print(" -z don't compile the installed python files") 152 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() 153 print()
195 print("The file given to the -f option must be valid Python code" 154 print("The file given to the -f option must be valid Python code"
196 " defining a") 155 " defining a")
197 print("dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir'," 156 print("dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir',"
198 " 'ericIconDir',") 157 " 'ericIconDir',")
204 " parts of eric6.") 163 " parts of eric6.")
205 164
206 exit(rcode) 165 exit(rcode)
207 166
208 167
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(): 168 def initGlobals():
239 """ 169 """
240 Module function to set the values of globals that need more than a 170 Module function to set the values of globals that need more than a
241 simple assignment. 171 simple assignment.
242 """ 172 """
243 global platBinDir, modDir, pyModDir, apisDir, pyqtVariant, platBinDirOld 173 global platBinDir, modDir, pyModDir, apisDir, platBinDirOld
244 174
245 try: 175 try:
246 import distutils.sysconfig 176 import distutils.sysconfig
247 except ImportError: 177 except ImportError:
248 print("Please install the 'distutils' package first.") 178 print("Please install the 'distutils' package first.")
262 # install the eric scripts along the python executable 192 # install the eric scripts along the python executable
263 platBinDir = pyBinDir 193 platBinDir = pyBinDir
264 else: 194 else:
265 # install them in the user's bin directory 195 # install them in the user's bin directory
266 platBinDir = os.path.expanduser("~/bin") 196 platBinDir = os.path.expanduser("~/bin")
267 if platBinDir != "/usr/local/bin" and \ 197 if (
268 os.access("/usr/local/bin", os.W_OK): 198 platBinDir != "/usr/local/bin" and
199 os.access("/usr/local/bin", os.W_OK)
200 ):
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 = (
370 .replace("@VERSION@", Version.split(None, 1)[0])\ 282 text.replace("@MARKER@", "")
283 .replace("@VERSION@", Version.split(None, 1)[0])
371 .replace("@DATE@", time.strftime("%Y-%m-%d")) 284 .replace("@DATE@", time.strftime("%Y-%m-%d"))
372 285 )
373 if sys.version_info[0] == 2: 286
374 f = codecs.open(dst, "w", "utf-8") 287 f = open(dst, "w", encoding="utf-8")
375 else:
376 f = open(dst, "w", encoding="utf-8")
377 f.write(text) 288 f.write(text)
378 f.close() 289 f.close()
379 os.chmod(dst, 0o644) 290 os.chmod(dst, 0o644)
380 291
381 292
406 @param saveDir directory to save the file into (string) 317 @param saveDir directory to save the file into (string)
407 @param isGuiScript flag indicating a wrapper script for a GUI 318 @param isGuiScript flag indicating a wrapper script for a GUI
408 application (boolean) 319 application (boolean)
409 @return the platform specific name of the wrapper (string) 320 @return the platform specific name of the wrapper (string)
410 """ 321 """
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 322 # all kinds of Windows systems
424 if sys.platform.startswith(("win", "cygwin")): 323 if sys.platform.startswith(("win", "cygwin")):
425 wname = wfile + marker + ".cmd" 324 wname = wfile + ".cmd"
426 if isGuiScript: 325 if isGuiScript:
427 wrapper = \ 326 wrapper = (
428 '''@echo off\n''' \ 327 '''@echo off\n'''
429 '''start "" "{2}\\pythonw.exe"''' \ 328 '''start "" "{2}\\pythonw.exe"'''
430 ''' "{0}\\{1}.pyw"{3}''' \ 329 ''' "{0}\\{1}.pyw"'''
431 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format( 330 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format(
432 pydir, wfile, sys.exec_prefix, pyqt4opt) 331 pydir, wfile, sys.exec_prefix)
332 )
433 else: 333 else:
434 wrapper = \ 334 wrapper = (
435 '''@"{0}\\python" "{1}\\{2}.py"{3}''' \ 335 '''@"{0}\\python" "{1}\\{2}.py"'''
436 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format( 336 ''' %1 %2 %3 %4 %5 %6 %7 %8 %9\n'''.format(
437 sys.exec_prefix, pydir, wfile, pyqt4opt) 337 sys.exec_prefix, pydir, wfile)
338 )
438 339
439 # Mac OS X 340 # Mac OS X
440 elif sys.platform == "darwin": 341 elif sys.platform == "darwin":
441 major = sys.version_info.major 342 major = sys.version_info.major
442 pyexec = "{0}/bin/pythonw{1}".format(sys.exec_prefix, major) 343 pyexec = "{0}/bin/pythonw{1}".format(sys.exec_prefix, major)
443 if not os.path.exists(pyexec): 344 if not os.path.exists(pyexec):
444 pyexec = "{0}/bin/python{1}".format(sys.exec_prefix, major) 345 pyexec = "{0}/bin/python{1}".format(sys.exec_prefix, major)
445 wname = wfile + marker 346 wname = wfile
446 wrapper = ('''#!/bin/sh\n''' 347 wrapper = ('''#!/bin/sh\n'''
447 '''\n''' 348 '''\n'''
448 '''exec "{0}" "{1}/{2}.py"{3} "$@"\n''' 349 '''exec "{0}" "{1}/{2}.py" "$@"\n'''
449 .format(pyexec, pydir, wfile, pyqt4opt)) 350 .format(pyexec, pydir, wfile))
450 351
451 # *nix systems 352 # *nix systems
452 else: 353 else:
453 wname = wfile + marker 354 wname = wfile
454 wrapper = ('''#!/bin/sh\n''' 355 wrapper = ('''#!/bin/sh\n'''
455 '''\n''' 356 '''\n'''
456 '''exec "{0}" "{1}/{2}.py"{3} "$@"\n''' 357 '''exec "{0}" "{1}/{2}.py" "$@"\n'''
457 .format(sys.executable, pydir, wfile, pyqt4opt)) 358 .format(sys.executable, pydir, wfile))
458 359
459 wname = os.path.join(saveDir, wname) 360 wname = os.path.join(saveDir, wname)
460 copyToFile(wname, wrapper) 361 copyToFile(wname, wrapper)
461 os.chmod(wname, 0o755) 362 os.chmod(wname, 0o755)
462 363
572 473
573 def cleanUp(): 474 def cleanUp():
574 """ 475 """
575 Uninstall the old eric files. 476 Uninstall the old eric files.
576 """ 477 """
577 global platBinDir, platBinDirOld, includePythonVariant 478 global platBinDir, platBinDirOld
578 479
579 try: 480 try:
580 from eric6config import getConfig 481 from eric6config import getConfig
581 except ImportError: 482 except ImportError:
582 # eric6 wasn't installed previously 483 # eric6 wasn't installed previously
603 "eric6_trpreviewer", "eric6_uipreviewer", 504 "eric6_trpreviewer", "eric6_uipreviewer",
604 "eric6_unittest", "eric6", 505 "eric6_unittest", "eric6",
605 "eric6_tray", "eric6_editor", 506 "eric6_tray", "eric6_editor",
606 "eric6_plugininstall", "eric6_pluginuninstall", 507 "eric6_plugininstall", "eric6_pluginuninstall",
607 "eric6_pluginrepository", "eric6_sqlbrowser", 508 "eric6_pluginrepository", "eric6_sqlbrowser",
608 "eric6_webbrowser", "eric6_iconeditor", 509 "eric6_iconeditor", "eric6_snap", "eric6_hexeditor",
609 "eric6_snap", "eric6_hexeditor", "eric6_browser", 510 "eric6_browser", "eric6_shell",
610 "eric6_shell", 511 # from Python2 era
512 "eric6_webbrowser",
611 ] 513 ]
612 if includePythonVariant:
613 marker = PythonMarkers[sys.version_info.major]
614 rem_wnames = [n + marker for n in rem_wnames]
615 514
616 try: 515 try:
617 dirs = [platBinDir, getConfig('bindir')] 516 dirs = [platBinDir, getConfig('bindir')]
618 if platBinDirOld: 517 if platBinDirOld:
619 dirs.append(platBinDirOld) 518 dirs.append(platBinDirOld)
678 if os.getuid() == 0: 577 if os.getuid() == 0:
679 for name in ["/usr/share/pixmaps/eric.png", 578 for name in ["/usr/share/pixmaps/eric.png",
680 "/usr/share/pixmaps/ericWeb.png"]: 579 "/usr/share/pixmaps/ericWeb.png"]:
681 if os.path.exists(name): 580 if os.path.exists(name):
682 os.remove(name) 581 os.remove(name)
683 if includePythonVariant:
684 marker = PythonMarkers[sys.version_info.major]
685 else:
686 marker = ""
687 for name in [ 582 for name in [
688 "/usr/share/applications/eric6" + marker + ".desktop", 583 "/usr/share/applications/eric6.desktop",
689 "/usr/share/appdata/eric6" + marker + ".appdata.xml", 584 "/usr/share/appdata/eric6.appdata.xml",
690 "/usr/share/metainfo/eric6" + marker + ".appdata.xml", 585 "/usr/share/metainfo/eric6.appdata.xml",
691 "/usr/share/applications/eric6_webbrowser" + marker + 586 "/usr/share/applications/eric6_browser.desktop",
692 ".desktop", 587 "/usr/share/pixmaps/eric.png",
693 "/usr/share/applications/eric6_browser" + marker + 588 "/usr/share/pixmaps/ericWeb.png",
694 ".desktop", 589 # from Python2 era
695 "/usr/share/pixmaps/eric" + marker + ".png", 590 "/usr/share/applications/eric6_webbrowser.desktop",
696 "/usr/share/pixmaps/ericWeb" + marker + ".png",
697 ]: 591 ]:
698 if os.path.exists(name): 592 if os.path.exists(name):
699 os.remove(name) 593 os.remove(name)
700 elif os.getuid() >= 1000: 594 elif os.getuid() >= 1000:
701 # it is assumed that user ids start at 1000 595 # it is assumed that user ids start at 1000
702 for name in ["~/.local/share/pixmaps/eric.png", 596 for name in ["~/.local/share/pixmaps/eric.png",
703 "~/.local/share/pixmaps/ericWeb.png"]: 597 "~/.local/share/pixmaps/ericWeb.png"]:
704 path = os.path.expanduser(name) 598 path = os.path.expanduser(name)
705 if os.path.exists(path): 599 if os.path.exists(path):
706 os.remove(path) 600 os.remove(path)
707 if includePythonVariant:
708 marker = PythonMarkers[sys.version_info.major]
709 else:
710 marker = ""
711 for name in [ 601 for name in [
712 "~/.local/share/applications/eric6" + marker + ".desktop", 602 "~/.local/share/applications/eric6.desktop",
713 "~/.local/share/appdata/eric6" + marker + ".appdata.xml", 603 "~/.local/share/appdata/eric6.appdata.xml",
714 "~/.local/share/metainfo/eric6" + marker + ".appdata.xml", 604 "~/.local/share/metainfo/eric6.appdata.xml",
715 "~/.local/share/applications/eric6_webbrowser" + marker + 605 "~/.local/share/applications/eric6_browser.desktop",
716 ".desktop", 606 "~/.local/share/pixmaps/eric.png",
717 "~/.local/share/applications/eric6_browser" + marker + 607 "~/.local/share/pixmaps/ericWeb.png",
718 ".desktop", 608 # from Python2 era
719 "~/.local/share/pixmaps/eric" + marker + ".png", 609 "/usr/share/applications/eric6_webbrowser.desktop",
720 "~/.local/share/pixmaps/ericWeb" + marker + ".png",
721 ]: 610 ]:
722 path = os.path.expanduser(name) 611 path = os.path.expanduser(name)
723 if os.path.exists(path): 612 if os.path.exists(path):
724 os.remove(path) 613 os.remove(path)
725 614
754 from pywintypes import com_error # __IGNORE_WARNING__ 643 from pywintypes import com_error # __IGNORE_WARNING__
755 except ImportError: 644 except ImportError:
756 # links were not created by install.py 645 # links were not created by install.py
757 return 646 return
758 647
759 regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" + \ 648 regPath = (
760 "\\User Shell Folders" 649 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" +
650 "\\User Shell Folders"
651 )
761 652
762 if doCleanDesktopLinks or forceCleanDesktopLinks: 653 if doCleanDesktopLinks or forceCleanDesktopLinks:
763 # 1. cleanup desktop links 654 # 1. cleanup desktop links
764 regName = "Desktop" 655 regName = "Desktop"
765 desktopEntry = getWinregEntry(regName, regPath) 656 desktopEntry = getWinregEntry(regName, regPath)
807 Actually perform the installation steps. 698 Actually perform the installation steps.
808 699
809 @return result code (integer) 700 @return result code (integer)
810 """ 701 """
811 global distDir, doCleanup, cfg, progLanguages, sourceDir, configName 702 global distDir, doCleanup, cfg, progLanguages, sourceDir, configName
812 global includePythonVariant, installApis 703 global installApis
813 704
814 # Create the platform specific wrappers. 705 # Create the platform specific wrappers.
815 scriptsDir = "install_scripts" 706 scriptsDir = "install_scripts"
816 if not os.path.isdir(scriptsDir): 707 if not os.path.isdir(scriptsDir):
817 os.mkdir(scriptsDir) 708 os.mkdir(scriptsDir)
822 "eric6_editor", "eric6_hexeditor", "eric6_iconeditor", 713 "eric6_editor", "eric6_hexeditor", "eric6_iconeditor",
823 "eric6_plugininstall", "eric6_pluginrepository", 714 "eric6_plugininstall", "eric6_pluginrepository",
824 "eric6_pluginuninstall", "eric6_qregexp", 715 "eric6_pluginuninstall", "eric6_qregexp",
825 "eric6_qregularexpression", "eric6_re", "eric6_snap", 716 "eric6_qregularexpression", "eric6_re", "eric6_snap",
826 "eric6_sqlbrowser", "eric6_tray", "eric6_trpreviewer", 717 "eric6_sqlbrowser", "eric6_tray", "eric6_trpreviewer",
827 "eric6_uipreviewer", "eric6_unittest", "eric6_webbrowser", 718 "eric6_uipreviewer", "eric6_unittest", "eric6_browser",
828 "eric6_browser", "eric6_shell", "eric6"]: 719 "eric6_shell", "eric6"]:
829 wnames.append(createPyWrapper(cfg['ericDir'], name, scriptsDir)) 720 wnames.append(createPyWrapper(cfg['ericDir'], name, scriptsDir))
830 721
831 # set install prefix, if not None 722 # set install prefix, if not None
832 if distDir: 723 if distDir:
833 for key in list(cfg.keys()): 724 for key in list(cfg.keys()):
1014 905
1015 def createLinuxSpecifics(): 906 def createLinuxSpecifics():
1016 """ 907 """
1017 Install Linux specific files. 908 Install Linux specific files.
1018 """ 909 """
1019 global distDir, sourceDir, includePythonVariant 910 global distDir, sourceDir
1020 911
1021 if includePythonVariant:
1022 marker = PythonMarkers[sys.version_info.major]
1023 else:
1024 marker = ""
1025
1026 if distDir: 912 if distDir:
1027 dst = os.path.normpath(os.path.join(distDir, "usr/share/pixmaps")) 913 dst = os.path.normpath(os.path.join(distDir, "usr/share/pixmaps"))
1028 if not os.path.exists(dst): 914 if not os.path.exists(dst):
1029 os.makedirs(dst) 915 os.makedirs(dst)
1030 shutilCopy( 916 shutilCopy(
1031 os.path.join(eric6SourceDir, "icons", "default", "eric.png"), 917 os.path.join(eric6SourceDir, "icons", "default", "eric.png"),
1032 os.path.join(dst, "eric" + marker + ".png")) 918 os.path.join(dst, "eric.png"))
1033 shutilCopy( 919 shutilCopy(
1034 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"), 920 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"),
1035 os.path.join(dst, "ericWeb" + marker + ".png")) 921 os.path.join(dst, "ericWeb.png"))
1036 dst = os.path.normpath( 922 dst = os.path.normpath(
1037 os.path.join(distDir, "usr/share/applications")) 923 os.path.join(distDir, "usr/share/applications"))
1038 if not os.path.exists(dst): 924 if not os.path.exists(dst):
1039 os.makedirs(dst) 925 os.makedirs(dst)
1040 copyDesktopFile(os.path.join(sourceDir, "linux", "eric6.desktop.in"), 926 copyDesktopFile(os.path.join(sourceDir, "linux", "eric6.desktop.in"),
1041 os.path.join(dst, "eric6" + marker + ".desktop"), 927 os.path.join(dst, "eric6.desktop"))
1042 marker)
1043 copyDesktopFile(
1044 os.path.join(sourceDir, "linux", "eric6_webbrowser.desktop.in"),
1045 os.path.join(dst, "eric6_webbrowser" + marker + ".desktop"),
1046 marker)
1047 copyDesktopFile( 928 copyDesktopFile(
1048 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"), 929 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"),
1049 os.path.join(dst, "eric6_browser" + marker + ".desktop"), 930 os.path.join(dst, "eric6_browser.desktop"))
1050 marker)
1051 dst = os.path.normpath( 931 dst = os.path.normpath(
1052 os.path.join(distDir, "usr/share/metainfo")) 932 os.path.join(distDir, "usr/share/metainfo"))
1053 if not os.path.exists(dst): 933 if not os.path.exists(dst):
1054 os.makedirs(dst) 934 os.makedirs(dst)
1055 copyAppStreamFile( 935 copyAppStreamFile(
1056 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 936 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1057 os.path.join(dst, "eric6" + marker + ".appdata.xml"), 937 os.path.join(dst, "eric6.appdata.xml"))
1058 marker)
1059 elif os.getuid() == 0: 938 elif os.getuid() == 0:
1060 shutilCopy(os.path.join( 939 shutilCopy(os.path.join(
1061 eric6SourceDir, "icons", "default", "eric.png"), 940 eric6SourceDir, "icons", "default", "eric.png"),
1062 "/usr/share/pixmaps/eric" + marker + ".png") 941 "/usr/share/pixmaps/eric.png")
1063 copyDesktopFile( 942 copyDesktopFile(
1064 os.path.join(sourceDir, "linux", "eric6.desktop.in"), 943 os.path.join(sourceDir, "linux", "eric6.desktop.in"),
1065 "/usr/share/applications/eric6" + marker + ".desktop", 944 "/usr/share/applications/eric6.desktop")
1066 marker)
1067 if os.path.exists("/usr/share/metainfo"): 945 if os.path.exists("/usr/share/metainfo"):
1068 copyAppStreamFile( 946 copyAppStreamFile(
1069 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 947 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1070 "/usr/share/metainfo/eric6" + marker + ".appdata.xml", 948 "/usr/share/metainfo/eric6.appdata.xml")
1071 marker)
1072 elif os.path.exists("/usr/share/appdata"): 949 elif os.path.exists("/usr/share/appdata"):
1073 copyAppStreamFile( 950 copyAppStreamFile(
1074 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 951 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1075 "/usr/share/appdata/eric6" + marker + ".appdata.xml", 952 "/usr/share/appdata/eric6.appdata.xml")
1076 marker)
1077 shutilCopy(os.path.join( 953 shutilCopy(os.path.join(
1078 eric6SourceDir, "icons", "default", "ericWeb48.png"), 954 eric6SourceDir, "icons", "default", "ericWeb48.png"),
1079 "/usr/share/pixmaps/ericWeb" + marker + ".png") 955 "/usr/share/pixmaps/ericWeb.png")
1080 copyDesktopFile(
1081 os.path.join(sourceDir, "linux", "eric6_webbrowser.desktop.in"),
1082 "/usr/share/applications/eric6_webbrowser" + marker +
1083 ".desktop",
1084 marker)
1085 copyDesktopFile( 956 copyDesktopFile(
1086 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"), 957 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"),
1087 "/usr/share/applications/eric6_browser" + marker + 958 "/usr/share/applications/eric6_browser.desktop")
1088 ".desktop",
1089 marker)
1090 elif os.getuid() >= 1000: 959 elif os.getuid() >= 1000:
1091 # it is assumed, that user ids start at 1000 960 # it is assumed, that user ids start at 1000
1092 localPath = os.path.join(os.path.expanduser("~"), 961 localPath = os.path.join(os.path.expanduser("~"),
1093 ".local", "share") 962 ".local", "share")
1094 # create directories first 963 # create directories first
1098 if not os.path.isdir(directory): 967 if not os.path.isdir(directory):
1099 os.makedirs(directory) 968 os.makedirs(directory)
1100 # now copy the files 969 # now copy the files
1101 shutilCopy( 970 shutilCopy(
1102 os.path.join(eric6SourceDir, "icons", "default", "eric.png"), 971 os.path.join(eric6SourceDir, "icons", "default", "eric.png"),
1103 os.path.join(localPath, "pixmaps", "eric" + marker + ".png")) 972 os.path.join(localPath, "pixmaps", "eric.png"))
1104 copyDesktopFile( 973 copyDesktopFile(
1105 os.path.join(sourceDir, "linux", "eric6.desktop.in"), 974 os.path.join(sourceDir, "linux", "eric6.desktop.in"),
1106 os.path.join(localPath, "applications", 975 os.path.join(localPath, "applications", "eric6.desktop"))
1107 "eric6" + marker + ".desktop"),
1108 marker)
1109 copyAppStreamFile( 976 copyAppStreamFile(
1110 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 977 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1111 os.path.join(localPath, "metainfo", 978 os.path.join(localPath, "metainfo", "eric6.appdata.xml"))
1112 "eric6" + marker + ".appdata.xml"),
1113 marker)
1114 copyAppStreamFile( 979 copyAppStreamFile(
1115 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"), 980 os.path.join(sourceDir, "linux", "eric6.appdata.xml.in"),
1116 os.path.join(localPath, "appdata", 981 os.path.join(localPath, "appdata", "eric6.appdata.xml"))
1117 "eric6" + marker + ".appdata.xml"),
1118 marker)
1119 shutilCopy( 982 shutilCopy(
1120 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"), 983 os.path.join(eric6SourceDir, "icons", "default", "ericWeb48.png"),
1121 os.path.join(localPath, "pixmaps", 984 os.path.join(localPath, "pixmaps", "ericWeb.png"))
1122 "ericWeb" + marker + ".png"))
1123 copyDesktopFile(
1124 os.path.join(sourceDir, "linux", "eric6_webbrowser.desktop.in"),
1125 os.path.join(localPath, "applications",
1126 "eric6_webbrowser" + marker + ".desktop"),
1127 marker)
1128 copyDesktopFile( 985 copyDesktopFile(
1129 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"), 986 os.path.join(sourceDir, "linux", "eric6_browser.desktop.in"),
1130 os.path.join(localPath, "applications", 987 os.path.join(localPath, "applications", "eric6_browser.desktop"))
1131 "eric6_browser" + marker + ".desktop"),
1132 marker)
1133 988
1134 989
1135 def createWindowsLinks(): 990 def createWindowsLinks():
1136 """ 991 """
1137 Create Desktop and Start Menu links. 992 Create Desktop and Start Menu links.
1150 args = [ 1005 args = [
1151 sys.executable, 1006 sys.executable,
1152 os.path.join(os.path.dirname(__file__), 1007 os.path.join(os.path.dirname(__file__),
1153 "create_windows_links.py"), 1008 "create_windows_links.py"),
1154 ] 1009 ]
1155 if includePythonVariant:
1156 args.append("-y")
1157 subprocess.call(args) 1010 subprocess.call(args)
1158 else: 1011 else:
1159 print( 1012 print(
1160 "\nThe Python package 'pywin32' is not installed. Desktop and" 1013 "\nThe Python package 'pywin32' is not installed. Desktop and"
1161 " Start Menu entries will not be created." 1014 " Start Menu entries will not be created."
1162 ) 1015 )
1163 return 1016 return
1164 1017
1165 regPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" + \ 1018 regPath = (
1166 "\\User Shell Folders" 1019 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer" +
1020 "\\User Shell Folders"
1021 )
1167 1022
1168 # 1. create desktop shortcuts 1023 # 1. create desktop shortcuts
1169 regName = "Desktop" 1024 regName = "Desktop"
1170 desktopFolder = os.path.normpath( 1025 desktopFolder = os.path.normpath(
1171 os.path.expandvars(getWinregEntry(regName, regPath))) 1026 os.path.expandvars(getWinregEntry(regName, regPath)))
1197 1052
1198 @param pydir the name of the directory where the Python script will 1053 @param pydir the name of the directory where the Python script will
1199 eventually be installed 1054 eventually be installed
1200 @type str 1055 @type str
1201 """ 1056 """
1202 global cfg, macAppBundleName, macPythonExe, macAppBundlePath, pyqtVariant 1057 global cfg, macAppBundleName, macPythonExe, macAppBundlePath
1203 1058
1204 directories = { 1059 directories = {
1205 "contents": "{0}/{1}/Contents/".format( 1060 "contents": "{0}/{1}/Contents/".format(
1206 macAppBundlePath, macAppBundleName), 1061 macAppBundlePath, macAppBundleName),
1207 "exe": "{0}/{1}/Contents/MacOS".format( 1062 "exe": "{0}/{1}/Contents/MacOS".format(
1222 wname = os.path.join(directories["exe"], "eric6") 1077 wname = os.path.join(directories["exe"], "eric6")
1223 1078
1224 # determine entry for DYLD_FRAMEWORK_PATH 1079 # determine entry for DYLD_FRAMEWORK_PATH
1225 dyldLine = "" 1080 dyldLine = ""
1226 try: 1081 try:
1227 if pyqtVariant == "PyQt4": 1082 from PyQt5.QtCore import QLibraryInfo
1228 from PyQt4.QtCore import QLibraryInfo
1229 else:
1230 from PyQt5.QtCore import QLibraryInfo
1231 qtLibraryDir = QLibraryInfo.location(QLibraryInfo.LibrariesPath) 1083 qtLibraryDir = QLibraryInfo.location(QLibraryInfo.LibrariesPath)
1232 except ImportError: 1084 except ImportError:
1233 qtLibraryDir = "" 1085 qtLibraryDir = ""
1234 if qtLibraryDir: 1086 if qtLibraryDir:
1235 dyldLine = "DYLD_FRAMEWORK_PATH={0}\n".format(qtLibraryDir) 1087 dyldLine = "DYLD_FRAMEWORK_PATH={0}\n".format(qtLibraryDir)
1435 @rtype bool 1287 @rtype bool
1436 """ 1288 """
1437 ok = False 1289 ok = False
1438 print("{0}\n\nShall '{1}' be installed using pip? (Y/n)" 1290 print("{0}\n\nShall '{1}' be installed using pip? (Y/n)"
1439 .format(message, packageName), end=" ") 1291 .format(message, packageName), end=" ")
1440 if sys.version_info[0] == 2: 1292 answer = input()
1441 answer = raw_input() # __IGNORE_WARNING__
1442 else:
1443 answer = input()
1444 if answer in ("", "Y", "y"): 1293 if answer in ("", "Y", "y"):
1445 exitCode = subprocess.call( 1294 exitCode = subprocess.call(
1446 [sys.executable, "-m", "pip", "install", packageName]) 1295 [sys.executable, "-m", "pip", "install", packageName])
1447 ok = (exitCode == 0) 1296 ok = (exitCode == 0)
1448 1297
1455 """ 1304 """
1456 print('Checking dependencies') 1305 print('Checking dependencies')
1457 1306
1458 # perform dependency checks 1307 # perform dependency checks
1459 print("Python Version: {0:d}.{1:d}.{2:d}".format(*sys.version_info[:3])) 1308 print("Python Version: {0:d}.{1:d}.{2:d}".format(*sys.version_info[:3]))
1460 if sys.version_info < (2, 7, 10): 1309 if sys.version_info < (3, 5, 0):
1461 print('Sorry, you must have Python 2.7.10 or higher or '
1462 'Python 3.5.0 or higher.')
1463 exit(5)
1464 elif sys.version_info < (3, 5, 0) and sys.version_info[0] == 3:
1465 print('Sorry, you must have Python 3.5.0 or higher.') 1310 print('Sorry, you must have Python 3.5.0 or higher.')
1466 exit(5) 1311 exit(5)
1467 if sys.version_info[0] > 3: 1312 if sys.version_info[0] > 3:
1468 print('Sorry, eric6 requires Python 3 or Python 2 for running.') 1313 print('Sorry, eric6 requires Python 3 for running.')
1469 exit(5) 1314 exit(5)
1470 1315
1471 try: 1316 try:
1472 import xml.etree # __IGNORE_WARNING__ 1317 import xml.etree # __IGNORE_WARNING__
1473 except ImportError: 1318 except ImportError:
1474 print('Your Python installation is missing the XML module.') 1319 print('Your Python installation is missing the XML module.')
1475 print('Please install it and try again.') 1320 print('Please install it and try again.')
1476 exit(5) 1321 exit(5)
1477 1322
1478 if pyqtVariant == "PyQt4": 1323 try:
1479 try: 1324 from PyQt5.QtCore import qVersion
1480 from PyQt4.QtCore import qVersion 1325 except ImportError as msg:
1481 except ImportError as msg: 1326 installed = pipInstall(
1482 print('Sorry, please install PyQt4.') 1327 "PyQt5",
1483 print('Error: {0}'.format(msg)) 1328 "PyQt5 could not be detected.\nError: {0}".format(msg)
1484 exit(1) 1329 )
1485 print("Found PyQt4") 1330 if installed:
1486 else: 1331 # try to import it again
1487 try: 1332 try:
1488 from PyQt5.QtCore import qVersion 1333 from PyQt5.QtCore import qVersion
1489 except ImportError as msg: 1334 except ImportError as msg:
1490 if sys.version_info[0] == 2:
1491 # no PyQt5 wheels available for Python 2
1492 installed = False
1493 else:
1494 installed = pipInstall(
1495 "PyQt5",
1496 "PyQt5 could not be detected.\nError: {0}".format(msg)
1497 )
1498 if installed:
1499 # try to import it again
1500 try:
1501 from PyQt5.QtCore import qVersion
1502 except ImportError as msg:
1503 print('Sorry, please install PyQt5.')
1504 print('Error: {0}'.format(msg))
1505 exit(1)
1506 else:
1507 print('Sorry, please install PyQt5.') 1335 print('Sorry, please install PyQt5.')
1508 print('Error: {0}'.format(msg)) 1336 print('Error: {0}'.format(msg))
1509 exit(1) 1337 exit(1)
1510 print("Found PyQt5")
1511
1512 try:
1513 if pyqtVariant == "PyQt4":
1514 pyuic = "pyuic4"
1515 from PyQt4 import uic # __IGNORE_WARNING__
1516 else: 1338 else:
1517 pyuic = "pyuic5" 1339 print('Sorry, please install PyQt5.')
1518 from PyQt5 import uic # __IGNORE_WARNING__ 1340 print('Error: {0}'.format(msg))
1341 exit(1)
1342 print("Found PyQt5")
1343
1344 try:
1345 pyuic = "pyuic5"
1346 from PyQt5 import uic # __IGNORE_WARNING__
1519 except ImportError as msg: 1347 except ImportError as msg:
1520 print("Sorry, {0} is not installed.".format(pyuic)) 1348 print("Sorry, {0} is not installed.".format(pyuic))
1521 print('Error: {0}'.format(msg)) 1349 print('Error: {0}'.format(msg))
1522 exit(1) 1350 exit(1)
1523 print("Found {0}".format(pyuic)) 1351 print("Found {0}".format(pyuic))
1524 1352
1525 if pyqtVariant != "PyQt4": 1353 try:
1526 try: 1354 from PyQt5 import QtWebEngineWidgets # __IGNORE_WARNING__
1527 from PyQt5 import QtWebEngineWidgets # __IGNORE_WARNING__ 1355 except ImportError as msg:
1528 except ImportError as msg: 1356 from PyQt5.QtCore import PYQT_VERSION
1529 from PyQt5.QtCore import PYQT_VERSION 1357 if PYQT_VERSION >= 0x050c00:
1530 if PYQT_VERSION >= 0x50c00: 1358 # PyQt 5.12 separated QtWebEngine into a separate wheel
1531 # PyQt 5.12 separated QtWebEngine into a separate wheel
1532 installed = pipInstall(
1533 "PyQtWebEngine",
1534 "PyQtWebEngine could not be detected.\nError: {0}"
1535 .format(msg)
1536 )
1537
1538 try:
1539 from PyQt5 import QtChart # __IGNORE_WARNING__
1540 except ImportError as msg:
1541 installed = pipInstall( 1359 installed = pipInstall(
1542 "PyQtChart", 1360 "PyQtWebEngine",
1543 "PyQtChart could not be detected.\nError: {0}" 1361 "PyQtWebEngine could not be detected.\nError: {0}"
1544 .format(msg) 1362 .format(msg)
1545 ) 1363 )
1546 1364
1547 try: 1365 try:
1548 if pyqtVariant == "PyQt4": 1366 from PyQt5 import QtChart # __IGNORE_WARNING__
1549 from PyQt4 import Qsci # __IGNORE_WARNING__ 1367 except ImportError as msg:
1368 installed = pipInstall(
1369 "PyQtChart",
1370 "PyQtChart could not be detected.\nError: {0}"
1371 .format(msg)
1372 )
1373
1374 try:
1375 from PyQt5 import Qsci # __IGNORE_WARNING__
1376 except ImportError as msg:
1377 installed = pipInstall(
1378 "QScintilla",
1379 "QScintilla could not be detected.\nError: {0}".format(msg)
1380 )
1381 if installed:
1382 # try to import it again
1383 try:
1384 from PyQt5 import Qsci # __IGNORE_WARNING__
1385 message = None
1386 except ImportError as msg:
1387 message = str(msg)
1550 else: 1388 else:
1551 from PyQt5 import Qsci # __IGNORE_WARNING__ 1389 message = "QScintilla could not be installed."
1552 except ImportError as msg:
1553 if pyqtVariant == "PyQt4":
1554 message = str(msg)
1555 else:
1556 installed = pipInstall(
1557 "QScintilla",
1558 "QScintilla could not be detected.\nError: {0}".format(msg)
1559 )
1560 if installed:
1561 # try to import it again
1562 try:
1563 from PyQt5 import Qsci # __IGNORE_WARNING__
1564 message = None
1565 except ImportError as msg:
1566 message = str(msg)
1567 else:
1568 message = "QScintilla could not be installed."
1569 if message: 1390 if message:
1570 print("Sorry, please install QScintilla2 and") 1391 print("Sorry, please install QScintilla2 and")
1571 print("its PyQt5/PyQt4 wrapper.") 1392 print("its PyQt5 wrapper.")
1572 print('Error: {0}'.format(message)) 1393 print('Error: {0}'.format(message))
1573 exit(1) 1394 exit(1)
1574 print("Found QScintilla2") 1395 print("Found QScintilla2")
1575 1396
1576 if pyqtVariant == "PyQt4": 1397 impModulesList = [
1577 impModulesList = [ 1398 "PyQt5.QtGui", "PyQt5.QtNetwork", "PyQt5.QtPrintSupport",
1578 "PyQt4.QtGui", "PyQt4.QtNetwork", "PyQt4.QtSql", 1399 "PyQt5.QtSql", "PyQt5.QtSvg", "PyQt5.QtWidgets",
1579 "PyQt4.QtSvg", "PyQt4.QtWebKit", 1400 ]
1580 ] 1401 altModulesList = [
1581 altModulesList = [] 1402 # Tuple with alternatives, flag indicating it's ok to not be
1582 else: 1403 # available (e.g. for 32-Bit Windows)
1583 impModulesList = [ 1404 (("PyQt5.QtWebEngineWidgets", ), sys.maxsize <= 2**32),
1584 "PyQt5.QtGui", "PyQt5.QtNetwork", "PyQt5.QtPrintSupport", 1405 ]
1585 "PyQt5.QtSql", "PyQt5.QtSvg", "PyQt5.QtWidgets",
1586 ]
1587 altModulesList = [
1588 # Tuple with alternatives, flag indicating it's ok to not be
1589 # available (e.g. for 32-Bit Windows)
1590 (("PyQt5.QtWebEngineWidgets", "PyQt5.QtWebKitWidgets"),
1591 sys.maxsize <= 2**32),
1592 ]
1593 # check mandatory modules 1406 # check mandatory modules
1594 modulesOK = True 1407 modulesOK = True
1595 for impModule in impModulesList: 1408 for impModule in impModulesList:
1596 name = impModule.split(".")[1] 1409 name = impModule.split(".")[1]
1597 try: 1410 try:
1634 1447
1635 # check version of Qt 1448 # check version of Qt
1636 qtMajor = int(qVersion().split('.')[0]) 1449 qtMajor = int(qVersion().split('.')[0])
1637 qtMinor = int(qVersion().split('.')[1]) 1450 qtMinor = int(qVersion().split('.')[1])
1638 print("Qt Version: {0}".format(qVersion().strip())) 1451 print("Qt Version: {0}".format(qVersion().strip()))
1639 if qtMajor < 4 or \ 1452 if qtMajor == 5 and qtMinor < 9:
1640 (qtMajor == 4 and qtMinor < 8) or \ 1453 print('Sorry, you must have Qt version 5.9.0 or better.')
1641 (qtMajor == 5 and qtMinor < 9):
1642 print('Sorry, you must have Qt version 4.8.0 or better or')
1643 print('5.9.0 or better.')
1644 exit(2) 1454 exit(2)
1645 1455
1646 # check version of sip 1456 # check version of sip
1647 try: 1457 try:
1648 try: 1458 try:
1657 sipVersion += '.0' 1467 sipVersion += '.0'
1658 (major, minor, pat) = sipVersion.split('.') 1468 (major, minor, pat) = sipVersion.split('.')
1659 major = int(major) 1469 major = int(major)
1660 minor = int(minor) 1470 minor = int(minor)
1661 pat = int(pat) 1471 pat = int(pat)
1662 if major < 4 or (major == 4 and minor < 14) or \ 1472 if (
1663 (major == 4 and minor == 14 and pat < 2): 1473 major < 4 or
1474 (major == 4 and minor < 14) or
1475 (major == 4 and minor == 14 and pat < 2)
1476 ):
1664 print('Sorry, you must have sip 4.14.2 or higher or' 1477 print('Sorry, you must have sip 4.14.2 or higher or'
1665 ' a recent snapshot release.') 1478 ' a recent snapshot release.')
1666 exit(3) 1479 exit(3)
1667 # check for blacklisted versions 1480 # check for blacklisted versions
1668 for vers in BlackLists["sip"] + PlatformBlackLists["sip"]: 1481 for vers in BlackLists["sip"] + PlatformBlackLists["sip"]:
1674 exit(3) 1487 exit(3)
1675 except (ImportError, AttributeError): 1488 except (ImportError, AttributeError):
1676 pass 1489 pass
1677 1490
1678 # check version of PyQt 1491 # check version of PyQt
1679 if pyqtVariant == "PyQt4": 1492 from PyQt5.QtCore import PYQT_VERSION_STR
1680 from PyQt4.QtCore import PYQT_VERSION_STR
1681 else:
1682 from PyQt5.QtCore import PYQT_VERSION_STR
1683 pyqtVersion = PYQT_VERSION_STR 1493 pyqtVersion = PYQT_VERSION_STR
1684 print("PyQt Version:", pyqtVersion.strip()) 1494 print("PyQt Version:", pyqtVersion.strip())
1685 # always assume, that snapshots or dev versions are new enough 1495 # always assume, that snapshots or dev versions are new enough
1686 if "snapshot" not in pyqtVersion and "dev" not in pyqtVersion: 1496 if "snapshot" not in pyqtVersion and "dev" not in pyqtVersion:
1687 while pyqtVersion.count('.') < 2: 1497 while pyqtVersion.count('.') < 2:
1688 pyqtVersion += '.0' 1498 pyqtVersion += '.0'
1689 (major, minor, pat) = pyqtVersion.split('.') 1499 (major, minor, pat) = pyqtVersion.split('.')
1690 major = int(major) 1500 major = int(major)
1691 minor = int(minor) 1501 minor = int(minor)
1692 pat = int(pat) 1502 pat = int(pat)
1693 if major < 4 or \ 1503 if major == 5 and minor < 9:
1694 (major == 4 and minor < 10) or \ 1504 print('Sorry, you must have PyQt 5.9.0 or better or'
1695 (major == 5 and minor < 9):
1696 print('Sorry, you must have PyQt 4.10.0 or better or')
1697 print('PyQt 5.9.0 or better or'
1698 ' a recent snapshot release.') 1505 ' a recent snapshot release.')
1699 exit(4) 1506 exit(4)
1700 # check for blacklisted versions 1507 # check for blacklisted versions
1701 for vers in BlackLists[pyqtVariant] + PlatformBlackLists[pyqtVariant]: 1508 for vers in BlackLists["PyQt5"] + PlatformBlackLists["PyQt5"]:
1702 if vers == pyqtVersion: 1509 if vers == pyqtVersion:
1703 print('Sorry, PyQt version {0} is not compatible with eric6.' 1510 print('Sorry, PyQt version {0} is not compatible with eric6.'
1704 .format(vers)) 1511 .format(vers))
1705 print('Please install another version.') 1512 print('Please install another version.')
1706 exit(4) 1513 exit(4)
1707 1514
1708 # check version of QScintilla 1515 # check version of QScintilla
1709 if pyqtVariant == "PyQt4": 1516 from PyQt5.Qsci import QSCINTILLA_VERSION_STR
1710 from PyQt4.Qsci import QSCINTILLA_VERSION_STR
1711 else:
1712 from PyQt5.Qsci import QSCINTILLA_VERSION_STR
1713 scintillaVersion = QSCINTILLA_VERSION_STR 1517 scintillaVersion = QSCINTILLA_VERSION_STR
1714 print("QScintilla Version:", QSCINTILLA_VERSION_STR.strip()) 1518 print("QScintilla Version:", QSCINTILLA_VERSION_STR.strip())
1715 # always assume, that snapshots or dev versions are new enough 1519 # always assume, that snapshots or dev versions are new enough
1716 if "snapshot" not in scintillaVersion and "dev" not in scintillaVersion: 1520 if "snapshot" not in scintillaVersion and "dev" not in scintillaVersion:
1717 while scintillaVersion.count('.') < 2: 1521 while scintillaVersion.count('.') < 2:
1723 if major < 2 or (major == 2 and minor < 9): 1527 if major < 2 or (major == 2 and minor < 9):
1724 print('Sorry, you must have QScintilla 2.9.0 or higher or' 1528 print('Sorry, you must have QScintilla 2.9.0 or higher or'
1725 ' a recent snapshot release.') 1529 ' a recent snapshot release.')
1726 exit(5) 1530 exit(5)
1727 # check for blacklisted versions 1531 # check for blacklisted versions
1728 for vers in BlackLists["QScintilla2"] + \ 1532 for vers in (
1729 PlatformBlackLists["QScintilla2"]: 1533 BlackLists["QScintilla2"] +
1534 PlatformBlackLists["QScintilla2"]
1535 ):
1730 if vers == scintillaVersion: 1536 if vers == scintillaVersion:
1731 print( 1537 print(
1732 'Sorry, QScintilla2 version {0} is not compatible with' 1538 'Sorry, QScintilla2 version {0} is not compatible with'
1733 ' eric6.'.format(vers)) 1539 ' eric6.'.format(vers))
1734 print('Please install another version.') 1540 print('Please install another version.')
1752 1558
1753 def compileUiFiles(): 1559 def compileUiFiles():
1754 """ 1560 """
1755 Compile the .ui files to Python sources. 1561 Compile the .ui files to Python sources.
1756 """ 1562 """
1757 if pyqtVariant == "PyQt4": 1563 from PyQt5.uic import compileUiDir
1758 from PyQt4.uic import compileUiDir
1759 else:
1760 from PyQt5.uic import compileUiDir
1761 compileUiDir(eric6SourceDir, True, __pyName) 1564 compileUiDir(eric6SourceDir, True, __pyName)
1762 1565
1763 1566
1764 def prepareInfoFile(fileName): 1567 def prepareInfoFile(fileName):
1765 """ 1568 """
1774 os.rename(fileName, fileName + ".orig") 1577 os.rename(fileName, fileName + ".orig")
1775 except EnvironmentError: 1578 except EnvironmentError:
1776 pass 1579 pass
1777 try: 1580 try:
1778 hgOut = subprocess.check_output(["hg", "identify", "-i"]) 1581 hgOut = subprocess.check_output(["hg", "identify", "-i"])
1779 if sys.version_info[0] == 3: 1582 hgOut = hgOut.decode()
1780 hgOut = hgOut.decode()
1781 except (OSError, subprocess.CalledProcessError): 1583 except (OSError, subprocess.CalledProcessError):
1782 hgOut = "" 1584 hgOut = ""
1783 if hgOut: 1585 if hgOut:
1784 hgOut = hgOut.strip() 1586 hgOut = hgOut.strip()
1785 if hgOut.endswith("+"): 1587 if hgOut.endswith("+"):
1786 hgOut = hgOut[:-1] 1588 hgOut = hgOut[:-1]
1787 if sys.version_info[0] == 2: 1589 f = open(fileName + ".orig", "r", encoding="utf-8")
1788 f = codecs.open(fileName + ".orig", "r", "utf-8")
1789 else:
1790 f = open(fileName + ".orig", "r", encoding="utf-8")
1791 text = f.read() 1590 text = f.read()
1792 f.close() 1591 f.close()
1793 text = text.replace("@@REVISION@@", hgOut)\ 1592 text = (
1593 text.replace("@@REVISION@@", hgOut)
1794 .replace("@@VERSION@@", "rev_" + hgOut) 1594 .replace("@@VERSION@@", "rev_" + hgOut)
1595 )
1795 copyToFile(fileName, text) 1596 copyToFile(fileName, text)
1796 else: 1597 else:
1797 shutil.copy(fileName + ".orig", fileName) 1598 shutil.copy(fileName + ".orig", fileName)
1798 1599
1799 1600
1807 @type str 1608 @type str
1808 @return value of requested registry variable 1609 @return value of requested registry variable
1809 @rtype any 1610 @rtype any
1810 """ 1611 """
1811 try: 1612 try:
1812 import _winreg as winreg 1613 import winreg
1813 except ImportError: 1614 except ImportError:
1814 try: 1615 return None
1815 import winreg
1816 except ImportError:
1817 return None
1818 1616
1819 try: 1617 try:
1820 registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0, 1618 registryKey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, path, 0,
1821 winreg.KEY_READ) 1619 winreg.KEY_READ)
1822 value, _ = winreg.QueryValueEx(registryKey, name) 1620 value, _ = winreg.QueryValueEx(registryKey, name)
1868 1666
1869 @return list of tuples containing the desktop link name, 1667 @return list of tuples containing the desktop link name,
1870 the link target and the icon target 1668 the link target and the icon target
1871 @rtype list of tuples of (str, str, str) 1669 @rtype list of tuples of (str, str, str)
1872 """ 1670 """
1873 global cfg, includePythonVariant 1671 global cfg
1874
1875 if includePythonVariant:
1876 marker = PythonMarkers[sys.version_info.major]
1877 else:
1878 marker = ""
1879 1672
1880 majorVersion, minorVersion = sys.version_info[:2] 1673 majorVersion, minorVersion = sys.version_info[:2]
1881 entriesTemplates = [ 1674 entriesTemplates = [
1882 ("eric6 (Python {0}.{1}).lnk", 1675 ("eric6 (Python {0}.{1}).lnk",
1883 os.path.join(cfg["bindir"], "eric6" + marker + ".cmd"), 1676 os.path.join(cfg["bindir"], "eric6.cmd"),
1884 os.path.join(cfg["ericPixDir"], "eric6.ico")), 1677 os.path.join(cfg["ericPixDir"], "eric6.ico")),
1678 ("eric6 Browser (Python {0}.{1}).lnk",
1679 os.path.join(cfg["bindir"], "eric6_browse.cmd"),
1680 os.path.join(cfg["ericPixDir"], "ericWeb48.ico")),
1885 ] 1681 ]
1886 if sys.version_info.major == 2:
1887 entriesTemplates.append((
1888 "eric6 Browser (Python {0}.{1}).lnk",
1889 os.path.join(cfg["bindir"], "eric6_webbrowser" + marker + ".cmd"),
1890 os.path.join(cfg["ericPixDir"], "ericWeb48.ico")
1891 ))
1892 else:
1893 entriesTemplates.append((
1894 "eric6 Browser (Python {0}.{1}).lnk",
1895 os.path.join(cfg["bindir"], "eric6_browser" + marker + ".cmd"),
1896 os.path.join(cfg["ericPixDir"], "ericWeb48.ico")
1897 ))
1898 1682
1899 return [ 1683 return [
1900 (e[0].format(majorVersion, minorVersion), e[1], e[2]) 1684 (e[0].format(majorVersion, minorVersion), e[1], e[2])
1901 for e in entriesTemplates 1685 for e in entriesTemplates
1902 ] 1686 ]
1922 """ 1706 """
1923 import getopt 1707 import getopt
1924 1708
1925 # Parse the command line. 1709 # Parse the command line.
1926 global progName, modDir, doCleanup, doCompile, distDir, cfg, apisDir 1710 global progName, modDir, doCleanup, doCompile, distDir, cfg, apisDir
1927 global sourceDir, eric6SourceDir, configName, includePythonVariant 1711 global sourceDir, eric6SourceDir, configName
1928 global macAppBundlePath, macAppBundleName, macPythonExe 1712 global macAppBundlePath, macAppBundleName, macPythonExe
1929 global pyqtVariant, pyqtOverride, installApis, doCleanDesktopLinks 1713 global installApis, doCleanDesktopLinks
1930 1714
1931 if sys.version_info < (2, 7, 0) or sys.version_info > (3, 9, 9): 1715 if sys.version_info < (3, 5, 0) or sys.version_info > (3, 99, 99):
1932 print('Sorry, eric6 requires at least Python 2.7 or ' 1716 print('Sorry, eric6 requires at least Python 3.5 for running.')
1933 'Python 3 for running.')
1934 exit(5) 1717 exit(5)
1935 1718
1936 progName = os.path.basename(argv[0]) 1719 progName = os.path.basename(argv[0])
1937 1720
1938 if os.path.dirname(argv[0]): 1721 if os.path.dirname(argv[0]):
1939 os.chdir(os.path.dirname(argv[0])) 1722 os.chdir(os.path.dirname(argv[0]))
1940 1723
1941 determinePyQtVariant()
1942 initGlobals() 1724 initGlobals()
1943 1725
1944 try: 1726 try:
1945 if sys.platform.startswith(("win", "cygwin")): 1727 if sys.platform.startswith(("win", "cygwin")):
1946 optlist, args = getopt.getopt( 1728 optlist, args = getopt.getopt(
1947 argv[1:], "chxyza:b:d:f:", 1729 argv[1:], "chxza:b:d:f:",
1948 ["help", "pyqt=", "no-apis"]) 1730 ["help", "no-apis"])
1949 elif sys.platform == "darwin": 1731 elif sys.platform == "darwin":
1950 optlist, args = getopt.getopt( 1732 optlist, args = getopt.getopt(
1951 argv[1:], "chxyza:b:d:f:i:m:n:p:", 1733 argv[1:], "chxza:b:d:f:i:m:n:p:",
1952 ["help", "pyqt=", "no-apis"]) 1734 ["help", "no-apis"])
1953 else: 1735 else:
1954 optlist, args = getopt.getopt( 1736 optlist, args = getopt.getopt(
1955 argv[1:], "chxyza:b:d:f:i:", 1737 argv[1:], "chxza:b:d:f:i:",
1956 ["help", "pyqt=", "no-apis"]) 1738 ["help", "no-apis"])
1957 except getopt.GetoptError as err: 1739 except getopt.GetoptError as err:
1958 print(err) 1740 print(err)
1959 usage() 1741 usage()
1960 1742
1961 global platBinDir 1743 global platBinDir
1977 depChecks = False 1759 depChecks = False
1978 elif opt == "-c": 1760 elif opt == "-c":
1979 doCleanup = False 1761 doCleanup = False
1980 elif opt == "-z": 1762 elif opt == "-z":
1981 doCompile = False 1763 doCompile = False
1982 elif opt == "-y":
1983 includePythonVariant = True
1984 elif opt == "-f": 1764 elif opt == "-f":
1985 try: 1765 try:
1986 exec(compile(open(arg).read(), arg, 'exec'), globals()) 1766 exec(compile(open(arg).read(), arg, 'exec'), globals())
1987 if len(cfg) != configLength: 1767 if len(cfg) != configLength:
1988 print("The configuration dictionary in '{0}' is incorrect." 1768 print("The configuration dictionary in '{0}' is incorrect."
1994 macAppBundleName = arg 1774 macAppBundleName = arg
1995 elif opt == "-n": 1775 elif opt == "-n":
1996 macAppBundlePath = arg 1776 macAppBundlePath = arg
1997 elif opt == "-p": 1777 elif opt == "-p":
1998 macPythonExe = arg 1778 macPythonExe = arg
1999 elif opt == "--pyqt":
2000 if arg not in ["4", "5"]:
2001 print("Invalid PyQt version given; should be 4 or 5. Aborting")
2002 exit(6)
2003 pyqtVariant = "PyQt{0}".format(arg)
2004 pyqtOverride = True
2005 elif opt == "--no-apis": 1779 elif opt == "--no-apis":
2006 installApis = False 1780 installApis = False
2007 elif opt == "--clean-desktop": 1781 elif opt == "--clean-desktop":
2008 doCleanDesktopLinks = True 1782 doCleanDesktopLinks = True
2009 1783
2070 # step 2: compile the forms 1844 # step 2: compile the forms
2071 compileUiFiles() 1845 compileUiFiles()
2072 1846
2073 if doCompile: 1847 if doCompile:
2074 print("\nCompiling source files ...") 1848 print("\nCompiling source files ...")
2075 # Hide compile errors (mainly because of Py2/Py3 differences)
2076 skipRe = re.compile(r"DebugClients[\\/]Python[\\/]") 1849 skipRe = re.compile(r"DebugClients[\\/]Python[\\/]")
2077 sys.stdout = io.StringIO() 1850 sys.stdout = io.StringIO()
2078 if distDir: 1851 if distDir:
2079 compileall.compile_dir( 1852 compileall.compile_dir(
2080 eric6SourceDir, 1853 eric6SourceDir,

eric ide

mercurial