diff options
Diffstat (limited to 'setup.py')
-rwxr-xr-x | setup.py | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..285894d --- /dev/null +++ b/setup.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python +''' +setup.py - this file is part of S3QL (http://s3ql.googlecode.com) + +Copyright (C) 2008-2009 Nikolaus Rath <Nikolaus@rath.org> + +This program can be distributed under the terms of the GNU LGPL. +''' + +from __future__ import division, print_function + +import sys +import os +import subprocess +import logging +from glob import glob + +# Work around setuptools bug +# http://bitbucket.org/tarek/distribute/issue/152/ +#pylint: disable=W0611 +import multiprocessing + +# Add S3QL sources +basedir = os.path.abspath(os.path.dirname(sys.argv[0])) +sys.path.insert(0, os.path.join(basedir, 'src')) +import s3ql + +# Import distribute +sys.path.insert(0, os.path.join(basedir, 'util')) +from distribute_setup import use_setuptools +use_setuptools(version='0.6.14', download_delay=5) +import setuptools +import setuptools.command.test as setuptools_test + +class build_docs(setuptools.Command): + description = 'Build Sphinx documentation' + user_options = [ + ('fresh-env', 'E', 'discard saved environment'), + ('all-files', 'a', 'build all files'), + ] + boolean_options = ['fresh-env', 'all-files'] + + def initialize_options(self): + self.fresh_env = False + self.all_files = False + + def finalize_options(self): + pass + + def run(self): + try: + from sphinx.application import Sphinx + from docutils.utils import SystemMessage + except ImportError: + raise QuietError('This command requires Sphinx to be installed.') + + dest_dir = os.path.join(basedir, 'doc') + src_dir = os.path.join(basedir, 'rst') + + confoverrides = {} + confoverrides['version'] = s3ql.VERSION + confoverrides['release'] = s3ql.VERSION + + for builder in ('html', 'latex', 'man'): + print('Running %s builder...' % builder) + self.mkpath(os.path.join(dest_dir, builder)) + app = Sphinx(srcdir=src_dir, confdir=src_dir, + outdir=os.path.join(dest_dir, builder), + doctreedir=os.path.join(dest_dir, 'doctrees'), + buildername=builder, confoverrides=confoverrides, + freshenv=self.fresh_env) + self.fresh_env = False + self.all_files = False + + try: + if self.all_files: + app.builder.build_all() + else: + app.builder.build_update() + except SystemMessage as err: + print('reST markup error:', + err.args[0].encode('ascii', 'backslashreplace'), + file=sys.stderr) + + # These shouldn't be installed by default + for name in ('expire_backups.1', 'pcp.1'): + os.rename(os.path.join(dest_dir, 'man', name), + os.path.join(basedir, 'contrib', name)) + + print('Running pdflatex...') + for _ in range(3): + subprocess.check_call(['pdflatex', '-interaction', + 'batchmode', 'manual.tex'], + cwd=os.path.join(dest_dir, 'latex'), + stdout=open('/dev/null', 'wb')) + os.rename(os.path.join(dest_dir, 'latex', 'manual.pdf'), + os.path.join(dest_dir, 'manual.pdf')) + + +def main(): + + with open(os.path.join(basedir, 'rst', 'about.rst'), 'r') as fh: + long_desc = fh.read() + + setuptools.setup( + name='s3ql', + zip_safe=True, + version=s3ql.VERSION, + description='a full-featured file system for online data storage', + long_description=long_desc, + author='Nikolaus Rath', + author_email='Nikolaus@rath.org', + url='http://code.google.com/p/s3ql/', + download_url='http://code.google.com/p/s3ql/downloads/list', + license='LGPL', + classifiers=['Development Status :: 4 - Beta', + 'Environment :: No Input/Output (Daemon)', + 'Environment :: Console', + 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', + 'Topic :: Internet', + 'Operating System :: POSIX', + 'Topic :: System :: Archiving'], + platforms=[ 'POSIX', 'UNIX', 'Linux' ], + keywords=['FUSE', 'backup', 'archival', 'compression', 'encryption', + 'deduplication', 'aws', 's3' ], + package_dir={'': 'src'}, + packages=setuptools.find_packages('src'), + provides=['s3ql'], + data_files = [ ('share/man/man1', + [ os.path.join('doc/man/', x) for x + in glob(os.path.join(basedir, 'doc', 'man', '*.1')) ]) ], + entry_points={ 'console_scripts': + [ + 'mkfs.s3ql = s3ql.cli.mkfs:main', + 'fsck.s3ql = s3ql.cli.fsck:main', + 'mount.s3ql = s3ql.cli.mount:main', + 'umount.s3ql = s3ql.cli.umount:main', + 's3qlcp = s3ql.cli.cp:main', + 's3qlstat = s3ql.cli.statfs:main', + 's3qladm = s3ql.cli.adm:main', + 's3qlctrl = s3ql.cli.ctrl:main', + 's3qllock = s3ql.cli.lock:main', + 's3qlrm = s3ql.cli.remove:main', + ] + }, + install_requires=['apsw >= 3.7.0', + 'pycryptopp', + 'llfuse >= 0.31', + 'argparse >= 1.1', + 'pyliblzma >= 0.5.3' ], + tests_require=['apsw >= 3.7.0', 'unittest2', + 'pycryptopp', + 'llfuse >= 0.29', + 'argparse >= 1.1', + 'pyliblzma >= 0.5.3' ], + test_suite='tests', + cmdclass={'test': test, + 'upload_docs': upload_docs, + 'build_sphinx': build_docs }, + command_options = { 'sdist': { 'formats': ('setup.py', 'bztar') } }, + ) + + +class test(setuptools_test.test): + # Attributes defined outside init, required by setuptools. + # pylint: disable=W0201 + description = "Run self-tests" + user_options = (setuptools_test.test.user_options + + [('debug=', None, 'Activate debugging for specified modules ' + '(separated by commas, specify "all" for all modules)'), + ('awskey=', None, 'Specify AWS access key to use, secret key will be asked for. ' + 'If this option is not specified, tests requiring access ' + 'to Amazon Web Services will be skipped.')]) + + + def initialize_options(self): + setuptools_test.test.initialize_options(self) + self.debug = None + self.awskey = None + + def finalize_options(self): + setuptools_test.test.finalize_options(self) + self.test_loader = "ScanningLoader" + if self.debug: + self.debug = [ x.strip() for x in self.debug.split(',') ] + + + def run_tests(self): + + # Add test modules + sys.path.insert(0, os.path.join(basedir, 'tests')) + import unittest2 as unittest + import _common + from s3ql.common import (setup_excepthook, add_file_logging, add_stdout_logging, + LoggerFilter) + from getpass import getpass + + # Initialize logging if not yet initialized + root_logger = logging.getLogger() + if not root_logger.handlers: + add_stdout_logging(quiet=True) + add_file_logging(os.path.join(basedir, 'setup.log')) + setup_excepthook() + if self.debug: + root_logger.setLevel(logging.DEBUG) + if 'all' not in self.debug: + root_logger.addFilter(LoggerFilter(self.debug, logging.INFO)) + else: + root_logger.setLevel(logging.INFO) + else: + root_logger.debug("Logging already initialized.") + + # Init AWS + if self.awskey: + if sys.stdin.isatty(): + pw = getpass("Enter AWS password: ") + else: + pw = sys.stdin.readline().rstrip() + _common.aws_credentials = (self.awskey, pw) + + # Define our own test loader to order modules alphabetically + from pkg_resources import resource_listdir, resource_exists + class ScanningLoader(unittest.TestLoader): + # Yes, this is a nasty hack + # pylint: disable=W0232,W0221,W0622 + def loadTestsFromModule(self, module): + """Return a suite of all tests cases contained in the given module""" + tests = [] + if module.__name__!='setuptools.tests.doctest': # ugh + tests.append(unittest.TestLoader.loadTestsFromModule(self,module)) + if hasattr(module, "additional_tests"): + tests.append(module.additional_tests()) + if hasattr(module, '__path__'): + for file in sorted(resource_listdir(module.__name__, '')): + if file.endswith('.py') and file!='__init__.py': + submodule = module.__name__+'.'+file[:-3] + else: + if resource_exists( + module.__name__, file+'/__init__.py' + ): + submodule = module.__name__+'.'+file + else: + continue + tests.append(self.loadTestsFromName(submodule)) + if len(tests)!=1: + return self.suiteClass(tests) + else: + return tests[0] # don't create a nested suite for only one return + + unittest.main( + None, None, [unittest.__file__]+self.test_args, + testLoader = ScanningLoader()) + + +class upload_docs(setuptools.Command): + user_options = [] + boolean_options = [] + description = "Upload documentation" + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + subprocess.check_call(['rsync', '-aHv', '--del', os.path.join(basedir, 'doc', 'html') + '/', + 'ebox.rath.org:/var/www/s3ql-docs/']) + subprocess.check_call(['rsync', '-aHv', '--del', os.path.join(basedir, 'doc', 'manual.pdf'), + 'ebox.rath.org:/var/www/s3ql-docs/']) + +if __name__ == '__main__': + main() |