##// END OF EJS Templates
Add SVG qt console icon to package data.
Fernando Perez -
Show More
@@ -1,32 +1,34 b''
1 1 include ipython.py
2 2 include setupbase.py
3 3 include setupegg.py
4 4
5 5 graft setupext
6 6
7 7 graft scripts
8 8
9 9 # Load main dir but exclude things we don't want in the distro
10 10 graft IPython
11 11 prune IPython/deathrow
12 12 prune IPython/frontend/html/notebook/static/mathjax
13 13
14 14 include IPython/.git_commit_info.ini
15 15
16 include IPython/frontend/qt/console/resources/icon/IPythonConsole.svg
17
16 18 graft docs
17 19 exclude docs/\#*
18 20 exclude docs/man/*.1
19 21
20 22 # docs subdirs we want to skip
21 23 prune docs/attic
22 24 prune docs/build
23 25 prune docs/gh-pages
24 26
25 27
26 28 global-exclude *~
27 29 global-exclude *.flc
28 30 global-exclude *.pyc
29 31 global-exclude .dircopy.log
30 32 global-exclude .svn
31 33 global-exclude .bzr
32 34 global-exclude .hgignore
@@ -1,377 +1,378 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11 from __future__ import print_function
12 12
13 13 #-------------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-------------------------------------------------------------------------------
19 19
20 20 #-------------------------------------------------------------------------------
21 21 # Imports
22 22 #-------------------------------------------------------------------------------
23 23 import os
24 24 import sys
25 25
26 26 try:
27 27 from configparser import ConfigParser
28 28 except:
29 29 from ConfigParser import ConfigParser
30 30 from distutils.command.build_py import build_py
31 31 from glob import glob
32 32
33 33 from setupext import install_data_ext
34 34
35 35 #-------------------------------------------------------------------------------
36 36 # Useful globals and utility functions
37 37 #-------------------------------------------------------------------------------
38 38
39 39 # A few handy globals
40 40 isfile = os.path.isfile
41 41 pjoin = os.path.join
42 42
43 43 def oscmd(s):
44 44 print(">", s)
45 45 os.system(s)
46 46
47 47 try:
48 48 execfile
49 49 except NameError:
50 50 def execfile(fname, globs, locs=None):
51 51 locs = locs or globs
52 52 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
53 53
54 54 # A little utility we'll need below, since glob() does NOT allow you to do
55 55 # exclusion on multiple endings!
56 56 def file_doesnt_endwith(test,endings):
57 57 """Return true if test is a file and its name does NOT end with any
58 58 of the strings listed in endings."""
59 59 if not isfile(test):
60 60 return False
61 61 for e in endings:
62 62 if test.endswith(e):
63 63 return False
64 64 return True
65 65
66 66 #---------------------------------------------------------------------------
67 67 # Basic project information
68 68 #---------------------------------------------------------------------------
69 69
70 70 # release.py contains version, authors, license, url, keywords, etc.
71 71 execfile(pjoin('IPython','core','release.py'), globals())
72 72
73 73 # Create a dict with the basic information
74 74 # This dict is eventually passed to setup after additional keys are added.
75 75 setup_args = dict(
76 76 name = name,
77 77 version = version,
78 78 description = description,
79 79 long_description = long_description,
80 80 author = author,
81 81 author_email = author_email,
82 82 url = url,
83 83 download_url = download_url,
84 84 license = license,
85 85 platforms = platforms,
86 86 keywords = keywords,
87 87 classifiers = classifiers,
88 88 cmdclass = {'install_data': install_data_ext},
89 89 )
90 90
91 91
92 92 #---------------------------------------------------------------------------
93 93 # Find packages
94 94 #---------------------------------------------------------------------------
95 95
96 96 def find_packages():
97 97 """
98 98 Find all of IPython's packages.
99 99 """
100 100 excludes = ['deathrow']
101 101 packages = []
102 102 for dir,subdirs,files in os.walk('IPython'):
103 103 package = dir.replace(os.path.sep, '.')
104 104 if any([ package.startswith('IPython.'+exc) for exc in excludes ]):
105 105 # package is to be excluded (e.g. deathrow)
106 106 continue
107 107 if '__init__.py' not in files:
108 108 # not a package
109 109 continue
110 110 packages.append(package)
111 111 return packages
112 112
113 113 #---------------------------------------------------------------------------
114 114 # Find package data
115 115 #---------------------------------------------------------------------------
116 116
117 117 def find_package_data():
118 118 """
119 119 Find IPython's package_data.
120 120 """
121 121 # This is not enough for these things to appear in an sdist.
122 122 # We need to muck with the MANIFEST to get this to work
123 123
124 124 # walk notebook resources:
125 125 cwd = os.getcwd()
126 126 os.chdir(os.path.join('IPython', 'frontend', 'html', 'notebook'))
127 127 static_walk = list(os.walk('static'))
128 128 os.chdir(cwd)
129 129 static_data = []
130 130 for parent, dirs, files in static_walk:
131 131 for f in files:
132 132 static_data.append(os.path.join(parent, f))
133 133
134 134 package_data = {
135 135 'IPython.config.profile' : ['README', '*/*.py'],
136 136 'IPython.testing' : ['*.txt'],
137 'IPython.frontend.html.notebook' : ['templates/*']+static_data
137 'IPython.frontend.html.notebook' : ['templates/*'] + static_data,
138 'IPython.frontend.qt.console' : ['resources/icon/*.svg'],
138 139 }
139 140 return package_data
140 141
141 142
142 143 #---------------------------------------------------------------------------
143 144 # Find data files
144 145 #---------------------------------------------------------------------------
145 146
146 147 def make_dir_struct(tag,base,out_base):
147 148 """Make the directory structure of all files below a starting dir.
148 149
149 150 This is just a convenience routine to help build a nested directory
150 151 hierarchy because distutils is too stupid to do this by itself.
151 152
152 153 XXX - this needs a proper docstring!
153 154 """
154 155
155 156 # we'll use these a lot below
156 157 lbase = len(base)
157 158 pathsep = os.path.sep
158 159 lpathsep = len(pathsep)
159 160
160 161 out = []
161 162 for (dirpath,dirnames,filenames) in os.walk(base):
162 163 # we need to strip out the dirpath from the base to map it to the
163 164 # output (installation) path. This requires possibly stripping the
164 165 # path separator, because otherwise pjoin will not work correctly
165 166 # (pjoin('foo/','/bar') returns '/bar').
166 167
167 168 dp_eff = dirpath[lbase:]
168 169 if dp_eff.startswith(pathsep):
169 170 dp_eff = dp_eff[lpathsep:]
170 171 # The output path must be anchored at the out_base marker
171 172 out_path = pjoin(out_base,dp_eff)
172 173 # Now we can generate the final filenames. Since os.walk only produces
173 174 # filenames, we must join back with the dirpath to get full valid file
174 175 # paths:
175 176 pfiles = [pjoin(dirpath,f) for f in filenames]
176 177 # Finally, generate the entry we need, which is a pari of (output
177 178 # path, files) for use as a data_files parameter in install_data.
178 179 out.append((out_path, pfiles))
179 180
180 181 return out
181 182
182 183
183 184 def find_data_files():
184 185 """
185 186 Find IPython's data_files.
186 187
187 188 Most of these are docs.
188 189 """
189 190
190 191 docdirbase = pjoin('share', 'doc', 'ipython')
191 192 manpagebase = pjoin('share', 'man', 'man1')
192 193
193 194 # Simple file lists can be made by hand
194 195 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
195 196 if not manpages:
196 197 # When running from a source tree, the manpages aren't gzipped
197 198 manpages = filter(isfile, glob(pjoin('docs','man','*.1')))
198 199 igridhelpfiles = filter(isfile,
199 200 glob(pjoin('IPython','extensions','igrid_help.*')))
200 201
201 202 # For nested structures, use the utility above
202 203 example_files = make_dir_struct(
203 204 'data',
204 205 pjoin('docs','examples'),
205 206 pjoin(docdirbase,'examples')
206 207 )
207 208 manual_files = make_dir_struct(
208 209 'data',
209 210 pjoin('docs','html'),
210 211 pjoin(docdirbase,'manual')
211 212 )
212 213
213 214 # And assemble the entire output list
214 215 data_files = [ (manpagebase, manpages),
215 216 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
216 217 ] + manual_files + example_files
217 218
218 219 return data_files
219 220
220 221
221 222 def make_man_update_target(manpage):
222 223 """Return a target_update-compliant tuple for the given manpage.
223 224
224 225 Parameters
225 226 ----------
226 227 manpage : string
227 228 Name of the manpage, must include the section number (trailing number).
228 229
229 230 Example
230 231 -------
231 232
232 233 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
233 234 ('docs/man/ipython.1.gz',
234 235 ['docs/man/ipython.1'],
235 236 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
236 237 """
237 238 man_dir = pjoin('docs', 'man')
238 239 manpage_gz = manpage + '.gz'
239 240 manpath = pjoin(man_dir, manpage)
240 241 manpath_gz = pjoin(man_dir, manpage_gz)
241 242 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
242 243 locals() )
243 244 return (manpath_gz, [manpath], gz_cmd)
244 245
245 246 #---------------------------------------------------------------------------
246 247 # Find scripts
247 248 #---------------------------------------------------------------------------
248 249
249 250 def find_scripts(entry_points=False, suffix=''):
250 251 """Find IPython's scripts.
251 252
252 253 if entry_points is True:
253 254 return setuptools entry_point-style definitions
254 255 else:
255 256 return file paths of plain scripts [default]
256 257
257 258 suffix is appended to script names if entry_points is True, so that the
258 259 Python 3 scripts get named "ipython3" etc.
259 260 """
260 261 if entry_points:
261 262 console_scripts = [s % suffix for s in [
262 263 'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
263 264 'pycolor%s = IPython.utils.PyColorize:main',
264 265 'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
265 266 'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
266 267 'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
267 268 'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
268 269 'iptest%s = IPython.testing.iptest:main',
269 270 'irunner%s = IPython.lib.irunner:main'
270 271 ]]
271 272 gui_scripts = [s % suffix for s in [
272 273 'ipython%s-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
273 274 ]]
274 275 scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
275 276 else:
276 277 parallel_scripts = pjoin('IPython','parallel','scripts')
277 278 main_scripts = pjoin('IPython','scripts')
278 279 scripts = [
279 280 pjoin(parallel_scripts, 'ipengine'),
280 281 pjoin(parallel_scripts, 'ipcontroller'),
281 282 pjoin(parallel_scripts, 'ipcluster'),
282 283 pjoin(parallel_scripts, 'iplogger'),
283 284 pjoin(main_scripts, 'ipython'),
284 285 pjoin(main_scripts, 'pycolor'),
285 286 pjoin(main_scripts, 'irunner'),
286 287 pjoin(main_scripts, 'iptest')
287 288 ]
288 289 return scripts
289 290
290 291 #---------------------------------------------------------------------------
291 292 # Verify all dependencies
292 293 #---------------------------------------------------------------------------
293 294
294 295 def check_for_dependencies():
295 296 """Check for IPython's dependencies.
296 297
297 298 This function should NOT be called if running under setuptools!
298 299 """
299 300 from setupext.setupext import (
300 301 print_line, print_raw, print_status,
301 302 check_for_sphinx, check_for_pygments,
302 303 check_for_nose, check_for_pexpect,
303 304 check_for_pyzmq, check_for_readline
304 305 )
305 306 print_line()
306 307 print_raw("BUILDING IPYTHON")
307 308 print_status('python', sys.version)
308 309 print_status('platform', sys.platform)
309 310 if sys.platform == 'win32':
310 311 print_status('Windows version', sys.getwindowsversion())
311 312
312 313 print_raw("")
313 314 print_raw("OPTIONAL DEPENDENCIES")
314 315
315 316 check_for_sphinx()
316 317 check_for_pygments()
317 318 check_for_nose()
318 319 check_for_pexpect()
319 320 check_for_pyzmq()
320 321 check_for_readline()
321 322
322 323 def record_commit_info(pkg_dir, build_cmd=build_py):
323 324 """ Return extended build command class for recording commit
324 325
325 326 The extended command tries to run git to find the current commit, getting
326 327 the empty string if it fails. It then writes the commit hash into a file
327 328 in the `pkg_dir` path, named ``.git_commit_info.ini``.
328 329
329 330 In due course this information can be used by the package after it is
330 331 installed, to tell you what commit it was installed from if known.
331 332
332 333 To make use of this system, you need a package with a .git_commit_info.ini
333 334 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
334 335 this::
335 336
336 337 # This is an ini file that may contain information about the code state
337 338 [commit hash]
338 339 # The line below may contain a valid hash if it has been substituted
339 340 # during 'git archive'
340 341 archive_subst_hash=$Format:%h$
341 342 # This line may be modified by the install process
342 343 install_hash=
343 344
344 345 The .git_commit_info file above is also designed to be used with git
345 346 substitution - so you probably also want a ``.gitattributes`` file in the
346 347 root directory of your working tree that contains something like this::
347 348
348 349 myproject/.git_commit_info.ini export-subst
349 350
350 351 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
351 352 archive`` - useful in case someone makes such an archive - for example with
352 353 via the github 'download source' button.
353 354
354 355 Although all the above will work as is, you might consider having something
355 356 like a ``get_info()`` function in your package to display the commit
356 357 information at the terminal. See the ``pkg_info.py`` module in the nipy
357 358 package for an example.
358 359 """
359 360 class MyBuildPy(build_cmd):
360 361 ''' Subclass to write commit data into installation tree '''
361 362 def run(self):
362 363 build_cmd.run(self)
363 364 import subprocess
364 365 proc = subprocess.Popen('git rev-parse --short HEAD',
365 366 stdout=subprocess.PIPE,
366 367 stderr=subprocess.PIPE,
367 368 shell=True)
368 369 repo_commit, _ = proc.communicate()
369 370 # We write the installation commit even if it's empty
370 371 cfg_parser = ConfigParser()
371 372 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
372 373 cfg_parser.set('commit hash', 'install_hash', repo_commit.decode('ascii'))
373 374 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
374 375 out_file = open(out_pth, 'wt')
375 376 cfg_parser.write(out_file)
376 377 out_file.close()
377 378 return MyBuildPy
General Comments 0
You need to be logged in to leave comments. Login now