From 66702da299622151949dfd17cea834399fca0d4c Mon Sep 17 00:00:00 2001 From: Sam Clements Date: Thu, 6 Mar 2014 13:21:47 +0000 Subject: [PATCH] Inital commit --- README.md | 46 ++++++++++++++++++- cookiecutter.json | 16 +++++++ .../.gitignore | 0 {{cookiecutter.project_name}}/README.rst | 39 ++++++++++++++++ {{cookiecutter.project_name}}/setup.py | 31 +++++++++++++ {{cookiecutter.project_name}}/tox.ini | 6 +++ .../{{cookiecutter.project_name}}/__init__.py | 8 ++++ 7 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 cookiecutter.json rename .gitignore => {{cookiecutter.project_name}}/.gitignore (100%) create mode 100644 {{cookiecutter.project_name}}/README.rst create mode 100644 {{cookiecutter.project_name}}/setup.py create mode 100644 {{cookiecutter.project_name}}/tox.ini create mode 100644 {{cookiecutter.project_name}}/{{cookiecutter.project_name}}/__init__.py diff --git a/README.md b/README.md index 1edccfe..5713612 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,48 @@ cookiecutter-pypackage-minimal ============================== -An opinionated, minimal cookiecutter template for Python packages +An opinionated, minimal cookiecutter template for Python packages, and some guidelines for Python packaging. + +Usage +----- + +:: + + pip install cookiecutter + git clone https://github.com/borntyping/cookiecutter-pypackage-minimal.git + cookiecutter cookiecutter-pypackage-minimal/ + +You should then change the classifiers in `{{ package_name }}/setup.py` - it is assumed that the project will run on the latest versions of Python 2 and 3, so you should remove any classifiers that do not apply. The full list of PyPI classifiers can be found [here](https://pypi.python.org/pypi?:action=list_classifiers). + +Fill out the README, and - if necessary - add a license to the project. + +Explanation +----------- + +The decisions `cookiecutter-pypackage-minimal` makes should all be explained here. + +### README + +* **README should use reStructuredText format** + This is the format used by most Python tools, and is expected by setuptools +* **As few README files as possible** + Additional README files (AUTHORS, CHANGELOG, etc) should be left to the user to create when necessary. + +### `setup.py` + +* **Use setuptools** + It's the standard packaging library for Python. `distribute` has merged back into `setuptools`, and `distutils` is less capable. +* **setup.py should not import anything from the package** + When installing from source, the user may not have the packages dependencies installed, and importing the package is likely to raise an `ImportError`. +* **setup.py should be the canonical source of package dependencies** + There is no reason to duplicate dependency specifiers (e.g. also using `requirements.txt`) + See the testing section below for testing dependencies. + +### Testing + +* **Use [Tox](http://testrun.org/tox/latest/) to manage test environments** + Tox provides isolation, runs tests across multiple Python versions, and ensures the package can be installed. +* **Uses [pytest](http://pytest.org/latest/) as the default test runner** + This can be changed easily, though pytest is a easier, more powerful test library and runner than the standard library's unittest. +* **Define testing dependencies in `tox.ini`** + Avoid duplicating dependency definitions, and use `tox.ini` as the canonical description of how the unittests should be run. diff --git a/cookiecutter.json b/cookiecutter.json new file mode 100644 index 0000000..eef0865 --- /dev/null +++ b/cookiecutter.json @@ -0,0 +1,16 @@ +{ + "author_name": "Sam Clements", + "author_email": "sam@borntyping.co.uk", + + "maintainer_name": null, + "maintainer_email": null, + + "package_name": "cookiecutter-pypackage-minimal", + "package_version": "0.1.0", + "package_description": "An opinionated, minimal cookiecutter template for Python packages", + "package_url": "https://github.com/borntyping/cookiecutter-pypackage-minimal", + + "readme_pypi_badge": true, + "readme_travis_badge": true, + "readme_travis_url": "https://travis-ci.org/borntyping/cookiecutter-pypackage-minimal", +} diff --git a/.gitignore b/{{cookiecutter.project_name}}/.gitignore similarity index 100% rename from .gitignore rename to {{cookiecutter.project_name}}/.gitignore diff --git a/{{cookiecutter.project_name}}/README.rst b/{{cookiecutter.project_name}}/README.rst new file mode 100644 index 0000000..676bbf2 --- /dev/null +++ b/{{cookiecutter.project_name}}/README.rst @@ -0,0 +1,39 @@ +{{ cookiecutter.package_name }} +{{ len(cookiecutter.package_name) * "=" }} + +{% if cookiecutter.readme_pypi_badge -%} +.. image:: https://pypip.in/v/{{ cookiecutter.package_name }}/badge.png + :target: https://pypi.python.org/pypi/{{ cookiecutter.package_name }} + :alt: Latest PyPI version +{%- endif %} + +{% if cookiecutter.readme_travis_badge and cookiecutter.readme_travis_url is not None -%} +.. image:: {{ cookiecutter.readme_travis_url }}.png + :target: {{ cookiecutter.readme_travis_url }} + :alt: Latest Travis CI build status +{%- endif %} + +{{ cookiecutter.package_description }} + +Usage +----- + +Installation +------------ + +Requirements +^^^^^^^^^^^^ + +Compatibility +------------- + +Licence +------- + +Authors +------- + +{{ cookiecutter.package_name }} was written by `{{ cookiecutter.author_name }} <{{ cookiecutter.author_email }}>`_. +{% if cookiecutter.maintainer_name is not None -%} +{{ cookiecutter.package_name }} was written by `{{ cookiecutter.maintainer_name }} <{{ cookiecutter.maintainer_email }}>`_. +{%- endif %} diff --git a/{{cookiecutter.project_name}}/setup.py b/{{cookiecutter.project_name}}/setup.py new file mode 100644 index 0000000..e43c20e --- /dev/null +++ b/{{cookiecutter.project_name}}/setup.py @@ -0,0 +1,31 @@ +import setuptools + +setuptools.setup( + name='{{ cookiecutter.package_name }}', + version='{{ cookiecutter.package_version }}', + url="{{ cookiecutter.package_url }}", + + author="{{ cookiecutter.author_name }}", + author_email="{{ cookiecutter.author_email }}", + + {% if cookiecutter.maintainer_name is not None -%} + maintainer="{{ cookiecutter.maintainer_name }}", + maintainer_email="{{ cookiecutter.maintainer_email }}", + {%- endif %} + + description = "{{ cookiecutter.package_description }}", + long_description = open('README.rst').read(), + + packages = setuptools.find_packages(), + + install_requires=[], + + classifiers = [ + 'Development Status :: 2 - Pre-Alpha', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + ], +) diff --git a/{{cookiecutter.project_name}}/tox.ini b/{{cookiecutter.project_name}}/tox.ini new file mode 100644 index 0000000..b3439b0 --- /dev/null +++ b/{{cookiecutter.project_name}}/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist=py27,py33 + +[testenv] +commands=py.test {{ cookiecutter.package_name }} +deps=pytest diff --git a/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/__init__.py b/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/__init__.py new file mode 100644 index 0000000..7657d2b --- /dev/null +++ b/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}/__init__.py @@ -0,0 +1,8 @@ +"""{{ cookiecutter.package_name }} - {{ cookiecutter.package_description }}""" + +__version__ = '{{ cookiecutter.package_version }}' +__author__ = '{{ cookiecutter.author_name }} <{{ cookiecutter.author_email }}>' +{% if cookiecutter.maintainer_name is not None -%} +__maintainer__ = '{{ cookiecutter.maintainer_name }} <{{ cookiecutter.maintainer_email }}>' +{%- endif %} +__all__ = []