setup.py

branch
setup.py
changeset 6950
62e39a353cd9
parent 6949
a5255f1ba3f0
child 6951
ef3e87580dc9
equal deleted inserted replaced
6949:a5255f1ba3f0 6950:62e39a353cd9
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> 4 # Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de>
5 # 5 #
6
7 """
8 Module to prepare a distribution package for uploading to PyPI.
9 """
6 10
7 from __future__ import unicode_literals 11 from __future__ import unicode_literals
8 12
9 import os 13 import os
10 import sys 14 import sys
11 import subprocess 15 import subprocess
16 import shutil
17 import fnmatch
12 18
13 from setuptools import setup, find_packages 19 from setuptools import setup, find_packages
14 from distutils.command.install_data import install_data 20 from distutils.command.install_data import install_data
15 21
16 ###################################################################### 22 ######################################################################
23 29
24 @return string containing the version 30 @return string containing the version
25 @rtype str 31 @rtype str
26 """ 32 """
27 version = "<unknown>" 33 version = "<unknown>"
28 with open(os.path.join(os.path.dirname(__file__), "VERSION"), 34 if sys.argv[-1].startswith(("1", "2")):
29 encoding="ASCII") as f: 35 # assume it is a version info starting with year
30 version = f.read().strip() 36 version = sys.argv[-1]
37 del sys.argv[-1]
38 else:
39 # calculate according our version scheme (year.month)
40 import datetime
41 today = datetime.date.today()
42 version = "{0}.{1}".format(today.year - 2000, today.month)
31 return version 43 return version
32 44
33 45
34 def getPackageData(package, extensions): 46 def getPackageData(package, extensions):
35 """ 47 """
63 ]), 75 ]),
64 ('share/icons', [ 76 ('share/icons', [
65 'eric6/icons/default/eric.png', 77 'eric6/icons/default/eric.png',
66 'eric6/icons/default/ericWeb48.png' 78 'eric6/icons/default/ericWeb48.png'
67 ]), 79 ]),
68 ('share/metainfo', ['linux/eric6.appdata.xml']) 80 ('share/appdata', ['linux/eric6.appdata.xml']),
81 ('share/metainfo', ['linux/eric6.appdata.xml']),
69 ] 82 ]
70 elif os.name == 'nt': 83 elif sys.platform.startswith(("win", "cygwin")):
71 dataFiles = [ 84 dataFiles = [
72 ('scripts', [ 85 ('scripts', [
73 'eric6/pixmaps/eric6.ico', 86 'eric6/pixmaps/eric6.ico',
74 'eric6/pixmaps/ericWeb48.ico']) 87 'eric6/pixmaps/ericWeb48.ico'])
75 ] 88 ]
79 92
80 ###################################################################### 93 ######################################################################
81 ## make Linux detect eric6 desktop files 94 ## make Linux detect eric6 desktop files
82 ###################################################################### 95 ######################################################################
83 96
84 class Eric6InstallData(install_data): 97 class Eric6InstallDataWrapper(install_data):
98 """
99 Class providing an install_data command wrapper to perform
100 post-installation tasks.
101 """
85 def run(self): 102 def run(self):
103 """
104 Public method to perform the data installation.
105 """
106 # do the distutils install_data first
86 install_data.run(self) 107 install_data.run(self)
108
109 # now perform our post installation stuff
87 if sys.platform.startswith('linux'): 110 if sys.platform.startswith('linux'):
88 try: 111 try:
89 subprocess.call(['update-desktop-database']) 112 subprocess.call(['update-desktop-database'])
90 except: 113 except:
91 print("ERROR: unable to update desktop database", 114 print("ERROR: unable to update desktop database",
92 file=sys.stderr) 115 file=sys.stderr)
116
93 CmdClass = { 117 CmdClass = {
94 'install_data': Eric6InstallData, 118 'install_data': Eric6InstallDataWrapper,
95 } 119 }
96 120
97 ###################################################################### 121 ######################################################################
122 ## functions to prepare the sources for building
123 ######################################################################
124
125 def prepareInfoFile(fileName, version):
126 """
127 Function to prepare an Info.py file when installing from source.
128
129 @param fileName name of the Python file containing the info (string)
130 @param version version string for the package (string)
131 """
132 if not fileName:
133 return
134
135 try:
136 os.rename(fileName, fileName + ".orig")
137 except EnvironmentError:
138 pass
139 try:
140 hgOut = subprocess.check_output(["hg", "identify", "-i"])
141 if sys.version_info[0] == 3:
142 hgOut = hgOut.decode()
143 except (OSError, subprocess.CalledProcessError):
144 hgOut = ""
145 if hgOut:
146 hgOut = hgOut.strip()
147 if hgOut.endswith("+"):
148 hgOut = hgOut[:-1]
149 f = open(fileName + ".orig", "r", encoding="utf-8")
150 text = f.read()
151 f.close()
152 text = text.replace("@@REVISION@@", hgOut)\
153 .replace("@@VERSION@@", version)
154 f = open(fileName, "w")
155 f.write(text)
156 f.close()
157 else:
158 shutil.copy(fileName + ".orig", fileName)
159
160
161 def cleanupSource(dirName):
162 """
163 Cleanup the sources directory to get rid of leftover files
164 and directories.
165
166 @param dirName name of the directory to prune (string)
167 """
168 # step 1: delete all Ui_*.py files without a corresponding
169 # *.ui file
170 dirListing = os.listdir(dirName)
171 for formName, sourceName in [
172 (f.replace('Ui_', "").replace(".py", ".ui"), f)
173 for f in dirListing if fnmatch.fnmatch(f, "Ui_*.py")]:
174 if not os.path.exists(os.path.join(dirName, formName)):
175 os.remove(os.path.join(dirName, sourceName))
176 if os.path.exists(os.path.join(dirName, sourceName + "c")):
177 os.remove(os.path.join(dirName, sourceName + "c"))
178
179 # step 2: delete the __pycache__ directory and all remaining *.pyc files
180 if os.path.exists(os.path.join(dirName, "__pycache__")):
181 shutil.rmtree(os.path.join(dirName, "__pycache__"))
182 for name in [f for f in os.listdir(dirName)
183 if fnmatch.fnmatch(f, "*.pyc")]:
184 os.remove(os.path.join(dirName, name))
185
186 # step 3: delete *.orig files
187 for name in [f for f in os.listdir(dirName)
188 if fnmatch.fnmatch(f, "*.orig")]:
189 os.remove(os.path.join(dirName, name))
190
191 # step 4: descent into subdirectories and delete them if empty
192 for name in os.listdir(dirName):
193 name = os.path.join(dirName, name)
194 if os.path.isdir(name):
195 cleanupSource(name)
196 if len(os.listdir(name)) == 0:
197 os.rmdir(name)
198
199
200 def __pyName(py_dir, py_file):
201 """
202 Local function to create the Python source file name for the compiled
203 .ui file.
204
205 @param py_dir suggested name of the directory (string)
206 @param py_file suggested name for the compile source file (string)
207 @return tuple of directory name (string) and source file name (string)
208 """
209 return py_dir, "Ui_{0}".format(py_file)
210
211
212 def compileUiFiles(dirName):
213 """
214 Compile the .ui files to Python sources.
215
216 @param dirName name of the directory to compile UI files for (string)
217 """
218 from PyQt5.uic import compileUiDir
219 compileUiDir(dirName, True, __pyName)
220
221 ######################################################################
98 ## setup() below 222 ## setup() below
99 ###################################################################### 223 ######################################################################
224
225 Version = getVersion()
226 sourceDir = os.path.join(os.path.dirname(__file__), "eric6")
227 infoFileName = os.path.join(sourceDir, "UI", "Info.py")
228 if sys.argv[1].startswith("bdist"):
229 # prepare the sources under "eric6" for building the wheel file
230 print("preparing the sources...")
231 cleanupSource(sourceDir)
232 compileUiFiles(sourceDir)
233 prepareInfoFile(infoFileName, Version)
234 print("Preparation finished")
100 235
101 setup( 236 setup(
102 name="eric6", 237 name="eric6",
103 version=getVersion(), 238 version=Version,
104 description="eric6 is an integrated development environment for the" 239 description="eric6 is an integrated development environment for the"
105 " Python language.", 240 " Python language.",
106 long_description="eric6 is an integrated development environment for the" 241 long_description="eric6 is an integrated development environment for the"
107 " Python language. It uses the PyQt5 bindings and the QScintilla2" 242 " Python language. It uses the PyQt5 bindings and the QScintilla2"
108 " editor widget. See https://eric-ide.python-projects.org for more" 243 " editor widget. See https://eric-ide.python-projects.org for more"
146 "PyQtWebEngine>=5.12.1", 281 "PyQtWebEngine>=5.12.1",
147 "QScintilla>=2.11.1", 282 "QScintilla>=2.11.1",
148 "pip", 283 "pip",
149 "docutils", 284 "docutils",
150 "Markdown", 285 "Markdown",
286 "pywin32>=1.0;platform_system=='Windows'",
151 ], 287 ],
152 data_files=getDataFiles(), 288 data_files=getDataFiles(),
153 packages=find_packages(), 289 packages=find_packages(),
154 # include_package_data=True,
155 zip_safe=False, 290 zip_safe=False,
156 package_data={ 291 package_data={
157 "": getPackageData( 292 "": getPackageData(
158 "eric6", 293 "eric6",
159 [".png", ".svg", ".svgz", ".xpm", ".ico", ".gif", ".icns", ".txt", 294 [".png", ".svg", ".svgz", ".xpm", ".ico", ".gif", ".icns", ".txt",
160 ".style", ".tmpl", ".html", ".qch", ".css", ".qss", ".e4h", 295 ".style", ".tmpl", ".html", ".qch", ".css", ".qss", ".e4h",
161 ".e6h", ".api", ".bas" ".dat"]) + 296 ".e6h", ".api", ".bas" ".dat"]
162 ["i18n/eric6_de.qm", "i18n/eric6_en.qm", "i18n/eric6_es.qm", 297 ) + ["i18n/eric6_de.qm", "i18n/eric6_en.qm", "i18n/eric6_es.qm",
163 "i18n/eric6_ru.qm", 298 "i18n/eric6_ru.qm",
164 ] 299 ]
165 }, 300 },
166 entry_points={ 301 entry_points={
167 "gui_scripts": [ 302 "gui_scripts": [
188 "eric6_unittest = eric6.eric6_unittest:main", 323 "eric6_unittest = eric6.eric6_unittest:main",
189 ], 324 ],
190 "console_scripts":[ 325 "console_scripts":[
191 "eric6_api = eric6.eric6_api:main", 326 "eric6_api = eric6.eric6_api:main",
192 "eric6_doc = eric6.eric6_doc:main", 327 "eric6_doc = eric6.eric6_doc:main",
328 "eric6_post_install = eric6.eric6_post_install:main"
193 ], 329 ],
194 }, 330 },
195 cmdclass=CmdClass, 331 cmdclass=CmdClass,
196 ) 332 )
333
334 if os.path.exists(infoFileName + ".orig"):
335 try:
336 os.remove(infoFileName)
337 os.rename(infoFileName + ".orig", infoFileName)
338 except EnvironmentError:
339 pass

eric ide

mercurial