diff --git a/.gitignore b/.gitignore index 5f1d4d5..9ae827f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # tools, IDEs, build folders /.coverage/ +/.eggs/ /.idea/ +/.tox/ /build/ /dist/ /docs/build/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..0e6a36b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: python +install: + - pip install virtualenv +script: + - python setup.py test diff --git a/README.rst b/README.rst index 4da4741..04a6f49 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,11 @@ -=========== -django todo -=========== +============================ +django todo |latest-version| +============================ + +|build-status| |health| |downloads| |license| django-todo is a pluggable multi-user, multi-group task management and -assignment application for Django. It can serve as anything from a personal +assignment application for Django. It can serve as anything from a personal to-do system to a complete, working ticketing system for organizations. Documentation @@ -19,3 +21,36 @@ For documentation, see the django-todo wiki pages: - `Version history `_ + +Tests +===== + +Serious tests are missing, but we're checking PEP8 conformity of our syntax on +both Python 2 and 3 using ``tox``. You can run the tests locally via:: + + $ python setup.py test + +No prerequisites are required, all test dependencies will be installed +automatically by ``tox`` in virtual environments created on the fly. +Unfortunately, you'll have to install ``virtualenv`` for this to work, though. + +To remove all build files and folders including Python byte code you can run:: + + $ python setup.py clean + + +.. |latest-version| image:: https://img.shields.io/pypi/v/django-todo.svg + :alt: Latest version on PyPI + :target: https://pypi.python.org/pypi/django-todo +.. |build-status| image:: https://travis-ci.org/shacker/django-todo.svg + :alt: Build status + :target: https://travis-ci.org/shacker/django-todo +.. |health| image:: https://landscape.io/github/shacker/django-todo/master/landscape.svg?style=flat + :target: https://landscape.io/github/shacker/django-todo/master + :alt: Code health +.. |downloads| image:: https://img.shields.io/pypi/dm/django-todo.svg + :alt: Monthly downloads from PyPI + :target: https://pypi.python.org/pypi/django-todo +.. |license| image:: https://img.shields.io/pypi/l/django-todo.svg + :alt: Software license + :target: https://github.com/shacker/django-todo/blob/master/LICENSE diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 789b9c3..0000000 --- a/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -max-line-length = 120 -max-complexity = 10 -exclude = build,dist,docs/conf.py,todo/migrations,*.egg-info diff --git a/setup.py b/setup.py index dcdd7bd..58e305c 100755 --- a/setup.py +++ b/setup.py @@ -1,26 +1,105 @@ #!/usr/bin/env python +from glob import glob +from os import remove +from os.path import abspath, dirname, join from setuptools import setup, find_packages -import todo +from setuptools.command.test import test as TestCommand +from shlex import split +from shutil import rmtree +from sys import exit + +import todo as package + + +class Tox(TestCommand): + user_options = [('tox-args=', 'a', "Arguments to pass to tox")] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.tox_args = None + + def finalize_options(self): + TestCommand.finalize_options(self) + self.test_args = [] + self.test_suite = True + + def run_tests(self): + import tox + args = self.tox_args + if args: + args = split(self.tox_args) + errno = tox.cmdline(args=args) + exit(errno) + + +class Clean(TestCommand): + def run(self): + delete_in_root = [ + 'build', + 'dist', + '.eggs', + '*.egg-info', + '.tox', + ] + delete_everywhere = [ + '__pycache__', + '*.pyc', + ] + for candidate in delete_in_root: + rmtree_glob(candidate) + for visible_dir in glob('[A-Za-z0-9]*'): + for candidate in delete_everywhere: + rmtree_glob(join(visible_dir, candidate)) + rmtree_glob(join(visible_dir, '*', candidate)) + rmtree_glob(join(visible_dir, '*', '*', candidate)) + + +def rmtree_glob(file_glob): + for fobj in glob(file_glob): + try: + rmtree(fobj) + print('%s/ removed ...' % fobj) + except OSError: + try: + remove(fobj) + print('%s removed ...' % fobj) + except OSError: + pass + + +def read_file(*pathname): + with open(join(dirname(abspath(__file__)), *pathname)) as f: + return f.read() setup( name='django-todo', - version=todo.__version__, - description='A multi-user, multi-group task management and assignment system for Django.', - author=todo.__author__, - author_email=todo.__email__, - url=todo.__url__, - license=todo.__license__, + version=package.__version__, + description=package.__doc__.strip(), + long_description=read_file('README.rst'), + author=package.__author__, + author_email=package.__email__, + url=package.__url__, + license=package.__license__, packages=find_packages(), classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Web Environment', + 'Framework :: Django', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', - 'Framework :: Django', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Topic :: Office/Business :: Groupware', + 'Topic :: Software Development :: Bug Tracking', ], include_package_data=True, zip_safe=False, + tests_require=['tox'], + cmdclass={ + 'clean': Clean, + 'test': Tox, + }, ) diff --git a/todo/__init__.py b/todo/__init__.py index abfd735..e579e68 100644 --- a/todo/__init__.py +++ b/todo/__init__.py @@ -1,5 +1,7 @@ -"""django todo""" -__version__ = '1.5' +""" +A multi-user, multi-group task management and assignment system for Django. +""" +__version__ = '1.6.dev1' __author__ = 'Scot Hacker' __email__ = 'shacker@birdhouse.org' diff --git a/todo/settings.py b/todo/settings.py index 3c9099e..e9231b5 100644 --- a/todo/settings.py +++ b/todo/settings.py @@ -1,5 +1,4 @@ from django.conf import settings -from django.contrib.auth.models import User STAFF_ONLY = getattr(settings, 'TODO_STAFF_ONLY', False) diff --git a/todo/views.py b/todo/views.py index 4624735..27f83a3 100644 --- a/todo/views.py +++ b/todo/views.py @@ -389,7 +389,7 @@ def search(request): query_string = None found_items = None - return render(request, - 'todo/search_results.html', - {'query_string': query_string, 'found_items': found_items}, - context_instance=RequestContext(request)) + return render(request, 'todo/search_results.html', { + 'query_string': query_string, + 'found_items': found_items + }, context_instance=RequestContext(request)) diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..a0d1671 --- /dev/null +++ b/tox.ini @@ -0,0 +1,24 @@ +[tox] +envlist = + flake8py{2,3} + +[testenv] +# deps = pytest +commands = + # py.test + +[testenv:flake8py2] +basepython = python2.7 +deps = flake8 +commands = flake8 . + +[testenv:flake8py3] +basepython = python3.4 +deps = flake8 +commands = flake8 . + +[flake8] +# TODO: reduce max-complexity, ideally to 10 +max-line-length = 120 +max-complexity = 21 +exclude = build,dist,docs/conf.py,*/migrations,*.egg-info