2007-03-29 21:01:28 +00:00
#! /usr/bin/env python
2006-12-05 08:29:26 +00:00
2007-04-30 20:06:09 +00:00
# Allmydata Tahoe -- secure, distributed storage grid
2008-07-14 21:53:25 +00:00
#
2008-01-22 17:22:51 +00:00
# Copyright (C) 2008 Allmydata, Inc.
2008-07-14 21:53:25 +00:00
#
2007-04-27 20:47:15 +00:00
# This file is part of tahoe.
2008-07-14 21:53:25 +00:00
#
2008-01-08 18:45:00 +00:00
# See the docs/about.html file for licensing information.
2006-12-05 08:29:26 +00:00
2009-01-09 19:42:22 +00:00
import os , re , shutil , stat , subprocess , sys , zipfile
2008-09-12 01:03:21 +00:00
##### sys.path management
2008-12-06 00:30:54 +00:00
def pylibdir ( prefixdir ) :
pyver = " python %d . %d " % ( sys . version_info [ : 2 ] )
if sys . platform == " win32 " :
return os . path . join ( prefixdir , " Lib " , " site-packages " )
else :
return os . path . join ( prefixdir , " lib " , pyver , " site-packages " )
2008-09-12 01:03:21 +00:00
basedir = os . path . dirname ( os . path . abspath ( __file__ ) )
2008-12-06 00:30:54 +00:00
supportlib = pylibdir ( os . path . join ( basedir , " support " ) )
2009-01-29 05:56:08 +00:00
prefixdirs = [ ] # argh! horrible kludge to work-around setuptools #54
2008-12-06 00:30:54 +00:00
for i in range ( len ( sys . argv ) ) :
arg = sys . argv [ i ]
if arg . startswith ( " --prefix= " ) :
2009-01-29 05:56:08 +00:00
prefixdirs . append ( arg [ len ( " --prefix= " ) : ] )
2008-12-06 00:30:54 +00:00
if arg == " --prefix " :
if len ( sys . argv ) > i + 1 :
2009-01-29 05:56:08 +00:00
prefixdirs . append ( sys . argv [ i + 1 ] )
2008-12-06 00:30:54 +00:00
2009-01-29 14:00:00 +00:00
# The following horrible kludge to workaround setuptools #17 is commented-out, because I can't at this moment figure out how to make sure the horrible kludge gets executed only when it is needed (i.e., only when a "setup.py develop" step is about to happen), and the bad effect of setuptools #17 is "only" that setuptools re-installs extant packages.
# if arg.startswith("develop") or arg.startswith("build") or arg.startswith("test"): # argh! horrible kludge to workaround setuptools #17
# if sys.platform == "linux2":
# # workaround for tahoe #229 / setuptools #17, on debian
# sys.argv.extend(["--site-dirs", "/var/lib/python-support/python%d.%d" % (sys.version_info[:2])])
# elif sys.platform == "darwin":
# # this probably only applies to leopard 10.5, possibly only 10.5.5
# sd = "/System/Library/Frameworks/Python.framework/Versions/%d.%d/Extras/lib/python" % (sys.version_info[:2])
# sys.argv.extend(["--site-dirs", sd])
2007-12-22 17:44:47 +00:00
2009-01-29 05:56:08 +00:00
if not prefixdirs :
prefixdirs . append ( " support " )
for prefixdir in prefixdirs :
libdir = pylibdir ( prefixdir )
try :
os . makedirs ( libdir )
except EnvironmentError , le :
# Okay, maybe the dir was already there.
pass
sys . path . append ( libdir )
pp = os . environ . get ( ' PYTHONPATH ' , ' ' ) . split ( os . pathsep )
pp . append ( libdir )
os . environ [ ' PYTHONPATH ' ] = os . pathsep . join ( pp )
2007-11-09 21:58:03 +00:00
try :
from ez_setup import use_setuptools
except ImportError :
pass
2007-09-13 01:57:10 +00:00
else :
2008-03-26 19:13:02 +00:00
# This invokes our own customized version of ez_setup.py to make sure that
# setuptools >= v0.6c8 (a.k.a. v0.6-final) is installed.
# setuptools < v0.6c8 doesn't handle eggs which get installed into the CWD
# as a result of being transitively depended on in a setup_requires, but
# then are needed for the installed code to run, i.e. in an
# install_requires.
2008-12-06 00:30:54 +00:00
use_setuptools ( download_delay = 0 , min_version = " 0.6c10dev " )
2007-09-13 21:51:19 +00:00
2008-09-17 23:08:29 +00:00
from setuptools import find_packages , setup
2008-08-27 18:26:44 +00:00
from setuptools . command import sdist
2009-01-29 14:00:58 +00:00
from setuptools import Command
2009-01-09 19:42:22 +00:00
from pkg_resources import require
2008-12-01 18:48:04 +00:00
2008-01-23 00:24:33 +00:00
# Make the dependency-version-requirement, which is used by the Makefile at
# build-time, also available to the app at runtime:
import shutil
2008-09-24 00:04:02 +00:00
shutil . copyfile ( " _auto_deps.py " , os . path . join ( " src " , " allmydata " , " _auto_deps.py " ) )
2008-01-23 00:24:33 +00:00
2007-04-27 20:47:15 +00:00
trove_classifiers = [
2008-04-14 18:08:23 +00:00
" Development Status :: 5 - Production/Stable " ,
2007-04-27 20:47:15 +00:00
" Environment :: Console " ,
" Environment :: Web Environment " ,
2008-07-14 21:53:25 +00:00
" License :: OSI Approved :: GNU General Public License (GPL) " ,
2008-01-08 18:45:00 +00:00
" License :: DFSG approved " ,
" License :: Other/Proprietary License " ,
2008-07-14 21:53:25 +00:00
" Intended Audience :: Developers " ,
2007-04-27 20:47:15 +00:00
" Intended Audience :: End Users/Desktop " ,
" Intended Audience :: System Administrators " ,
" Operating System :: Microsoft " ,
" Operating System :: Microsoft :: Windows " ,
2008-10-21 16:32:00 +00:00
" Operating System :: Microsoft :: Windows :: Windows NT/2000 " ,
2007-04-27 20:47:15 +00:00
" Operating System :: Unix " ,
" Operating System :: POSIX :: Linux " ,
" Operating System :: POSIX " ,
" Operating System :: MacOS :: MacOS X " ,
2008-07-14 21:53:25 +00:00
" Operating System :: OS Independent " ,
" Natural Language :: English " ,
" Programming Language :: C " ,
" Programming Language :: Python " ,
2008-10-21 16:32:00 +00:00
" Programming Language :: Python :: 2 " ,
" Programming Language :: Python :: 2.4 " ,
" Programming Language :: Python :: 2.5 " ,
2009-01-29 01:26:28 +00:00
" Programming Language :: Python :: 2.6 " ,
2007-04-27 20:47:15 +00:00
" Topic :: Utilities " ,
" Topic :: System :: Systems Administration " ,
" Topic :: System :: Filesystems " ,
" Topic :: System :: Distributed Computing " ,
" Topic :: Software Development :: Libraries " ,
" Topic :: Communications :: Usenet News " ,
2008-07-14 21:53:25 +00:00
" Topic :: System :: Archiving :: Backup " ,
" Topic :: System :: Archiving :: Mirroring " ,
" Topic :: System :: Archiving " ,
2007-04-27 20:47:15 +00:00
]
2006-12-14 10:25:30 +00:00
2007-05-04 03:14:07 +00:00
2009-01-29 19:56:40 +00:00
# Note that the darcsver command from the darcsver plugin is needed to initialize the
# distribution's .version attribute correctly. (It does this either by examining darcs history,
# or if that fails by reading the src/allmydata/_version.py file).
2007-08-14 20:57:41 +00:00
LONG_DESCRIPTION = \
2008-07-14 21:53:25 +00:00
""" Welcome to the Tahoe project, a secure, decentralized, fault-tolerant
filesystem . All of the source code is available under a Free Software , Open
2008-01-22 15:35:38 +00:00
Source licence .
2008-07-14 21:53:25 +00:00
This filesystem is encrypted and spread over multiple peers in such a way that
it remains available even when some of the peers are unavailable ,
2008-01-22 15:35:38 +00:00
malfunctioning , or malicious . """
2006-12-05 08:29:26 +00:00
2007-08-14 20:57:41 +00:00
2008-04-09 18:30:53 +00:00
setup_requires = [ ]
2008-09-17 01:36:27 +00:00
2008-10-25 13:50:42 +00:00
# Nevow requires Twisted to setup, but doesn't declare that requirement in a way that enables
# setuptools to satisfy that requirement before Nevow's setup.py tried to "import twisted".
2009-01-27 05:40:46 +00:00
# Fortunately we require setuptools_trial to setup and setuptools_trial requires Twisted to
# install, so hopefully everything will work out until the Nevow issue is fixed:
# http://divmod.org/trac/ticket/2629
# setuptools_trial is needed if you want "./setup.py trial" or "./setup.py test" to execute the
# tests (and in order to make sure Twisted is installed early enough -- see the paragraph
# above).
# http://pypi.python.org/pypi/setuptools_trial
setup_requires . extend ( [ ' setuptools_trial ' ] )
2008-10-25 13:50:42 +00:00
2009-01-20 19:42:29 +00:00
# darcsver is needed if you want "./setup.py darcsver" to write a new version stamp in
# src/allmydata/_version.py, with a version number derived from darcs history.
2008-01-01 06:28:31 +00:00
# http://pypi.python.org/pypi/darcsver
2009-01-29 19:56:40 +00:00
setup_requires . append ( ' darcsver >= 1.2.0 ' )
2008-01-01 06:28:31 +00:00
2009-01-27 05:40:46 +00:00
if ' trial ' in sys . argv [ 1 : ] or ' test ' in sys . argv [ 1 : ] :
2009-01-14 16:15:46 +00:00
# Cygwin requires the poll reactor to work at all. Linux requires the poll reactor to avoid
# bug #402 (twisted bug #3218). In general, the poll reactor is better than the select
# reactor, but it is not available on all platforms. According to exarkun on IRC, it is
# available but buggy on some versions of Mac OS X, so just because you can install it
# doesn't mean we want to use it on every platform.
if sys . platform in ( " linux2 " , " cygwin " ) :
2009-01-14 17:40:22 +00:00
if not [ a for a in sys . argv if a . startswith ( " --reactor " ) ] :
sys . argv . append ( " --reactor=poll " )
2009-01-17 01:00:47 +00:00
2008-01-22 15:35:38 +00:00
# setuptools_darcs is required to produce complete distributions (such as with
# "sdist" or "bdist_egg"), unless there is a PKG-INFO file present which shows
# that this is itself a source distribution.
2008-01-01 06:28:31 +00:00
# http://pypi.python.org/pypi/setuptools_darcs
2008-01-22 15:35:38 +00:00
if not os . path . exists ( ' PKG-INFO ' ) :
2008-01-23 00:42:54 +00:00
setup_requires . append ( ' setuptools_darcs >= 1.1.0 ' )
2008-01-22 15:35:38 +00:00
2008-09-12 01:03:21 +00:00
class ShowSupportLib ( Command ) :
user_options = [ ]
def initialize_options ( self ) :
pass
def finalize_options ( self ) :
pass
def run ( self ) :
# TODO: --quiet suppresses the 'running show_supportlib' message.
# Find a way to do this all the time.
print supportlib # TODO windowsy
class ShowPythonPath ( Command ) :
user_options = [ ]
def initialize_options ( self ) :
pass
def finalize_options ( self ) :
pass
def run ( self ) :
# TODO: --quiet suppresses the 'running show_supportlib' message.
# Find a way to do this all the time.
2009-01-15 03:37:51 +00:00
print " PYTHONPATH= %s " % os . environ . get ( " PYTHONPATH " , ' ' )
2008-09-12 01:03:21 +00:00
2008-09-12 04:44:18 +00:00
class RunWithPythonPath ( Command ) :
description = " Run a subcommand with PYTHONPATH set appropriately "
user_options = [ ( " python " , " p " ,
" Treat command string as arguments to a python executable " ) ,
( " command= " , " c " , " Command to be run " ) ,
( " directory= " , " d " , " Directory to run the command in " ) ,
]
boolean_options = [ " python " ]
def initialize_options ( self ) :
self . command = None
self . python = False
self . directory = None
def finalize_options ( self ) :
pass
def run ( self ) :
2009-01-15 03:37:51 +00:00
oldpp = os . environ . get ( " PYTHONPATH " , " " ) . split ( os . pathsep )
if oldpp == [ " " ] :
# grr silly split() behavior
oldpp = [ ]
os . environ [ ' PYTHONPATH ' ] = os . pathsep . join ( oldpp + [ supportlib , ] )
# We must require the command to be safe to split on
# whitespace, and have --python and --directory to make it
# easier to achieve this.
2008-09-12 04:44:18 +00:00
command = [ ]
if self . python :
command . append ( sys . executable )
if self . command :
command . extend ( self . command . split ( ) )
if not command :
raise RuntimeError ( " The --command argument is mandatory " )
if self . directory :
os . chdir ( self . directory )
if self . verbose :
print " command = " , " " . join ( command )
rc = subprocess . call ( command )
sys . exit ( rc )
2008-09-12 03:59:04 +00:00
class CheckAutoDeps ( Command ) :
user_options = [ ]
def initialize_options ( self ) :
pass
def finalize_options ( self ) :
pass
def run ( self ) :
import _auto_deps
_auto_deps . require_auto_deps ( )
2009-01-29 01:07:16 +00:00
class MakeExecutable ( Command ) :
2008-09-12 01:03:21 +00:00
user_options = [ ]
def initialize_options ( self ) :
pass
def finalize_options ( self ) :
pass
def run ( self ) :
2009-01-29 01:07:16 +00:00
bin_tahoe_template = os . path . join ( " bin " , " tahoe-script.template " )
# Create the 'tahoe-script.py' file under the 'bin' directory. The 'tahoe-script.py'
# file is exactly the same as the 'tahoe-script.template' script except that the shebang
# line is rewritten to use our sys.executable for the interpreter. On Windows, create a
# tahoe.exe will execute it. On non-Windows, make a symlink to it from 'tahoe'. The
# tahoe.exe will be copied from the setuptools egg's cli.exe and this will work from a
# zip-safe and non-zip-safe setuptools egg.
f = open ( bin_tahoe_template , " rU " )
script_lines = f . readlines ( )
f . close ( )
script_lines [ 0 ] = " #! %s \n " % sys . executable
tahoe_script = os . path . join ( " bin " , " tahoe-script.py " )
f = open ( tahoe_script , " w " )
for line in script_lines :
f . write ( line )
f . close ( )
2009-01-09 19:42:22 +00:00
if sys . platform == " win32 " :
setuptools_egg = require ( " setuptools " ) [ 0 ] . location
if os . path . isfile ( setuptools_egg ) :
z = zipfile . ZipFile ( setuptools_egg , ' r ' )
for filename in z . namelist ( ) :
if ' cli.exe ' in filename :
cli_exe = z . read ( filename )
else :
cli_exe = os . path . join ( setuptools_egg , ' setuptools ' , ' cli.exe ' )
tahoe_exe = os . path . join ( " bin " , " tahoe.exe " )
if os . path . isfile ( setuptools_egg ) :
f = open ( tahoe_exe , ' wb ' )
f . write ( cli_exe )
f . close ( )
else :
shutil . copy ( cli_exe , tahoe_exe )
2009-01-29 01:07:16 +00:00
else :
try :
os . remove ( os . path . join ( ' bin ' , ' tahoe ' ) )
except :
# okay, probably it was already gone
pass
os . symlink ( ' tahoe-script.py ' , os . path . join ( ' bin ' , ' tahoe ' ) )
# chmod +x bin/tahoe-script.py
old_mode = stat . S_IMODE ( os . stat ( tahoe_script ) [ stat . ST_MODE ] )
new_mode = old_mode | ( stat . S_IXUSR | stat . S_IRUSR |
stat . S_IXGRP | stat . S_IRGRP |
stat . S_IXOTH | stat . S_IROTH )
os . chmod ( tahoe_script , new_mode )
2008-09-12 01:03:21 +00:00
2008-08-27 18:26:44 +00:00
class MySdist ( sdist . sdist ) :
""" A hook in the sdist command so that we can determine whether this the
tarball should be ' SUMO ' or not , i . e . whether or not to include the
2008-09-17 20:01:19 +00:00
external dependency tarballs . Note that we always include
misc / dependencies / * in the tarball ; - - sumo controls whether tahoe - deps / *
is included as well .
2008-08-27 18:26:44 +00:00
"""
user_options = sdist . sdist . user_options + \
2008-09-17 20:01:19 +00:00
[ ( ' sumo ' , ' s ' ,
" create a ' sumo ' sdist which includes the contents of tahoe-deps/* " ) ,
]
2008-08-27 18:26:44 +00:00
boolean_options = [ ' sumo ' ]
def initialize_options ( self ) :
sdist . sdist . initialize_options ( self )
2008-09-17 20:01:19 +00:00
self . sumo = False
def make_distribution ( self ) :
# add our extra files to the list just before building the
# tarball/zipfile. We override make_distribution() instead of run()
# because setuptools.command.sdist.run() does not lend itself to
# easy/robust subclassing (the code we need to add goes right smack
# in the middle of a 12-line method). If this were the distutils
# version, we'd override get_file_list().
if self . sumo :
# If '--sumo' was specified, include tahoe-deps/* in the sdist.
# We assume that the user has fetched the tahoe-deps.tar.gz
# tarball and unpacked it already.
self . filelist . extend ( [ os . path . join ( " tahoe-deps " , fn )
for fn in os . listdir ( " tahoe-deps " ) ] )
# In addition, we want the tarball/zipfile to have -SUMO in the
# name, and the unpacked directory to have -SUMO too. The easiest
# way to do this is to patch self.distribution and override the
# get_fullname() method. (an alternative is to modify
# self.distribution.metadata.version, but that also affects the
# contents of PKG-INFO).
fullname = self . distribution . get_fullname ( )
def get_fullname ( ) :
return fullname + " -SUMO "
self . distribution . get_fullname = get_fullname
return sdist . sdist . make_distribution ( self )
2008-08-27 18:26:44 +00:00
2008-09-17 01:36:27 +00:00
# Tahoe's dependencies are managed by the find_links= entry in setup.cfg and
# the _auto_deps.install_requires list, which is used in the call to setup()
# at the end of this file
2008-09-12 01:03:21 +00:00
from _auto_deps import install_requires
2008-01-01 06:28:31 +00:00
2007-08-14 20:57:41 +00:00
setup ( name = ' allmydata-tahoe ' ,
2008-01-22 17:22:51 +00:00
description = ' secure, decentralized, fault-tolerant filesystem ' ,
2007-08-14 20:57:41 +00:00
long_description = LONG_DESCRIPTION ,
2008-04-18 18:58:00 +00:00
author = ' the allmydata.org Tahoe project ' ,
2007-04-27 20:47:15 +00:00
author_email = ' tahoe-dev@allmydata.org ' ,
url = ' http://allmydata.org/ ' ,
2008-01-08 18:45:00 +00:00
license = ' GNU GPL ' ,
2008-09-12 01:03:21 +00:00
cmdclass = { " show_supportlib " : ShowSupportLib ,
" show_pythonpath " : ShowPythonPath ,
2008-09-12 04:44:18 +00:00
" run_with_pythonpath " : RunWithPythonPath ,
2008-09-12 03:59:04 +00:00
" check_auto_deps " : CheckAutoDeps ,
2009-01-29 01:07:16 +00:00
" make_executable " : MakeExecutable ,
2008-09-12 01:03:21 +00:00
" sdist " : MySdist ,
} ,
2007-11-10 01:04:19 +00:00
package_dir = { ' ' : ' src ' } ,
packages = find_packages ( " src " ) ,
2007-04-27 20:47:15 +00:00
classifiers = trove_classifiers ,
test_suite = " allmydata.test " ,
2008-09-12 01:03:21 +00:00
install_requires = install_requires ,
2007-11-10 01:04:19 +00:00
include_package_data = True ,
2008-01-01 06:28:31 +00:00
setup_requires = setup_requires ,
2007-10-11 10:38:24 +00:00
entry_points = { ' console_scripts ' : [ ' tahoe = allmydata.scripts.runner:run ' ] } ,
2007-09-13 22:37:55 +00:00
zip_safe = False , # We prefer unzipped for easier access.
2007-04-27 20:47:15 +00:00
)