setupbase.py
320 lines
| 10.9 KiB
| text/x-python
|
PythonLexer
Brian E Granger
|
r1237 | # encoding: utf-8 | ||
Brian E Granger
|
r1239 | """ | ||
This module defines the things that are used in setup.py for building IPython | ||||
This includes: | ||||
* The basic arguments to setup | ||||
* Functions for finding things like packages, package data, etc. | ||||
* A function for checking dependencies. | ||||
""" | ||||
Brian E Granger
|
r1237 | __docformat__ = "restructuredtext en" | ||
#------------------------------------------------------------------------------- | ||||
# Copyright (C) 2008 The IPython Development Team | ||||
# | ||||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#------------------------------------------------------------------------------- | ||||
#------------------------------------------------------------------------------- | ||||
# Imports | ||||
#------------------------------------------------------------------------------- | ||||
import os, sys | ||||
from glob import glob | ||||
from setupext import install_data_ext | ||||
#------------------------------------------------------------------------------- | ||||
# Useful globals and utility functions | ||||
#------------------------------------------------------------------------------- | ||||
# A few handy globals | ||||
isfile = os.path.isfile | ||||
pjoin = os.path.join | ||||
def oscmd(s): | ||||
print ">", s | ||||
os.system(s) | ||||
# A little utility we'll need below, since glob() does NOT allow you to do | ||||
# exclusion on multiple endings! | ||||
def file_doesnt_endwith(test,endings): | ||||
"""Return true if test is a file and its name does NOT end with any | ||||
of the strings listed in endings.""" | ||||
if not isfile(test): | ||||
return False | ||||
for e in endings: | ||||
if test.endswith(e): | ||||
return False | ||||
return True | ||||
#--------------------------------------------------------------------------- | ||||
# Basic project information | ||||
#--------------------------------------------------------------------------- | ||||
Brian Granger
|
r2146 | # release.py contains version, authors, license, url, keywords, etc. | ||
Brian Granger
|
r2058 | execfile(pjoin('IPython','core','release.py')) | ||
Brian E Granger
|
r1237 | |||
# Create a dict with the basic information | ||||
# This dict is eventually passed to setup after additional keys are added. | ||||
setup_args = dict( | ||||
name = name, | ||||
version = version, | ||||
description = description, | ||||
long_description = long_description, | ||||
author = author, | ||||
author_email = author_email, | ||||
url = url, | ||||
download_url = download_url, | ||||
license = license, | ||||
platforms = platforms, | ||||
keywords = keywords, | ||||
cmdclass = {'install_data': install_data_ext}, | ||||
) | ||||
#--------------------------------------------------------------------------- | ||||
# Find packages | ||||
#--------------------------------------------------------------------------- | ||||
Fernando Perez
|
r1525 | def add_package(packages,pname,config=False,tests=False,scripts=False, | ||
others=None): | ||||
Brian E Granger
|
r1239 | """ | ||
Add a package to the list of packages, including certain subpackages. | ||||
""" | ||||
Brian E Granger
|
r1240 | packages.append('.'.join(['IPython',pname])) | ||
Brian E Granger
|
r1237 | if config: | ||
Brian E Granger
|
r1240 | packages.append('.'.join(['IPython',pname,'config'])) | ||
Brian E Granger
|
r1237 | if tests: | ||
Brian E Granger
|
r1240 | packages.append('.'.join(['IPython',pname,'tests'])) | ||
Brian E Granger
|
r1237 | if scripts: | ||
Brian E Granger
|
r1240 | packages.append('.'.join(['IPython',pname,'scripts'])) | ||
Brian E Granger
|
r1237 | if others is not None: | ||
for o in others: | ||||
Brian E Granger
|
r1240 | packages.append('.'.join(['IPython',pname,o])) | ||
Brian E Granger
|
r1237 | |||
def find_packages(): | ||||
Brian E Granger
|
r1239 | """ | ||
Find all of IPython's packages. | ||||
""" | ||||
Brian E Granger
|
r1240 | packages = ['IPython'] | ||
Brian Granger
|
r2269 | add_package(packages, 'config', tests=True, others=['default','profile']) | ||
Brian Granger
|
r2058 | add_package(packages, 'core', tests=True) | ||
add_package(packages, 'deathrow', tests=True) | ||||
Brian Granger
|
r2064 | add_package(packages , 'extensions') | ||
Brian E Granger
|
r1237 | add_package(packages, 'external') | ||
gvaroquaux
|
r1488 | add_package(packages, 'frontend', tests=True) | ||
Brian Granger
|
r2058 | # Don't include the cocoa frontend for now as it is not stable | ||
if sys.platform == 'darwin' and False: | ||||
add_package(packages, 'frontend.cocoa', tests=True, others=['plugin']) | ||||
add_package(packages, 'frontend.cocoa.examples') | ||||
add_package(packages, 'frontend.cocoa.examples.IPython1Sandbox') | ||||
add_package(packages, 'frontend.cocoa.examples.IPython1Sandbox.English.lproj') | ||||
Gael Varoquaux
|
r1947 | add_package(packages, 'frontend.process') | ||
gvaroquaux
|
r1486 | add_package(packages, 'frontend.wx') | ||
Brian Granger
|
r2058 | add_package(packages, 'gui') | ||
add_package(packages, 'gui.wx') | ||||
bgranger
|
r2315 | add_package(packages, 'kernel', config=False, tests=True, scripts=True) | ||
add_package(packages, 'kernel.core', config=False, tests=True) | ||||
Brian Granger
|
r2058 | add_package(packages, 'lib', tests=True) | ||
add_package(packages, 'quarantine', tests=True) | ||||
add_package(packages, 'scripts') | ||||
Brian E Granger
|
r1237 | add_package(packages, 'testing', tests=True) | ||
Fernando Perez
|
r1580 | add_package(packages, 'testing.plugin', tests=False) | ||
Brian Granger
|
r2058 | add_package(packages, 'utils', tests=True) | ||
Brian E Granger
|
r1237 | return packages | ||
#--------------------------------------------------------------------------- | ||||
# Find package data | ||||
#--------------------------------------------------------------------------- | ||||
def find_package_data(): | ||||
Brian E Granger
|
r1239 | """ | ||
Find IPython's package_data. | ||||
""" | ||||
Brian E Granger
|
r1237 | # This is not enough for these things to appear in an sdist. | ||
# We need to muck with the MANIFEST to get this to work | ||||
Brian E Granger
|
r1317 | package_data = { | ||
Brian Granger
|
r2058 | 'IPython.config.userconfig' : ['*'], | ||
Brian E Granger
|
r1317 | 'IPython.testing' : ['*.txt'] | ||
} | ||||
Brian E Granger
|
r1237 | return package_data | ||
#--------------------------------------------------------------------------- | ||||
# Find data files | ||||
#--------------------------------------------------------------------------- | ||||
Fernando Perez
|
r1525 | def make_dir_struct(tag,base,out_base): | ||
"""Make the directory structure of all files below a starting dir. | ||||
This is just a convenience routine to help build a nested directory | ||||
hierarchy because distutils is too stupid to do this by itself. | ||||
XXX - this needs a proper docstring! | ||||
""" | ||||
# we'll use these a lot below | ||||
lbase = len(base) | ||||
pathsep = os.path.sep | ||||
lpathsep = len(pathsep) | ||||
out = [] | ||||
for (dirpath,dirnames,filenames) in os.walk(base): | ||||
# we need to strip out the dirpath from the base to map it to the | ||||
# output (installation) path. This requires possibly stripping the | ||||
# path separator, because otherwise pjoin will not work correctly | ||||
# (pjoin('foo/','/bar') returns '/bar'). | ||||
dp_eff = dirpath[lbase:] | ||||
if dp_eff.startswith(pathsep): | ||||
dp_eff = dp_eff[lpathsep:] | ||||
# The output path must be anchored at the out_base marker | ||||
out_path = pjoin(out_base,dp_eff) | ||||
# Now we can generate the final filenames. Since os.walk only produces | ||||
# filenames, we must join back with the dirpath to get full valid file | ||||
# paths: | ||||
pfiles = [pjoin(dirpath,f) for f in filenames] | ||||
# Finally, generate the entry we need, which is a triple of (tag,output | ||||
# path, files) for use as a data_files parameter in install_data. | ||||
out.append((tag,out_path,pfiles)) | ||||
return out | ||||
Brian E Granger
|
r1237 | def find_data_files(): | ||
Brian E Granger
|
r1239 | """ | ||
Find IPython's data_files. | ||||
Fernando Perez
|
r1525 | |||
Most of these are docs. | ||||
Brian E Granger
|
r1239 | """ | ||
Brian E Granger
|
r1237 | |||
Brian Granger
|
r2058 | docdirbase = pjoin('share', 'doc', 'ipython') | ||
manpagebase = pjoin('share', 'man', 'man1') | ||||
Fernando Perez
|
r1525 | # Simple file lists can be made by hand | ||
Brian Granger
|
r2058 | manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz'))) | ||
Brian Granger
|
r2064 | igridhelpfiles = filter(isfile, glob(pjoin('IPython','extensions','igrid_help.*'))) | ||
Fernando Perez
|
r1525 | |||
# For nested structures, use the utility above | ||||
Brian Granger
|
r2058 | example_files = make_dir_struct( | ||
'data', | ||||
pjoin('docs','examples'), | ||||
pjoin(docdirbase,'examples') | ||||
) | ||||
manual_files = make_dir_struct( | ||||
'data', | ||||
pjoin('docs','dist'), | ||||
pjoin(docdirbase,'manual') | ||||
) | ||||
Fernando Perez
|
r1525 | |||
# And assemble the entire output list | ||||
data_files = [ ('data',manpagebase, manpages), | ||||
('data',pjoin(docdirbase,'extensions'),igridhelpfiles), | ||||
] + manual_files + example_files | ||||
Fernando Perez
|
r1522 | ## import pprint # dbg | ||
## print '*'*80 | ||||
## print 'data files' | ||||
## pprint.pprint(data_files) | ||||
## print '*'*80 | ||||
return data_files | ||||
Brian E Granger
|
r1237 | |||
Fernando Perez
|
r2100 | |||
def make_man_update_target(manpage): | ||||
"""Return a target_update-compliant tuple for the given manpage. | ||||
Parameters | ||||
---------- | ||||
manpage : string | ||||
Name of the manpage, must include the section number (trailing number). | ||||
Example | ||||
------- | ||||
>>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE | ||||
('docs/man/ipython.1.gz', | ||||
['docs/man/ipython.1'], | ||||
'cd docs/man && gzip -9c ipython.1 > ipython.1.gz') | ||||
""" | ||||
man_dir = pjoin('docs', 'man') | ||||
manpage_gz = manpage + '.gz' | ||||
manpath = pjoin(man_dir, manpage) | ||||
manpath_gz = pjoin(man_dir, manpage_gz) | ||||
gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" % | ||||
locals() ) | ||||
return (manpath_gz, [manpath], gz_cmd) | ||||
Brian E Granger
|
r1237 | #--------------------------------------------------------------------------- | ||
# Find scripts | ||||
#--------------------------------------------------------------------------- | ||||
def find_scripts(): | ||||
Brian E Granger
|
r1239 | """ | ||
Find IPython's scripts. | ||||
""" | ||||
Brian Granger
|
r2058 | kernel_scripts = pjoin('IPython','kernel','scripts') | ||
main_scripts = pjoin('IPython','scripts') | ||||
scripts = [pjoin(kernel_scripts, 'ipengine'), | ||||
pjoin(kernel_scripts, 'ipcontroller'), | ||||
pjoin(kernel_scripts, 'ipcluster'), | ||||
pjoin(main_scripts, 'ipython'), | ||||
pjoin(main_scripts, 'ipythonx'), | ||||
pjoin(main_scripts, 'ipython-wx'), | ||||
pjoin(main_scripts, 'pycolor'), | ||||
pjoin(main_scripts, 'irunner'), | ||||
pjoin(main_scripts, 'iptest') | ||||
] | ||||
Brian E Granger
|
r1237 | |||
# Script to be run by the windows binary installer after the default setup | ||||
# routine, to add shortcuts and similar windows-only things. Windows | ||||
# post-install scripts MUST reside in the scripts/ dir, otherwise distutils | ||||
# doesn't find them. | ||||
if 'bdist_wininst' in sys.argv: | ||||
if len(sys.argv) > 2 and ('sdist' in sys.argv or 'bdist_rpm' in sys.argv): | ||||
print >> sys.stderr,"ERROR: bdist_wininst must be run alone. Exiting." | ||||
sys.exit(1) | ||||
Brian Granger
|
r2060 | scripts.append(pjoin('scripts','ipython_win_post_install.py')) | ||
Brian E Granger
|
r1237 | |||
return scripts | ||||
#--------------------------------------------------------------------------- | ||||
Fernando Perez
|
r1525 | # Verify all dependencies | ||
Brian E Granger
|
r1237 | #--------------------------------------------------------------------------- | ||
def check_for_dependencies(): | ||||
Brian E Granger
|
r1239 | """Check for IPython's dependencies. | ||
This function should NOT be called if running under setuptools! | ||||
""" | ||||
Brian E Granger
|
r1237 | from setupext.setupext import ( | ||
print_line, print_raw, print_status, print_message, | ||||
check_for_zopeinterface, check_for_twisted, | ||||
check_for_foolscap, check_for_pyopenssl, | ||||
check_for_sphinx, check_for_pygments, | ||||
check_for_nose, check_for_pexpect | ||||
) | ||||
print_line() | ||||
print_raw("BUILDING IPYTHON") | ||||
print_status('python', sys.version) | ||||
print_status('platform', sys.platform) | ||||
if sys.platform == 'win32': | ||||
print_status('Windows version', sys.getwindowsversion()) | ||||
print_raw("") | ||||
print_raw("OPTIONAL DEPENDENCIES") | ||||
check_for_zopeinterface() | ||||
check_for_twisted() | ||||
check_for_foolscap() | ||||
check_for_pyopenssl() | ||||
check_for_sphinx() | ||||
check_for_pygments() | ||||
check_for_nose() | ||||
gvaroquaux
|
r1486 | check_for_pexpect() | ||