X-Git-Url: https://git.rkrishnan.org/?a=blobdiff_plain;f=setup.py;h=63697e004a4c7113b18d6733d8a7973719e97c72;hb=HEAD;hp=bbb662df4140e3775d96969851f96f3cbfed3821;hpb=b82cddef7b7f5eeed867001cd605431e1e18f9e9;p=tahoe-lafs%2Ftahoe-lafs.git diff --git a/setup.py b/setup.py index bbb662df..63697e00 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #! /usr/bin/env python # -*- coding: utf-8 -*- -u"Tahoe-LAFS does not run under Python 3. Please use a version of Python between 2.5 and 2.7.x inclusive." +import sys; assert sys.version_info < (3,), ur"Tahoe-LAFS does not run under Python 3. Please use Python 2.7.x." # Tahoe-LAFS -- secure, distributed storage grid # @@ -10,7 +10,7 @@ u"Tahoe-LAFS does not run under Python 3. Please use a version of Python between # # See the docs/about.rst file for licensing information. -import glob, os, stat, subprocess, sys, re +import os, stat, subprocess, re ##### sys.path management @@ -37,7 +37,8 @@ def read_version_py(infname): if mo: return mo.group(1) -version = read_version_py("src/allmydata/_version.py") +VERSION_PY_FILENAME = 'src/allmydata/_version.py' +version = read_version_py(VERSION_PY_FILENAME) APPNAME='allmydata-tahoe' APPNAMEFILE = os.path.join('src', 'allmydata', '_appname.py') @@ -49,7 +50,7 @@ except EnvironmentError: open(APPNAMEFILE, "w").write(APPNAMEFILESTR) else: if curappnamefilestr.strip() != APPNAMEFILESTR: - 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) + 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)) sys.exit(-1) # setuptools/zetuptoolz looks in __main__.__requires__ for a list of @@ -63,6 +64,7 @@ else: adglobals = {} execfile('src/allmydata/_auto_deps.py', adglobals) install_requires = adglobals['install_requires'] +setup_requires = adglobals['setup_requires'] if len(sys.argv) > 1 and sys.argv[1] == '--fakedependency': del sys.argv[1] @@ -70,9 +72,7 @@ if len(sys.argv) > 1 and sys.argv[1] == '--fakedependency': __requires__ = install_requires[:] -egg = os.path.realpath(glob.glob('setuptools-*.egg')[0]) -sys.path.insert(0, egg) -egg = os.path.realpath(glob.glob('darcsver-*.egg')[0]) +egg = os.path.realpath('setuptools-0.6c16dev6.egg') sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg @@ -92,7 +92,6 @@ trove_classifiers=[ "Intended Audience :: System Administrators", "Operating System :: Microsoft", "Operating System :: Microsoft :: Windows", - "Operating System :: Microsoft :: Windows :: Windows NT/2000", "Operating System :: Unix", "Operating System :: POSIX :: Linux", "Operating System :: POSIX", @@ -102,64 +101,18 @@ trove_classifiers=[ "Programming Language :: C", "Programming Language :: Python", "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.4", - "Programming Language :: Python :: 2.5", - "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Topic :: Utilities", "Topic :: System :: Systems Administration", "Topic :: System :: Filesystems", "Topic :: System :: Distributed Computing", "Topic :: Software Development :: Libraries", - "Topic :: Communications :: Usenet News", "Topic :: System :: Archiving :: Backup", "Topic :: System :: Archiving :: Mirroring", "Topic :: System :: Archiving", ] -setup_requires = [] - -# 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). darcsver will also write a new version -# stamp in src/allmydata/_version.py, with a version number derived from -# darcs history. Note that the setup.cfg file has an "[aliases]" section -# which enumerates commands that you might run and specifies that it will run -# darcsver before each one. If you add different commands (or if I forgot -# some that are already in use), you may need to add it to setup.cfg and -# configure it to run darcsver before your command, if you want the version -# number to be correct when that command runs. -# http://pypi.python.org/pypi/darcsver -setup_requires.append('darcsver >= 1.7.2') - -# Nevow imports itself when building, which causes Twisted and zope.interface -# to be imported. We need to make sure that the versions of Twisted and -# zope.interface used at build time satisfy Nevow's requirements. If not -# then there are two problems: -# - prior to Nevow v0.9.33, Nevow didn't declare its dependency on Twisted -# in a way that enabled setuptools to satisfy that requirement at -# build time. -# - some versions of zope.interface, e.g. v3.6.4, are incompatible with -# Nevow, and we need to avoid those both at build and run-time. -# -# This only matters when compatible versions of Twisted and zope.interface -# are not already installed. Retire this hack when -# https://bugs.launchpad.net/nevow/+bug/812537 has been fixed. -setup_requires += [req for req in install_requires if req.startswith('Twisted') or req.startswith('zope.interface')] - -# trialcoverage is required if you want the "trial" unit test runner to have a -# "--reporter=bwverbose-coverage" option which produces code-coverage results. -# The required version is 0.3.3, because that is the latest version that only -# depends on a version of pycoverage for which binary packages are available. -if "--reporter=bwverbose-coverage" in sys.argv: - setup_requires.append('trialcoverage >= 0.3.3') - -# stdeb is required to produce Debian files with the "sdist_dsc" command. -if "sdist_dsc" in sys.argv: - setup_requires.append('stdeb >= 0.3') - # We no longer have any requirements specific to tests. tests_require=[] @@ -173,6 +126,7 @@ class Trial(Command): ("reporter=", None, "The reporter to use for this test run."), ("suite=", "s", "Specify the test suite."), ("quiet", None, "Don't display version numbers and paths of Tahoe dependencies."), + ("coverage", "c", "Collect branch coverage information."), ] def initialize_options(self): @@ -182,12 +136,35 @@ class Trial(Command): self.reporter = None self.suite = "allmydata" self.quiet = False + self.coverage = False def finalize_options(self): pass def run(self): args = [sys.executable, os.path.join('bin', 'tahoe')] + + if self.coverage: + from errno import ENOENT + coverage_cmd = 'coverage' + try: + subprocess.call([coverage_cmd, 'help']) + except OSError as e: + if e.errno != ENOENT: + raise + coverage_cmd = 'python-coverage' + try: + rc = subprocess.call([coverage_cmd, 'help']) + except OSError as e: + if e.errno != ENOENT: + raise + print >>sys.stderr + print >>sys.stderr, "Couldn't find the command 'coverage' nor 'python-coverage'." + print >>sys.stderr, "coverage can be installed using 'pip install coverage', or on Debian-based systems, 'apt-get install python-coverage'." + sys.exit(1) + + args += ['@' + coverage_cmd, 'run', '--branch', '--source=src/allmydata', '@tahoe'] + if not self.quiet: args.append('--version-and-path') args += ['debug', 'trial'] @@ -256,44 +233,34 @@ class MakeExecutable(Command): raise -DARCS_VERSION_BODY = ''' -# This _version.py is generated from darcs metadata by the tahoe setup.py -# and the "darcsver" package. - -__pkgname__ = "%(pkgname)s" -verstr = "%(pkgversion)s" -__version__ = verstr -''' - GIT_VERSION_BODY = ''' # This _version.py is generated from git metadata by the tahoe setup.py. -__pkgname__ = "%(pkgname)s" -real_version = "%(version)s" -full_version = "%(full)s" -verstr = "%(normalized)s" +__pkgname__ = %(pkgname)r +real_version = %(version)r +full_version = %(full)r +branch = %(branch)r +verstr = %(normalized)r __version__ = verstr ''' -def run_command(args, cwd=None, verbose=False): +def run_command(args, cwd=None): + use_shell = sys.platform == "win32" try: - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd) - except EnvironmentError, e: - if verbose: - print "unable to run %s" % args[0] - print e + p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd, shell=use_shell) + except EnvironmentError as e: # if this gives a SyntaxError, note that Tahoe-LAFS requires Python 2.7+ + print("Warning: unable to run %r." % (" ".join(args),)) + print(e) return None stdout = p.communicate()[0].strip() if p.returncode != 0: - if verbose: - print "unable to run %s (error)" % args[0] + print("Warning: %r returned error code %r." % (" ".join(args), p.returncode)) return None return stdout -def versions_from_git(tag_prefix, verbose=False): - # this runs 'git' from the directory that contains this file. That either +def versions_from_git(tag_prefix): + # This runs 'git' from the directory that contains this file. That either # 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 @@ -314,19 +281,18 @@ def versions_from_git(tag_prefix, verbose=False): try: source_dir = os.path.dirname(os.path.abspath(__file__)) - except NameError: + except NameError as e: # some py2exe/bbfreeze/non-CPython implementations don't do __file__ - return {} # not always correct - GIT = "git" - if sys.platform == "win32": - GIT = "git.cmd" - stdout = run_command([GIT, "describe", "--tags", "--dirty", "--always"], + print("Warning: unable to find version because we could not obtain the source directory.") + print(e) + return {} + stdout = run_command(["git", "describe", "--tags", "--dirty", "--always"], cwd=source_dir) if stdout is None: + # run_command already complained. return {} if not stdout.startswith(tag_prefix): - if verbose: - print "tag '%s' doesn't start with prefix '%s'" % (stdout, tag_prefix) + print("Warning: tag %r doesn't start with prefix %r." % (stdout, tag_prefix)) return {} version = stdout[len(tag_prefix):] pieces = version.split("-") @@ -334,15 +300,27 @@ def versions_from_git(tag_prefix, verbose=False): normalized_version = pieces[0] else: normalized_version = "%s.post%s" % (pieces[0], pieces[1]) - stdout = run_command([GIT, "rev-parse", "HEAD"], cwd=source_dir) + + stdout = run_command(["git", "rev-parse", "HEAD"], cwd=source_dir) if stdout is None: + # run_command already complained. return {} full = stdout.strip() if version.endswith("-dirty"): full += "-dirty" normalized_version += ".dev0" - return {"version": version, "normalized": normalized_version, "full": full} + # Thanks to Jistanidiot at . + stdout = run_command(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=source_dir) + branch = (stdout or "unknown").strip() + + return {"version": version, "normalized": normalized_version, "full": full, "branch": branch} + +# 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. class UpdateVersion(Command): description = "update _version.py from revision-control metadata" @@ -353,38 +331,35 @@ class UpdateVersion(Command): def finalize_options(self): pass def run(self): - target = self.distribution.versionfiles[0] - if os.path.isdir(os.path.join(basedir, "_darcs")): - verstr = self.try_from_darcs(target) - elif os.path.isdir(os.path.join(basedir, ".git")): - verstr = self.try_from_git(target) - else: - print "no version-control data found, leaving _version.py alone" - return + global version + verstr = version + if os.path.isdir(os.path.join(basedir, ".git")): + verstr = self.try_from_git() + if verstr: self.distribution.metadata.version = verstr - - def try_from_darcs(self, target): - from darcsver.darcsvermodule import update - (rc, verstr) = update(pkgname=self.distribution.get_name(), - verfilename=self.distribution.versionfiles, - revision_number=True, - version_body=DARCS_VERSION_BODY) - if rc == 0: - return verstr - - def try_from_git(self, target): - versions = versions_from_git("allmydata-tahoe-", verbose=True) + else: + print("""\ +******************************************************************** +Warning: no version information found. This may cause tests to fail. +******************************************************************** +""") + + def try_from_git(self): + # If we change APPNAME, the release tag names should also change from then on. + versions = versions_from_git(APPNAME + '-') if versions: - for fn in self.distribution.versionfiles: - f = open(fn, "wb") - f.write(GIT_VERSION_BODY % - { "pkgname": self.distribution.get_name(), - "version": versions["version"], - "normalized": versions["normalized"], - "full": versions["full"] }) - f.close() - print "git-version: wrote '%s' into '%s'" % (versions["version"], fn) + f = open(VERSION_PY_FILENAME, "wb") + f.write(GIT_VERSION_BODY % + { "pkgname": self.distribution.get_name(), + "version": versions["version"], + "normalized": versions["normalized"], + "full": versions["full"], + "branch": versions["branch"], + }) + f.close() + print("Wrote normalized version %r into '%s'" % (versions["normalized"], VERSION_PY_FILENAME)) + return versions.get("normalized", None) @@ -443,12 +418,12 @@ if version: setup_args["version"] = version setup(name=APPNAME, - description='secure, decentralized, fault-tolerant filesystem', - long_description=open('README.txt', 'rU').read(), + description='secure, decentralized, fault-tolerant file store', + long_description=open('README.rst', 'rU').read(), author='the Tahoe-LAFS project', author_email='tahoe-dev@tahoe-lafs.org', url='https://tahoe-lafs.org/', - license='GNU GPL', # see README.txt -- there is an alternative licence + license='GNU GPL', # see README.rst -- there is an alternative licence cmdclass={"trial": Trial, "make_executable": MakeExecutable, "update_version": UpdateVersion, @@ -466,19 +441,20 @@ setup(name=APPNAME, 'allmydata.test', 'allmydata.util', 'allmydata.web', - 'allmydata.web.static', 'allmydata.windows', 'buildtest'], classifiers=trove_classifiers, test_suite="allmydata.test", install_requires=install_requires, tests_require=tests_require, - package_data={"allmydata.web": ["*.xhtml"], - "allmydata.web.static": ["*.js", "*.png", "*.css"], + package_data={"allmydata.web": ["*.xhtml", + "static/*.js", "static/*.png", "static/*.css", + "static/img/*.png", + "static/css/*.css", + ] }, setup_requires=setup_requires, entry_points = { 'console_scripts': [ 'tahoe = allmydata.scripts.runner:run' ] }, zip_safe=False, # We prefer unzipped for easier access. - versionfiles=['src/allmydata/_version.py',], **setup_args )