setup.py

branch
setup.py
changeset 6950
62e39a353cd9
parent 6949
a5255f1ba3f0
child 6951
ef3e87580dc9
--- a/setup.py	Mon Apr 15 19:53:29 2019 +0200
+++ b/setup.py	Tue Apr 16 19:43:53 2019 +0200
@@ -4,11 +4,17 @@
 # Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de>
 #
 
+"""
+Module to prepare a distribution package for uploading to PyPI.
+"""
+
 from __future__ import unicode_literals
 
 import os
 import sys
 import subprocess
+import shutil
+import fnmatch
 
 from setuptools import setup, find_packages
 from distutils.command.install_data import install_data
@@ -25,9 +31,15 @@
     @rtype str
     """
     version = "<unknown>"
-    with open(os.path.join(os.path.dirname(__file__), "VERSION"),
-              encoding="ASCII") as f:
-        version = f.read().strip()
+    if sys.argv[-1].startswith(("1", "2")):
+        # assume it is a version info starting with year
+        version = sys.argv[-1]
+        del sys.argv[-1]
+    else:
+        # calculate according our version scheme (year.month)
+        import datetime
+        today = datetime.date.today()
+        version = "{0}.{1}".format(today.year - 2000, today.month)
     return version
 
 
@@ -65,9 +77,10 @@
                 'eric6/icons/default/eric.png',
                 'eric6/icons/default/ericWeb48.png'
             ]),
-            ('share/metainfo', ['linux/eric6.appdata.xml'])
+            ('share/appdata', ['linux/eric6.appdata.xml']),
+            ('share/metainfo', ['linux/eric6.appdata.xml']),
         ]
-    elif os.name == 'nt':
+    elif sys.platform.startswith(("win", "cygwin")):
         dataFiles = [
             ('scripts', [
                 'eric6/pixmaps/eric6.ico',
@@ -81,26 +94,148 @@
 ## make Linux detect eric6 desktop files
 ######################################################################
 
-class Eric6InstallData(install_data):
+class Eric6InstallDataWrapper(install_data):
+    """
+    Class providing an install_data command wrapper to perform
+    post-installation tasks.
+    """
     def run(self):
+        """
+        Public method to perform the data installation.
+        """
+        # do the distutils install_data first
         install_data.run(self)
+        
+        # now perform our post installation stuff
         if sys.platform.startswith('linux'):
             try:
                 subprocess.call(['update-desktop-database'])
             except:
                 print("ERROR: unable to update desktop database",
                       file=sys.stderr)
+
 CmdClass = {
-    'install_data': Eric6InstallData,
+    'install_data': Eric6InstallDataWrapper,
 }
 
 ######################################################################
+## functions to prepare the sources for building
+######################################################################
+
+def prepareInfoFile(fileName, version):
+    """
+    Function to prepare an Info.py file when installing from source.
+    
+    @param fileName name of the Python file containing the info (string)
+    @param version version string for the package (string)
+    """
+    if not fileName:
+        return
+    
+    try:
+        os.rename(fileName, fileName + ".orig")
+    except EnvironmentError:
+        pass
+    try:
+        hgOut = subprocess.check_output(["hg", "identify", "-i"])
+        if sys.version_info[0] == 3:
+            hgOut = hgOut.decode()
+    except (OSError, subprocess.CalledProcessError):
+        hgOut = ""
+    if hgOut:
+        hgOut = hgOut.strip()
+        if hgOut.endswith("+"):
+            hgOut = hgOut[:-1]
+        f = open(fileName + ".orig", "r", encoding="utf-8")
+        text = f.read()
+        f.close()
+        text = text.replace("@@REVISION@@", hgOut)\
+            .replace("@@VERSION@@", version)
+        f = open(fileName, "w")
+        f.write(text)
+        f.close()
+    else:
+        shutil.copy(fileName + ".orig", fileName)
+
+
+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 all Ui_*.py files without a corresponding
+    #         *.ui file
+    dirListing = os.listdir(dirName)
+    for formName, sourceName in [
+        (f.replace('Ui_', "").replace(".py", ".ui"), f)
+            for f in dirListing if fnmatch.fnmatch(f, "Ui_*.py")]:
+        if not os.path.exists(os.path.join(dirName, formName)):
+            os.remove(os.path.join(dirName, sourceName))
+            if os.path.exists(os.path.join(dirName, sourceName + "c")):
+                os.remove(os.path.join(dirName, sourceName + "c"))
+    
+    # step 2: delete the __pycache__ directory and all remaining *.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 3: delete *.orig files
+    for name in [f for f in os.listdir(dirName)
+                 if fnmatch.fnmatch(f, "*.orig")]:
+        os.remove(os.path.join(dirName, name))
+    
+    # step 4: 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 __pyName(py_dir, py_file):
+    """
+    Local function to create the Python source file name for the compiled
+    .ui file.
+    
+    @param py_dir suggested name of the directory (string)
+    @param py_file suggested name for the compile source file (string)
+    @return tuple of directory name (string) and source file name (string)
+    """
+    return py_dir, "Ui_{0}".format(py_file)
+
+
+def compileUiFiles(dirName):
+    """
+    Compile the .ui files to Python sources.
+    
+    @param dirName name of the directory to compile UI files for (string)
+    """
+    from PyQt5.uic import compileUiDir
+    compileUiDir(dirName, True, __pyName)
+
+######################################################################
 ## setup() below
 ######################################################################
 
+Version = getVersion()
+sourceDir = os.path.join(os.path.dirname(__file__), "eric6")
+infoFileName = os.path.join(sourceDir, "UI", "Info.py")
+if sys.argv[1].startswith("bdist"):
+    # prepare the sources under "eric6" for building the wheel file
+    print("preparing the sources...")
+    cleanupSource(sourceDir)
+    compileUiFiles(sourceDir)
+    prepareInfoFile(infoFileName, Version)
+    print("Preparation finished")
+
 setup(
     name="eric6",
-    version=getVersion(),
+    version=Version,
     description="eric6 is an integrated development environment for the"
         " Python language.",
     long_description="eric6 is an integrated development environment for the"
@@ -148,18 +283,18 @@
         "pip",
         "docutils",
         "Markdown",
+        "pywin32>=1.0;platform_system=='Windows'",
     ],
     data_files=getDataFiles(),
     packages=find_packages(),
-#    include_package_data=True,
     zip_safe=False,
     package_data={
         "": getPackageData(
             "eric6",
             [".png", ".svg", ".svgz", ".xpm", ".ico", ".gif", ".icns", ".txt",
              ".style", ".tmpl", ".html", ".qch", ".css", ".qss", ".e4h",
-             ".e6h", ".api", ".bas" ".dat"]) + 
-            ["i18n/eric6_de.qm", "i18n/eric6_en.qm", "i18n/eric6_es.qm",
+             ".e6h", ".api", ".bas" ".dat"]
+        ) + ["i18n/eric6_de.qm", "i18n/eric6_en.qm", "i18n/eric6_es.qm",
              "i18n/eric6_ru.qm",
         ]
     },
@@ -190,7 +325,15 @@
         "console_scripts":[
             "eric6_api = eric6.eric6_api:main",
             "eric6_doc = eric6.eric6_doc:main",
+            "eric6_post_install = eric6.eric6_post_install:main"
         ],
     },
     cmdclass=CmdClass,
 )
+
+if os.path.exists(infoFileName + ".orig"):
+    try:
+        os.remove(infoFileName)
+        os.rename(infoFileName + ".orig", infoFileName)
+    except EnvironmentError:
+        pass

eric ide

mercurial