install.py

branch
maintenance
changeset 6273
0daf79d65080
parent 6216
2a0eeba143e7
child 6275
8ce9f9c467ec
equal deleted inserted replaced
6207:0a74c1efab70 6273:0daf79d65080
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: 13 try:
14 # Python2 only
14 import cStringIO as io 15 import cStringIO as io
15 import sip 16 import sip
16 sip.setapi('QString', 2) 17 sip.setapi('QString', 2)
17 sip.setapi('QVariant', 2) 18 sip.setapi('QVariant', 2)
18 sip.setapi('QTextStream', 2) 19 sip.setapi('QTextStream', 2)
20 input = raw_input # __IGNORE_WARNING__
19 except (ImportError): 21 except (ImportError):
20 import io # __IGNORE_WARNING__ 22 import io # __IGNORE_WARNING__
21 23
22 import sys 24 import sys
23 import os 25 import os
24 import re 26 import re
25 import compileall 27 import compileall
219 try: 221 try:
220 import PyQt4 # __IGNORE_WARNING__ 222 import PyQt4 # __IGNORE_WARNING__
221 pyqtVariant = "PyQt4" 223 pyqtVariant = "PyQt4"
222 del sys.modules["PyQt4"] 224 del sys.modules["PyQt4"]
223 except ImportError: 225 except ImportError:
224 pyqtVariant = "" 226 # default to PyQt5, installation will be asked for
227 pyqtVariant = "PyQt5"
225 228
226 229
227 def initGlobals(): 230 def initGlobals():
228 """ 231 """
229 Module function to set the values of globals that need more than a 232 Module function to set the values of globals that need more than a
238 platBinDirOld = platBinDir 241 platBinDirOld = platBinDir
239 platBinDir = os.path.join(platBinDir, "Scripts") 242 platBinDir = os.path.join(platBinDir, "Scripts")
240 if not os.path.exists(platBinDir): 243 if not os.path.exists(platBinDir):
241 platBinDir = platBinDirOld 244 platBinDir = platBinDirOld
242 else: 245 else:
243 platBinDir = "/usr/local/bin" 246 pyBinDir = os.path.normpath(os.path.dirname(sys.executable))
247 if os.access(pyBinDir, os.W_OK):
248 # install the eric scripts along the python executable
249 platBinDir = pyBinDir
250 else:
251 # install them in the user's bin directory
252 platBinDir = os.path.expanduser("~/bin")
253 if platBinDir != "/usr/local/bin" and \
254 os.access("/usr/local/bin", os.W_OK):
255 platBinDirOld = "/usr/local/bin"
244 256
245 modDir = distutils.sysconfig.get_python_lib(True) 257 modDir = distutils.sysconfig.get_python_lib(True)
246 pyModDir = modDir 258 pyModDir = modDir
247 259
248 pyqtDataDir = os.path.join(modDir, pyqtVariant) 260 pyqtDataDir = os.path.join(modDir, pyqtVariant)
249 if os.path.exists(os.path.join(pyqtDataDir, "qsci")): 261 if os.path.exists(os.path.join(pyqtDataDir, "qsci")):
250 # it's the installer 262 # it's the installer
251 qtDataDir = pyqtDataDir 263 qtDataDir = pyqtDataDir
252 else: 264 elif os.path.exists(os.path.join(pyqtDataDir, "Qt", "qsci")):
265 # it's the wheel
266 qtDataDir = os.path.join(pyqtDataDir, "Qt")
267 else:
268 # determine dynamically
253 try: 269 try:
254 if pyqtVariant == "PyQt4": 270 if pyqtVariant == "PyQt4":
255 from PyQt4.QtCore import QLibraryInfo 271 from PyQt4.QtCore import QLibraryInfo
256 else: 272 else:
257 from PyQt5.QtCore import QLibraryInfo 273 from PyQt5.QtCore import QLibraryInfo
284 300
285 @param src source file name (string) 301 @param src source file name (string)
286 @param dst destination file name (string) 302 @param dst destination file name (string)
287 @param marker marker to be used (string) 303 @param marker marker to be used (string)
288 """ 304 """
305 global cfg
306
289 if sys.version_info[0] == 2: 307 if sys.version_info[0] == 2:
290 f = codecs.open(src, "r", "utf-8") 308 f = codecs.open(src, "r", "utf-8")
291 else: 309 else:
292 f = open(src, "r", encoding="utf-8") 310 f = open(src, "r", encoding="utf-8")
293 text = f.read() 311 text = f.read()
294 f.close() 312 f.close()
295 313
314 text = text.replace("@BINDIR@", cfg['bindir'])
296 text = text.replace("@MARKER@", marker) 315 text = text.replace("@MARKER@", marker)
297 if marker: 316 if marker:
298 t_marker = " ({0})".format(PythonTextMarkers[marker]) 317 t_marker = " ({0})".format(PythonTextMarkers[marker])
299 else: 318 else:
300 t_marker = "" 319 t_marker = ""
542 return 561 return
543 562
544 global pyModDir, progLanguages 563 global pyModDir, progLanguages
545 564
546 # Remove the menu entry for Linux systems 565 # Remove the menu entry for Linux systems
547 if sys.platform.startswith("linux") and os.getuid() == 0: 566 if sys.platform.startswith("linux"):
548 for name in ["/usr/share/pixmaps/eric.png", 567 if os.getuid() == 0:
549 "/usr/share/pixmaps/ericWeb.png"]: 568 for name in ["/usr/share/pixmaps/eric.png",
550 if os.path.exists(name): 569 "/usr/share/pixmaps/ericWeb.png"]:
551 os.remove(name) 570 if os.path.exists(name):
552 if includePythonVariant: 571 os.remove(name)
553 marker = PythonMarkers[sys.version_info.major] 572 if includePythonVariant:
554 else: 573 marker = PythonMarkers[sys.version_info.major]
555 marker = "" 574 else:
556 for name in ["/usr/share/applications/eric6" + marker + ".desktop", 575 marker = ""
557 "/usr/share/appdata/eric6" + marker + ".appdata.xml", 576 for name in [
558 "/usr/share/metainfo/eric6" + marker + ".appdata.xml", 577 "/usr/share/applications/eric6" + marker + ".desktop",
559 "/usr/share/applications/eric6_webbrowser" + marker + 578 "/usr/share/appdata/eric6" + marker + ".appdata.xml",
560 ".desktop", 579 "/usr/share/metainfo/eric6" + marker + ".appdata.xml",
561 "/usr/share/applications/eric6_browser" + marker + 580 "/usr/share/applications/eric6_webbrowser" + marker +
562 ".desktop", 581 ".desktop",
563 ]: 582 "/usr/share/applications/eric6_browser" + marker +
564 if os.path.exists(name): 583 ".desktop",
565 os.remove(name) 584 "/usr/share/pixmaps/eric" + marker + ".png",
585 "/usr/share/pixmaps/ericWeb" + marker + ".png",
586 ]:
587 if os.path.exists(name):
588 os.remove(name)
589 elif os.getuid() >= 1000:
590 # it is assumed that user ids start at 1000
591 for name in ["~/.local/share/pixmaps/eric.png",
592 "~/.local/share/pixmaps/ericWeb.png"]:
593 path = os.path.expanduser(name)
594 if os.path.exists(path):
595 os.remove(path)
596 if includePythonVariant:
597 marker = PythonMarkers[sys.version_info.major]
598 else:
599 marker = ""
600 for name in [
601 "~/.local/share/applications/eric6" + marker + ".desktop",
602 "~/.local/share/appdata/eric6" + marker + ".appdata.xml",
603 "~/.local/share/metainfo/eric6" + marker + ".appdata.xml",
604 "~/.local/share/applications/eric6_webbrowser" + marker +
605 ".desktop",
606 "~/.local/share/applications/eric6_browser" + marker +
607 ".desktop",
608 "~/.local/share/pixmaps/eric" + marker + ".png",
609 "~/.local/share/pixmaps/ericWeb" + marker + ".png",
610 ]:
611 path = os.path.expanduser(name)
612 if os.path.exists(path):
613 os.remove(path)
566 614
567 # Remove the wrapper scripts 615 # Remove the wrapper scripts
568 rem_wnames = [ 616 rem_wnames = [
569 "eric6_api", "eric6_compare", 617 "eric6_api", "eric6_compare",
570 "eric6_configure", "eric6_diff", 618 "eric6_configure", "eric6_diff",
593 if os.path.exists(rwname): 641 if os.path.exists(rwname):
594 os.remove(rwname) 642 os.remove(rwname)
595 643
596 # Cleanup our config file(s) 644 # Cleanup our config file(s)
597 for name in ['eric6config.py', 'eric6config.pyc', 'eric6.pth']: 645 for name in ['eric6config.py', 'eric6config.pyc', 'eric6.pth']:
598 e5cfile = os.path.join(pyModDir, name) 646 e6cfile = os.path.join(pyModDir, name)
599 if os.path.exists(e5cfile): 647 if os.path.exists(e6cfile):
600 os.remove(e5cfile) 648 os.remove(e6cfile)
601 e5cfile = os.path.join(pyModDir, "__pycache__", name) 649 e5cfile = os.path.join(pyModDir, "__pycache__", name)
602 path, ext = os.path.splitext(e5cfile) 650 path, ext = os.path.splitext(e5cfile)
603 for f in glob.glob("{0}.*{1}".format(path, ext)): 651 for f in glob.glob("{0}.*{1}".format(path, ext)):
604 os.remove(f) 652 os.remove(f)
605 653
805 853
806 # install the API file 854 # install the API file
807 if installApis: 855 if installApis:
808 for progLanguage in progLanguages: 856 for progLanguage in progLanguages:
809 apidir = os.path.join(cfg['apidir'], progLanguage.lower()) 857 apidir = os.path.join(cfg['apidir'], progLanguage.lower())
858 print("Installing {0} API files to '{1}'.".format(
859 progLanguage, apidir))
810 if not os.path.exists(apidir): 860 if not os.path.exists(apidir):
811 os.makedirs(apidir) 861 os.makedirs(apidir)
812 for apiName in glob.glob(os.path.join(sourceDir, "APIs", 862 for apiName in glob.glob(os.path.join(sourceDir, "APIs",
813 progLanguage, "*.api")): 863 progLanguage, "*.api")):
814 try: 864 try:
815 shutilCopy(apiName, apidir) 865 shutilCopy(apiName, apidir)
816 except EnvironmentError: 866 except EnvironmentError:
817 print("Could not install '{0}'.".format(apiName)) 867 print("Could not install '{0}' (no permission)."
868 .format(apiName))
818 for apiName in glob.glob(os.path.join(sourceDir, "APIs", 869 for apiName in glob.glob(os.path.join(sourceDir, "APIs",
819 progLanguage, "*.bas")): 870 progLanguage, "*.bas")):
820 try: 871 try:
821 shutilCopy(apiName, apidir) 872 shutilCopy(apiName, apidir)
822 except EnvironmentError: 873 except EnvironmentError:
823 print("Could not install '{0}'.".format(apiName)) 874 print("Could not install '{0}' (no permission)."
875 .format(apiName))
824 if progLanguage == "Python": 876 if progLanguage == "Python":
825 # copy Python3 API files to the same destination 877 # copy Python3 API files to the same destination
826 for apiName in glob.glob(os.path.join(sourceDir, "APIs", 878 for apiName in glob.glob(os.path.join(sourceDir, "APIs",
827 "Python3", "*.api")): 879 "Python3", "*.api")):
828 try: 880 try:
829 shutilCopy(apiName, apidir) 881 shutilCopy(apiName, apidir)
830 except EnvironmentError: 882 except EnvironmentError:
831 print("Could not install '{0}'.".format(apiName)) 883 print("Could not install '{0}' (no permission)."
884 .format(apiName))
832 for apiName in glob.glob(os.path.join(sourceDir, "APIs", 885 for apiName in glob.glob(os.path.join(sourceDir, "APIs",
833 "Python3", "*.bas")): 886 "Python3", "*.bas")):
834 if os.path.exists(os.path.join( 887 if os.path.exists(os.path.join(
835 apidir, os.path.basename( 888 apidir, os.path.basename(
836 apiName.replace(".bas", ".api")))): 889 apiName.replace(".bas", ".api")))):
837 try: 890 try:
838 shutilCopy(apiName, apidir) 891 shutilCopy(apiName, apidir)
839 except EnvironmentError: 892 except EnvironmentError:
840 print("Could not install '{0}'.".format(apiName)) 893 print("Could not install '{0}' (no permission)."
894 .format(apiName))
841 895
842 # create menu entry for Linux systems 896 # create menu entry for Linux systems
843 if sys.platform.startswith("linux"): 897 if sys.platform.startswith("linux"):
844 if includePythonVariant: 898 if includePythonVariant:
845 marker = PythonMarkers[sys.version_info.major] 899 marker = PythonMarkers[sys.version_info.major]
908 copyDesktopFile( 962 copyDesktopFile(
909 os.path.join(sourceDir, "eric6_browser.desktop"), 963 os.path.join(sourceDir, "eric6_browser.desktop"),
910 "/usr/share/applications/eric6_browser" + marker + 964 "/usr/share/applications/eric6_browser" + marker +
911 ".desktop", 965 ".desktop",
912 marker) 966 marker)
967 elif os.getuid() >= 1000:
968 # it is assumed, that user ids start at 1000
969 localPath = os.path.join(os.path.expanduser("~"),
970 ".local", "share")
971 # create directories first
972 for directory in [os.path.join(localPath, name)
973 for name in ("pixmaps", "applications",
974 "metainfo", "appdata")]:
975 if not os.path.isdir(directory):
976 os.makedirs(directory)
977 # now copy the files
978 shutilCopy(
979 os.path.join(sourceDir, "icons", "default", "eric.png"),
980 os.path.join(localPath, "pixmaps", "eric" + marker + ".png"))
981 copyDesktopFile(
982 os.path.join(sourceDir, "eric6.desktop"),
983 os.path.join(localPath, "applications",
984 "eric6" + marker + ".desktop"),
985 marker)
986 copyAppStreamFile(
987 os.path.join(sourceDir, "eric6.appdata.xml"),
988 os.path.join(localPath, "metainfo",
989 "eric6" + marker + ".appdata.xml"),
990 marker)
991 copyAppStreamFile(
992 os.path.join(sourceDir, "eric6.appdata.xml"),
993 os.path.join(localPath, "appdata",
994 "eric6" + marker + ".appdata.xml"),
995 marker)
996 shutilCopy(
997 os.path.join(sourceDir, "icons", "default", "ericWeb48.png"),
998 os.path.join(localPath, "pixmaps",
999 "ericWeb" + marker + ".png"))
1000 copyDesktopFile(
1001 os.path.join(sourceDir, "eric6_webbrowser.desktop"),
1002 os.path.join(localPath, "applications",
1003 "eric6_webbrowser" + marker + ".desktop"),
1004 marker)
1005 copyDesktopFile(
1006 os.path.join(sourceDir, "eric6_browser.desktop"),
1007 os.path.join(localPath, "applications",
1008 "eric6_browser" + marker + ".desktop"),
1009 marker)
913 1010
914 # Create a Mac application bundle 1011 # Create a Mac application bundle
915 if sys.platform == "darwin": 1012 if sys.platform == "darwin":
916 createMacAppBundle(cfg['ericDir']) 1013 createMacAppBundle(cfg['ericDir'])
917 1014
1124 macAppBundlePath, macAppBundleName, 1221 macAppBundlePath, macAppBundleName,
1125 ) 1222 )
1126 copyToFile(fn, config) 1223 copyToFile(fn, config)
1127 1224
1128 1225
1226 def pipInstall(packageName, message):
1227 """
1228 Install the given package via pip.
1229
1230 @param packageName name of the package to be installed
1231 @type str
1232 @param message message to be shown to the user
1233 @type str
1234 @return flag indicating a successful installation
1235 @rtype bool
1236 """
1237 ok = False
1238 print(message, "\n")
1239 answer = input("Shall '{0}' be installed using pip? (Y/n) "
1240 .format(packageName))
1241 if answer in ("", "Y", "y"):
1242 exitCode = subprocess.call(
1243 [sys.executable, "-m", "pip", "install", packageName])
1244 ok = (exitCode == 0)
1245
1246 return ok
1247
1248
1129 def doDependancyChecks(): 1249 def doDependancyChecks():
1130 """ 1250 """
1131 Perform some dependency checks. 1251 Perform some dependency checks.
1132 """ 1252 """
1133 print('Checking dependencies') 1253 print('Checking dependencies')
1162 print("Found PyQt4") 1282 print("Found PyQt4")
1163 else: 1283 else:
1164 try: 1284 try:
1165 from PyQt5.QtCore import qVersion 1285 from PyQt5.QtCore import qVersion
1166 except ImportError as msg: 1286 except ImportError as msg:
1167 print('Sorry, please install PyQt5.') 1287 installed = pipInstall(
1168 print('Error: {0}'.format(msg)) 1288 "PyQt5",
1169 exit(1) 1289 "PyQt5 could not be detected.\nError: {0}".format(msg)
1290 )
1291 if installed:
1292 # try to import it again
1293 try:
1294 from PyQt5.QtCore import qVersion
1295 except ImportError as msg:
1296 print('Sorry, please install PyQt5.')
1297 print('Error: {0}'.format(msg))
1298 exit(1)
1299 else:
1300 exit(1)
1170 print("Found PyQt5") 1301 print("Found PyQt5")
1171 1302
1172 try: 1303 try:
1173 if pyqtVariant == "PyQt4": 1304 if pyqtVariant == "PyQt4":
1174 pyuic = "pyuic4" 1305 pyuic = "pyuic4"
1186 if pyqtVariant == "PyQt4": 1317 if pyqtVariant == "PyQt4":
1187 from PyQt4 import Qsci # __IGNORE_WARNING__ 1318 from PyQt4 import Qsci # __IGNORE_WARNING__
1188 else: 1319 else:
1189 from PyQt5 import Qsci # __IGNORE_WARNING__ 1320 from PyQt5 import Qsci # __IGNORE_WARNING__
1190 except ImportError as msg: 1321 except ImportError as msg:
1191 print("Sorry, please install QScintilla2 and") 1322 if pyqtVariant == "PyQt4":
1192 print("its PyQt5/PyQt4 wrapper.") 1323 message = str(msg)
1193 print('Error: {0}'.format(msg)) 1324 else:
1194 exit(1) 1325 installed = pipInstall(
1326 "QScintilla",
1327 "QScintilla could not be detected.\nError: {0}".format(msg)
1328 )
1329 if installed:
1330 # try to import it again
1331 try:
1332 from PyQt5 import Qsci # __IGNORE_WARNING__
1333 message = None
1334 except ImportError as msg:
1335 message = str(msg)
1336 if message:
1337 print("Sorry, please install QScintilla2 and")
1338 print("its PyQt5/PyQt4 wrapper.")
1339 print('Error: {0}'.format(msg))
1340 exit(1)
1195 print("Found QScintilla2") 1341 print("Found QScintilla2")
1196 1342
1197 if pyqtVariant == "PyQt4": 1343 if pyqtVariant == "PyQt4":
1198 impModulesList = [ 1344 impModulesList = [
1199 "PyQt4.QtGui", "PyQt4.QtNetwork", "PyQt4.QtSql", 1345 "PyQt4.QtGui", "PyQt4.QtNetwork", "PyQt4.QtSql",

eric ide

mercurial