# .. Copyright (C) 2012-2016 Bryan A. Jones.
#
# This file is part of CodeChat.
#
# CodeChat is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CodeChat is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CodeChat. If not, see .
#
# ***************************************
# setup.py - Package and install CodeChat
# ***************************************
# Builds and installs CodeChat.
#
# Packaging notes
# ===============
# Packaging on Python is a mess, IMHO. It takes an easy job and makes it hard.
#
# A quick summary: distutils_ can't
# install dependencies from PyPI_, so use setuptools_. A source distribution is
# a good idea becaues it can run on a bare Python installation with no other
# installs required, but there's no standard format (.zip?, .tar.gz?, etc.). An
# .egg is nice, but requires setuptools/pip/ez_setup installed. The .whl
# (`Python wheel `_)
# is the latest and greatest format that superceeds eggs, but with similar
# problems (requires wheel to be installed).
#
# Reading to get up to speed:
#
# * `Python Packaging User Guide `_ -
# the most up-to-date reference I've found so far. Tells which tools to
# actually use.
#
# * `distutils `_ - The built-in
# installer. Tells what to do, but not what actually happens. It doesn't have
# the ability to install dependencies from `PyPI `_,
# which I need.
#
# * `setuptools `_ - A distutils
# replacement which can install dependencies, so I use it.
#
# .. _to-package:
#
# To package
# ==========
# Create a source distribution, a built distribution, then upload both to
# `CodeChat at PyPI `_:
#
# ``python setup.py sdist bdist_wheel upload``
#
# To `upload docs
# `_,
# which are placed `here `__
# (make sure to run Sphinx first, so the docs will be current):
#
# ``python setup.py upload_docs --upload-dir=_build\html``
#
# For `development
# `_:
#
# ``python setup.py develop``
#
# Yajo helped `package this for Linux
# `_.
# Thanks so much. See also :doc:`Linux_packaging/python-codechat.spec`.
# Unfortunately, the Linux packaging is untested.
#
# Packaging script
# ================
# Otherwise known as the evils of ``setup.py``.
#
# For users who install this from source but don't have setuptools installed,
# `auto-install it
# `__.
# When packaging for Linux, downloads are blocked so we must specify a very old
# already-installed `version `_.
# Leave this as a `patch
# `_
# so that we normally use a more modern version.
import ez_setup
ez_setup.use_setuptools()
#
# PyPA copied code
# ----------------
# From `PyPA's sample setup.py
# `__,
# read ``long_description`` from a file. This code was last updated on
# 26-May-2015 based on `this commit
# `_.
#
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path
# Imports for `version parse code`_.
import sys
import os
import re
import io
here = path.abspath(path.dirname(__file__))
# Get the long description from the relevant file.
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = f.read()
# The inclusion of a raw tag causes PyPI_ to not render the reST. Ouch.
# Remove it before uploading.
long_description = re.sub('\.\. raw.*<\/iframe>', '', long_description, flags=re.DOTALL)
# This code was copied from `version parse code`_. See ``version`` in the call
# to ``setup`` below.
def read(*names, **kwargs):
with io.open(
os.path.join(os.path.dirname(__file__), *names),
encoding=kwargs.get("encoding", "utf8")
) as fp:
return fp.read()
def find_version(*file_paths):
version_file = read(*file_paths)
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
# My code
# -------
# We support Python 3.3 and higher.
assert sys.version_info >= (3, 3)
setup(
# This must comply with `PEP 0426
# `_'s
# name requirements.
name='CodeChat',
# Projects should comply with the `version scheme
# `_
# specified in PEP440. I use this so that my Sphinx docs will have the same
# version number. There are a lot of alternatives in `Single-sourcing the
# Project Version
# `_.
# While I like something simple, such as ``import CodeChat`` then
# ``version=CodeChat.__version__`` here, this means any dependeninces of
# :doc:`__init__.py ` will be requred to run setup,
# a bad thing. So, instead I read the file in ``setup.py`` and parse the
# version with a regex (see `version parse code
# `_).
version=find_version("CodeChat", "__init__.py"),
description="The CodeChat system for software documentation",
long_description=long_description,
# The project's main homepage.
url='https://pythonhosted.org/CodeChat/README.html',
# Obscure my e-mail address to help defeat spam-bots.
author="Bryan A. Jones",
author_email="bjones AT ece.msstate.edu",
license='GPLv3+',
# These are taken from the `full list
# `_.
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'Operating System :: OS Independent',
'Natural Language :: English',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Topic :: Software Development :: Documentation',
'Topic :: Text Processing :: Markup',
],
keywords='literate programming',
packages=['CodeChat'],
# List run-time dependencies here. These will be installed by pip when
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
#
install_requires=(
# `Enum `_ was introduced in
# Python 3.4. Use a backport of it if needed.
(['enum34'] if sys.version_info.minor == 3 else [])
# Note: I don't include Sphinx in this list: while :doc:`CodeToRest.py
# ` can be executed from the command line if the
# packages below are installed, :doc:`CodeToRestSphinx.py
# ` can only be executed by Sphinx.
+ ['docutils>=0.12',
'pygments>=2.1']),
# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
# for example:
#
# ``$ pip install -e .[test]``
extras_require={
'test': ['pytest'],
},
# To package data files, I'm using ``include_package_data=True`` then
# putting the files in :doc:`MANIFEST.in `. See `including data
# files `_.
include_package_data=True,
)