install-debugclients.py

branch
6_1_x
changeset 5056
ba04754da6a4
child 5145
95947ce71171
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/install-debugclients.py	Sun Jul 24 16:50:04 2016 +0200
@@ -0,0 +1,350 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+# This is the install script for the eric6 debug client. It may be used
+# to just install the debug clients for remote debugging.
+#
+
+"""
+Installation script for the eric6 debug clients.
+"""
+
+from __future__ import unicode_literals, print_function
+try:
+    import cStringIO as io
+    import sip
+    sip.setapi('QString', 2)
+    sip.setapi('QVariant', 2)
+    sip.setapi('QTextStream', 2)
+except (ImportError):
+    import io    # __IGNORE_WARNING__
+
+import sys
+import os
+import re
+import compileall
+import shutil
+import fnmatch
+import distutils.sysconfig
+
+# Define the globals.
+progName = None
+currDir = os.getcwd()
+modDir = None
+pyModDir = None
+distDir = None
+installPackage = "eric6DebugClients"
+doCleanup = True
+doCompile = True
+sourceDir = "eric"
+
+
+def exit(rcode=0):
+    """
+    Exit the install script.
+    
+    @param rcode result code to report back (integer)
+    """
+    global currDir
+    
+    if sys.platform.startswith("win"):
+        # different meaning of input between Py2 and Py3
+        try:
+            input("Press enter to continue...")
+        except (EOFError, SyntaxError):
+            pass
+    
+    os.chdir(currDir)
+    
+    sys.exit(rcode)
+
+
+def usage(rcode=2):
+    """
+    Display a usage message and exit.
+
+    @param rcode the return code passed back to the calling process.
+    """
+    global progName, modDir, distDir
+
+    print()
+    print("Usage:")
+    if sys.platform == "darwin":
+        print("    {0} [-chz] [-d dir] [-i dir]".format(progName))
+    elif sys.platform.startswith("win"):
+        print("    {0} [-chz] [-d dir]".format(progName))
+    else:
+        print("    {0} [-chz][-d dir] [-i dir]".format(progName))
+    print("where:")
+    print("    -h, --help display this help message")
+    print("    -d dir     where eric6 debug client files will be installed")
+    print("               (default: {0})".format(modDir))
+    if not sys.platform.startswith("win"):
+        print("    -i dir     temporary install prefix")
+        print("               (default: {0})".format(distDir))
+    print("    -c         don't cleanup old installation first")
+    print("    -z         don't compile the installed python files")
+
+    exit(rcode)
+
+
+def initGlobals():
+    """
+    Module function to set the values of globals that need more than a
+    simple assignment.
+    """
+    global modDir, pyModDir
+
+    modDir = distutils.sysconfig.get_python_lib(True)
+    pyModDir = modDir
+
+
+def copyTree(src, dst, filters, excludeDirs=[], excludePatterns=[]):
+    """
+    Copy files of a directory tree.
+    
+    @param src name of the source directory
+    @param dst name of the destination directory
+    @param filters list of filter pattern determining the files to be copied
+    @param excludeDirs list of (sub)directories to exclude from copying
+    @keyparam excludePatterns list of filter pattern determining the files to
+        be skipped
+    """
+    try:
+        names = os.listdir(src)
+    except OSError:
+        # ignore missing directories
+        return
+    
+    for name in names:
+        skipIt = False
+        for excludePattern in excludePatterns:
+            if fnmatch.fnmatch(name, excludePattern):
+                skipIt = True
+                break
+        if not skipIt:
+            srcname = os.path.join(src, name)
+            dstname = os.path.join(dst, name)
+            for filter in filters:
+                if fnmatch.fnmatch(srcname, filter):
+                    if not os.path.isdir(dst):
+                        os.makedirs(dst)
+                    shutil.copy2(srcname, dstname)
+                    os.chmod(dstname, 0o644)
+                    break
+            else:
+                if os.path.isdir(srcname) and srcname not in excludeDirs:
+                    copyTree(srcname, dstname, filters,
+                             excludePatterns=excludePatterns)
+
+
+def cleanupSource(dirName):
+    """
+    Cleanup the sources directory to get rid of leftover files
+    and directories.
+    
+    @param dirName name of the directory to prune (string)
+    """
+    # step 1: delete the __pycache__ directory and all *.pyc files
+    if os.path.exists(os.path.join(dirName, "__pycache__")):
+        shutil.rmtree(os.path.join(dirName, "__pycache__"))
+    for name in [f for f in os.listdir(dirName)
+                 if fnmatch.fnmatch(f, "*.pyc")]:
+        os.remove(os.path.join(dirName, name))
+    
+    # step 2: descent into subdirectories and delete them if empty
+    for name in os.listdir(dirName):
+        name = os.path.join(dirName, name)
+        if os.path.isdir(name):
+            cleanupSource(name)
+            if len(os.listdir(name)) == 0:
+                os.rmdir(name)
+
+
+def cleanUp():
+    """
+    Uninstall the old eric debug client files.
+    """
+    global pyModDir
+    
+    try:
+        # Cleanup the install directories
+        dirname = os.path.join(pyModDir, installPackage)
+        if os.path.exists(dirname):
+            shutil.rmtree(dirname, True)
+    except (IOError, OSError) as msg:
+        sys.stderr.write(
+            'Error: {0}\nTry install with admin rights.\n'.format(msg))
+        exit(7)
+
+
+def shutilCopy(src, dst, perm=0o644):
+    """
+    Wrapper function around shutil.copy() to ensure the permissions.
+    
+    @param src source file name (string)
+    @param dst destination file name or directory name (string)
+    @keyparam perm permissions to be set (integer)
+    """
+    shutil.copy(src, dst)
+    if os.path.isdir(dst):
+        dst = os.path.join(dst, os.path.basename(src))
+    os.chmod(dst, perm)
+
+
+def installEricDebugClients():
+    """
+    Actually perform the installation steps.
+    
+    @return result code (integer)
+    """
+    global distDir, doCleanup, sourceDir, modDir
+    
+    # set install prefix, if not None
+    if distDir:
+        targetDir = os.path.normpath(os.path.join(distDir, installPackage))
+    else:
+        targetDir = os.path.join(modDir, installPackage)
+    
+    try:
+        # Install the files
+        # copy the various parts of eric6 debug clients
+        copyTree(
+            os.path.join(sourceDir, "DebugClients"), targetDir,
+            ['*.py', '*.pyc', '*.pyo', '*.pyw'],
+            ['{1}{0}.ropeproject'.format(os.sep, sourceDir)],
+            excludePatterns=["eric6config.py*"])
+        copyTree(
+            os.path.join(sourceDir, "DebugClients"), targetDir,
+            ['*.rb'],
+            ['{1}{0}Examples'.format(os.sep, sourceDir)])
+        
+        # copy the license file
+        shutilCopy(
+            '{1}{0}LICENSE.GPL3'.format(os.sep, sourceDir), targetDir)
+        
+    except (IOError, OSError) as msg:
+        sys.stderr.write(
+            'Error: {0}\nTry install with admin rights.\n'.format(msg))
+        return(7)
+    
+    return 0
+
+
+def main(argv):
+    """
+    The main function of the script.
+
+    @param argv the list of command line arguments.
+    """
+    import getopt
+
+    # Parse the command line.
+    global progName, modDir, doCleanup, doCompile, distDir
+    global sourceDir
+    
+    if sys.version_info < (2, 7, 0) or sys.version_info > (3, 9, 9):
+        print('Sorry, eric6 requires at least Python 2.7 or '
+              'Python 3 for running.')
+        exit(5)
+    
+    progName = os.path.basename(argv[0])
+    
+    if os.path.dirname(argv[0]):
+        os.chdir(os.path.dirname(argv[0]))
+    
+    initGlobals()
+
+    try:
+        if sys.platform.startswith("win"):
+            optlist, args = getopt.getopt(
+                argv[1:], "chzd:", ["help"])
+        elif sys.platform == "darwin":
+            optlist, args = getopt.getopt(
+                argv[1:], "chzd:i:", ["help"])
+        else:
+            optlist, args = getopt.getopt(
+                argv[1:], "chzd:i:", ["help"])
+    except getopt.GetoptError as err:
+        print(err)
+        usage()
+
+    for opt, arg in optlist:
+        if opt in ["-h", "--help"]:
+            usage(0)
+        elif opt == "-d":
+            modDir = arg
+        elif opt == "-i":
+            distDir = os.path.normpath(arg)
+        elif opt == "-c":
+            doCleanup = False
+        elif opt == "-z":
+            doCompile = False
+    
+    installFromSource = not os.path.isdir(sourceDir)
+    if installFromSource:
+        sourceDir = os.path.dirname(__file__) or "."
+    
+    # cleanup source if installing from source
+    if installFromSource:
+        print("Cleaning up source ...")
+        cleanupSource(os.path.join(sourceDir, "DebugClients"))
+        print()
+    
+    # cleanup old installation
+    try:
+        if doCleanup:
+            print("Cleaning up old installation ...")
+            if distDir:
+                shutil.rmtree(distDir, True)
+            else:
+                cleanUp()
+    except (IOError, OSError) as msg:
+        sys.stderr.write('Error: {0}\nTry install as root.\n'.format(msg))
+        exit(7)
+
+    if doCompile:
+        print("\nCompiling source files ...")
+        if sys.version_info[0] == 3:
+            skipRe = re.compile(r"DebugClients[\\/]Python[\\/]")
+        else:
+            skipRe = re.compile(r"DebugClients[\\/]Python3[\\/]")
+        # Hide compile errors (mainly because of Py2/Py3 differences)
+        sys.stdout = io.StringIO()
+        if distDir:
+            compileall.compile_dir(
+                os.path.join(sourceDir, "DebugClients"),
+                ddir=os.path.join(distDir, modDir, installPackage),
+                rx=skipRe,
+                quiet=True)
+        else:
+            compileall.compile_dir(
+                os.path.join(sourceDir, "DebugClients"),
+                ddir=os.path.join(modDir, installPackage),
+                rx=skipRe,
+                quiet=True)
+        sys.stdout = sys.__stdout__
+    print("\nInstalling eric6 debug clients ...")
+    res = installEricDebugClients()
+    
+    print("\nInstallation complete.")
+    print()
+    
+    exit(res)
+    
+    
+if __name__ == "__main__":
+    try:
+        main(sys.argv)
+    except SystemExit:
+        raise
+    except Exception:
+        print("""An internal error occured.  Please report all the output"""
+              """ of the program,\nincluding the following traceback, to"""
+              """ eric-bugs@eric-ide.python-projects.org.\n""")
+        raise
+
+#
+# eflag: noqa = M801

eric ide

mercurial