2007-03-29 21:01:28 +00:00
#! /usr/bin/env python
2009-09-20 18:03:43 +00:00
# -*- coding: utf-8 -*-
2016-03-23 05:22:53 +00:00
import sys
2006-12-05 08:29:26 +00:00
2010-05-04 09:43:40 +00:00
# Tahoe-LAFS -- secure, distributed storage grid
2008-07-14 21:53:25 +00:00
#
2012-03-13 20:50:57 +00:00
# Copyright © 2006-2012 The Tahoe-LAFS Software Foundation
2008-07-14 21:53:25 +00:00
#
2009-08-02 02:57:10 +00:00
# This file is part of Tahoe-LAFS.
2008-07-14 21:53:25 +00:00
#
2011-05-10 19:16:50 +00:00
# See the docs/about.rst file for licensing information.
2006-12-05 08:29:26 +00:00
2016-02-16 18:59:02 +00:00
import os , subprocess , re
2008-09-12 01:03:21 +00:00
basedir = os . path . dirname ( os . path . abspath ( __file__ ) )
2008-12-06 00:30:54 +00:00
2009-08-18 01:00:57 +00:00
# locate our version number
def read_version_py ( infname ) :
try :
verstrline = open ( infname , " rt " ) . read ( )
except EnvironmentError :
return None
else :
VSRE = r " ^verstr = [ ' \" ]([^ ' \" ]*)[ ' \" ] "
mo = re . search ( VSRE , verstrline , re . M )
if mo :
return mo . group ( 1 )
2014-11-21 07:56:21 +00:00
VERSION_PY_FILENAME = ' src/allmydata/_version.py '
version = read_version_py ( VERSION_PY_FILENAME )
2009-08-18 01:00:57 +00:00
2016-03-25 19:16:01 +00:00
APPNAME = ' tahoe-lafs '
2010-10-29 22:28:25 +00:00
APPNAMEFILE = os . path . join ( ' src ' , ' allmydata ' , ' _appname.py ' )
APPNAMEFILESTR = " __appname__ = ' %s ' " % ( APPNAME , )
try :
curappnamefilestr = open ( APPNAMEFILE , ' rU ' ) . read ( )
except EnvironmentError :
# No file, or unreadable or something, okay then let's try to write one.
open ( APPNAMEFILE , " w " ) . write ( APPNAMEFILESTR )
else :
if curappnamefilestr . strip ( ) != APPNAMEFILESTR :
2013-03-15 04:28:35 +00:00
print ( " Error -- this setup.py file is configured with the ' application name ' to be ' %s ' , but there is already a file in place in ' %s ' which contains the contents ' %s ' . If the file is wrong, please remove it and setup.py will regenerate it and write ' %s ' into it. " % ( APPNAME , APPNAMEFILE , curappnamefilestr , APPNAMEFILESTR ) )
2010-10-29 22:28:25 +00:00
sys . exit ( - 1 )
# 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()
# below.
adglobals = { }
2016-03-23 05:22:53 +00:00
auto_deps_fn = " src/allmydata/_auto_deps.py "
if sys . version_info [ 0 ] > = 3 :
exec ( compile ( open ( auto_deps_fn , ' rb ' ) . read ( ) , auto_deps_fn , " exec " ) ,
adglobals , adglobals )
else :
execfile ( auto_deps_fn , adglobals )
2010-10-29 22:28:25 +00:00
install_requires = adglobals [ ' install_requires ' ]
2015-05-02 21:26:39 +00:00
setup_requires = adglobals [ ' setup_requires ' ]
2010-10-29 22:28:25 +00:00
2011-01-15 02:26:51 +00:00
if len ( sys . argv ) > 1 and sys . argv [ 1 ] == ' --fakedependency ' :
del sys . argv [ 1 ]
install_requires + = [ " fakedependency >= 1.0.0 " ]
2012-01-08 18:16:54 +00:00
from setuptools import setup
2009-01-29 14:00:58 +00:00
from setuptools import Command
2016-02-23 18:25:35 +00:00
from setuptools . command import install
2008-12-01 18:48:04 +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 " ,
" 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 " ,
2011-01-08 21:12:12 +00:00
" Programming Language :: Python :: 2.7 " ,
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 " ,
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
2011-12-05 04:40:01 +00:00
GIT_VERSION_BODY = '''
# This _version.py is generated from git metadata by the tahoe setup.py.
2016-03-23 05:22:53 +00:00
__pkgname__ = " %(pkgname)s "
real_version = " %(version)s "
full_version = " %(full)s "
branch = " %(branch)s "
verstr = " %(normalized)s "
2011-12-05 05:49:16 +00:00
__version__ = verstr
2011-12-05 04:40:01 +00:00
'''
2014-11-21 05:14:18 +00:00
def run_command ( args , cwd = None ) :
2015-02-17 19:10:54 +00:00
use_shell = sys . platform == " win32 "
2011-12-05 04:40:01 +00:00
try :
2015-02-17 19:10:54 +00:00
p = subprocess . Popen ( args , stdout = subprocess . PIPE , cwd = cwd , shell = use_shell )
2015-12-02 19:55:59 +00:00
except EnvironmentError as e : # if this gives a SyntaxError, note that Tahoe-LAFS requires Python 2.7+
2014-11-21 05:14:18 +00:00
print ( " Warning: unable to run %r . " % ( " " . join ( args ) , ) )
print ( e )
2011-12-05 04:40:01 +00:00
return None
stdout = p . communicate ( ) [ 0 ] . strip ( )
if p . returncode != 0 :
2014-11-21 05:14:18 +00:00
print ( " Warning: %r returned error code %r . " % ( " " . join ( args ) , p . returncode ) )
2011-12-05 04:40:01 +00:00
return None
return stdout
2014-11-21 05:14:18 +00:00
def versions_from_git ( tag_prefix ) :
# This runs 'git' from the directory that contains this file. That either
2011-12-05 04:40:01 +00:00
# means someone ran a setup.py command (and this code is in
# versioneer.py, thus the containing directory is the root of the source
# tree), or someone ran a project-specific entry point (and this code is
# in _version.py, thus the containing directory is somewhere deeper in
# the source tree). This only gets called if the git-archive 'subst'
# variables were *not* expanded, and _version.py hasn't already been
# rewritten with a short version string, meaning we're inside a checked
# out source tree.
# versions_from_git (as copied from python-versioneer) returns strings
# like "1.9.0-25-gb73aba9-dirty", which means we're in a tree with
# uncommited changes (-dirty), the latest checkin is revision b73aba9,
# the most recent tag was 1.9.0, and b73aba9 has 25 commits that weren't
# in 1.9.0 . The narrow-minded NormalizedVersion parser that takes our
# output (meant to enable sorting of version strings) refuses most of
# that. Tahoe uses a function named suggest_normalized_version() that can
# handle "1.9.0.post25", so dumb down our output to match.
try :
source_dir = os . path . dirname ( os . path . abspath ( __file__ ) )
2014-11-21 05:14:18 +00:00
except NameError as e :
2011-12-05 04:40:01 +00:00
# some py2exe/bbfreeze/non-CPython implementations don't do __file__
2014-11-21 05:14:18 +00:00
print ( " Warning: unable to find version because we could not obtain the source directory. " )
print ( e )
return { }
2015-02-17 19:10:54 +00:00
stdout = run_command ( [ " git " , " describe " , " --tags " , " --dirty " , " --always " ] ,
2011-12-05 04:40:01 +00:00
cwd = source_dir )
if stdout is None :
2014-11-21 05:14:18 +00:00
# run_command already complained.
2011-12-05 04:40:01 +00:00
return { }
2016-03-23 05:22:53 +00:00
stdout = stdout . decode ( " ascii " )
2011-12-05 04:40:01 +00:00
if not stdout . startswith ( tag_prefix ) :
2014-11-21 05:14:18 +00:00
print ( " Warning: tag %r doesn ' t start with prefix %r . " % ( stdout , tag_prefix ) )
2011-12-05 04:40:01 +00:00
return { }
version = stdout [ len ( tag_prefix ) : ]
pieces = version . split ( " - " )
if len ( pieces ) == 1 :
normalized_version = pieces [ 0 ]
else :
normalized_version = " %s .post %s " % ( pieces [ 0 ] , pieces [ 1 ] )
2013-04-25 01:14:50 +00:00
2015-02-17 19:10:54 +00:00
stdout = run_command ( [ " git " , " rev-parse " , " HEAD " ] , cwd = source_dir )
2011-12-05 04:40:01 +00:00
if stdout is None :
2014-11-21 05:14:18 +00:00
# run_command already complained.
2011-12-05 04:40:01 +00:00
return { }
2016-03-23 05:22:53 +00:00
full = stdout . decode ( " ascii " ) . strip ( )
2011-12-05 04:40:01 +00:00
if version . endswith ( " -dirty " ) :
full + = " -dirty "
2011-12-05 05:49:16 +00:00
normalized_version + = " .dev0 "
2013-04-25 01:14:50 +00:00
# Thanks to Jistanidiot at <http://stackoverflow.com/questions/6245570/get-current-branch-name>.
2015-02-17 19:10:54 +00:00
stdout = run_command ( [ " git " , " rev-parse " , " --abbrev-ref " , " HEAD " ] , cwd = source_dir )
2016-03-23 05:22:53 +00:00
branch = ( stdout or b " unknown " ) . decode ( " ascii " ) . strip ( )
2013-04-25 01:14:50 +00:00
2016-03-23 05:22:53 +00:00
# this returns native strings (bytes on py2, unicode on py3)
return { " version " : version , " normalized " : normalized_version ,
" full " : full , " branch " : branch }
2011-12-05 04:40:01 +00:00
2013-03-19 22:26:21 +00:00
# setup.cfg has an [aliases] section which runs "update_version" before many
# commands (like "build" and "sdist") that need to know our package version
# ahead of time. If you add different commands (or if we forgot some), you
# may need to add it to setup.cfg and configure it to run update_version
# before your command.
2011-12-05 04:40:01 +00:00
class UpdateVersion ( Command ) :
description = " update _version.py from revision-control metadata "
2016-02-23 18:25:35 +00:00
user_options = install . install . user_options
2011-12-05 04:40:01 +00:00
def initialize_options ( self ) :
pass
def finalize_options ( self ) :
pass
def run ( self ) :
2014-11-21 08:38:37 +00:00
global version
verstr = version
2013-03-19 22:26:21 +00:00
if os . path . isdir ( os . path . join ( basedir , " .git " ) ) :
verstr = self . try_from_git ( )
2014-11-21 08:38:37 +00:00
2011-12-05 04:40:01 +00:00
if verstr :
self . distribution . metadata . version = verstr
2014-11-21 08:38:37 +00:00
else :
print ( """ \
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Warning : no version information found . This may cause tests to fail .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
""" )
2011-12-05 04:40:01 +00:00
2013-03-19 22:26:21 +00:00
def try_from_git ( self ) :
2014-11-21 05:00:05 +00:00
# If we change APPNAME, the release tag names should also change from then on.
versions = versions_from_git ( APPNAME + ' - ' )
2016-03-23 05:22:53 +00:00
# setup.py might be run by either py2 or py3 (when run by tox, which
# uses py3 on modern debian/ubuntu distros). We want this generated
# file to contain native strings on both (str=bytes in py2,
# str=unicode in py3)
2011-12-05 04:40:01 +00:00
if versions :
2016-03-23 05:22:53 +00:00
body = GIT_VERSION_BODY % {
" pkgname " : self . distribution . get_name ( ) ,
" version " : versions [ " version " ] ,
" normalized " : versions [ " normalized " ] ,
" full " : versions [ " full " ] ,
" branch " : versions [ " branch " ] ,
}
2014-11-21 07:56:21 +00:00
f = open ( VERSION_PY_FILENAME , " wb " )
2016-03-23 05:22:53 +00:00
f . write ( body . encode ( " ascii " ) )
2013-03-19 22:26:21 +00:00
f . close ( )
2014-11-21 08:38:37 +00:00
print ( " Wrote normalized version %r into ' %s ' " % ( versions [ " normalized " ] , VERSION_PY_FILENAME ) )
2014-11-21 07:56:21 +00:00
2011-12-05 04:40:01 +00:00
return versions . get ( " normalized " , None )
2009-08-18 01:00:57 +00:00
setup_args = { }
if version :
setup_args [ " version " ] = version
versioning: include an "appname" in the application version string in the versioning protocol, and make that appname be controlled by setup.py
It is currently hardcoded in setup.py to be 'allmydata-tahoe'. Ticket #556 is to make it configurable by a runtime command-line argument to setup.py: "--appname=foo", but I suddenly wondered if we really wanted that and at the same time realized that we don't need that for tahoe-1.3.0 release, so this patch just hardcodes it in setup.py.
setup.py inspects a file named 'src/allmydata/_appname.py' and assert that it contains the string "__appname__ = 'allmydata-tahoe'", and creates it if it isn't already present. src/allmydata/__init__.py import _appname and reads __appname__ from it. The rest of the Python code imports allmydata and inspects "allmydata.__appname__", although actually every use it uses "allmydata.__full_version__" instead, where "allmydata.__full_version__" is created in src/allmydata/__init__.py to be:
__full_version__ = __appname + '-' + str(__version__).
All the code that emits an "application version string" when describing what version of a protocol it supports (introducer server, storage server, upload helper), or when describing itself in general (introducer client), usese allmydata.__full_version__.
This fixes ticket #556 at least well enough for tahoe-1.3.0 release.
2009-02-12 00:18:16 +00:00
setup ( name = APPNAME ,
2015-07-31 17:21:47 +00:00
description = ' secure, decentralized, fault-tolerant file store ' ,
2014-09-09 17:51:44 +00:00
long_description = open ( ' README.rst ' , ' rU ' ) . read ( ) ,
2010-05-04 09:43:40 +00:00
author = ' the Tahoe-LAFS project ' ,
2010-09-30 15:37:08 +00:00
author_email = ' tahoe-dev@tahoe-lafs.org ' ,
2011-10-29 18:39:46 +00:00
url = ' https://tahoe-lafs.org/ ' ,
2014-09-09 17:51:44 +00:00
license = ' GNU GPL ' , # see README.rst -- there is an alternative licence
2016-03-22 20:59:10 +00:00
cmdclass = { " update_version " : UpdateVersion ,
2008-09-12 01:03:21 +00:00
} ,
2007-11-10 01:04:19 +00:00
package_dir = { ' ' : ' src ' } ,
2012-01-08 18:16:54 +00:00
packages = [ ' allmydata ' ,
' allmydata.frontends ' ,
' allmydata.immutable ' ,
' allmydata.immutable.downloader ' ,
' allmydata.introducer ' ,
' allmydata.mutable ' ,
' allmydata.scripts ' ,
' allmydata.storage ' ,
' allmydata.test ' ,
' allmydata.util ' ,
' allmydata.web ' ,
' allmydata.windows ' ,
2016-03-23 05:56:03 +00:00
] ,
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 ,
2016-04-12 19:15:42 +00:00
extras_require = { " test " : [ " pyflakes " , " coverage " ] ,
} ,
2014-03-29 00:41:33 +00:00
package_data = { " allmydata.web " : [ " *.xhtml " ,
" static/*.js " , " static/*.png " , " static/*.css " ,
" static/img/*.png " ,
" static/css/*.css " ,
]
2012-01-08 18:16:54 +00:00
} ,
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 ' ] } ,
2009-08-18 01:00:57 +00:00
* * setup_args
2007-04-27 20:47:15 +00:00
)