Skip to content

Commit

Permalink
Rearrange packaging to install memex
Browse files Browse the repository at this point in the history
This commit rearranges the packaging metadata to install the `memex`
package, rather than `h`.

The logic behind this is that `memex` will be versioned, documented, and
released to PyPI as a library, while the rest of the source code will
*not* be an installable package and will be deployed continuously as a
Docker image (or otherwise).

A couple of the changes here merit further explanation:

- The requirements for h and memex have been split up: memex
  requirements remain in `setup.py`, while the h application
  requirements are defined in `requirements.in` and frozen into the
  `requirements.txt` file using [pip-compile][1].

  For more about the motivation for this pattern, see [this blog post by
  the author of pip-tools][2].

- Previously, h version numbers have been dynamically generated from git
  metadata. In this commit I've pinned the version of the memex package
  explicitly in `src/memex/__init__.py`. This is a less flexible but
  simpler way of versioning memex, and we can build tools to assist with
  version bumping/releasing to PyPI if appropriate.

[1]: https://github.com/nvie/pip-tools
[2]: http://nvie.com/posts/better-package-management/
  • Loading branch information
nickstenning committed Aug 9, 2016
1 parent 9f22181 commit e5caa07
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 129 deletions.
5 changes: 0 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ matrix:
postgresql: "9.4"
before_script: createdb htest

# Check Python package manifest
- env: ACTION=tox TOXENV=manifest
language: python
python: '2.7'

# Test web application frontend
- env: ACTION=gulp GULPTASK=test
language: node_js
Expand Down
21 changes: 2 additions & 19 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
include Makefile AUTHORS CHANGES CODE_OF_CONDUCT LICENSE NOTICE
include AUTHORS CHANGES CODE_OF_CONDUCT LICENSE NOTICE
include *.rst
include Dockerfile
include gulpfile.js
include gunicorn.conf.py
include package.json
include requirements.txt
exclude Jenkinsfile
graft conf
graft docs
prune docs/_build
include h/accounts/blacklist
include h/assets.ini
include h/assets_client.ini
graft h/migrations
graft h/static
graft h/templates
graft scripts
prune tests
graft vendor
graft src
global-exclude __pycache__
global-exclude *.py[co]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ test: node_modules/.uptodate
# Fake targets to aid with deps installation
h.egg-info/.uptodate: setup.py requirements.txt
@echo installing python dependencies
@pip install --use-wheel -e .[dev] tox
@pip install --use-wheel -r requirements-dev.in tox
@touch $@

node_modules/.uptodate: package.json
Expand Down
7 changes: 7 additions & 0 deletions requirements-dev.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-r requirements.txt

honcho
pep257
prospector[with_pyroma]
pyramid_debugtoolbar
sphinxcontrib-httpdomain
41 changes: 41 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
PyJWT
SQLAlchemy
alembic
celery
certifi
cffi
click
cryptacular
cryptography
deform < 1.0
deform-jinja2
elasticsearch < 2.0.0
gevent
gunicorn
itsdangerous
jsonpointer == 1.0
jsonschema
kombu
psycogreen
psycopg2
pyramid < 1.7
pyramid-jinja2
pyramid-multiauth
pyramid-services
pyramid_mailer
pyramid_redis_sessions
pyramid_tm
python-dateutil
python-slugify < 1.2.0
raven
statsd
unicodecsv
wsaccel
ws4py
zope.sqlalchemy

# Version pin for known bug
# https://github.com/repoze/repoze.sendmail/issues/31
repoze.sendmail < 4.2

-e . # memex
87 changes: 83 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,84 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile --output-file requirements.txt requirements.in
#

-e .
certifi
cffi
requests[security]
wsaccel
alembic==0.8.7
amqp==1.4.9 # via kombu
anyjson==0.3.3 # via kombu
billiard==3.3.0.23 # via celery
blinker==1.3
celery==3.1.23
certifi==2016.2.28
cffi==1.7.0
Chameleon==2.24 # via deform
click==6.6
colander==1.3.1 # via deform
contextlib2==0.5.3 # via raven
cryptacular==1.4.1
cryptography==1.4
deform-jinja2==0.5
deform==0.9.9
elasticsearch==1.9.0
enum34==1.1.6 # via cryptography
functools32==3.2.3.post2 # via jsonschema
gevent==1.1.2
greenlet==0.4.10 # via gevent
gunicorn==19.6.0
idna==2.1 # via cryptography
ipaddress==1.0.16 # via cryptography
iso8601==0.1.11 # via colander
itsdangerous==0.24
Jinja2==2.8 # via deform-jinja2, pyramid-jinja2
jsonpointer==1.0
jsonschema==2.5.1
kombu==3.0.35
Mako==1.0.4 # via alembic
MarkupSafe==0.23 # via jinja2, mako, pyramid-jinja2
PasteDeploy==1.5.2 # via pyramid
pbkdf2==1.3 # via cryptacular
peppercorn==0.5 # via deform
psycogreen==1.0
psycopg2==2.6.2
pyasn1==0.1.9 # via cryptography
pycparser==2.14 # via cffi
PyJWT==1.4.1
pyparsing==2.1.5
pyramid-jinja2==2.6.2
pyramid-mailer==0.14.1
pyramid-multiauth==0.8.0
pyramid-redis-sessions==1.0.1
pyramid-services==0.4
pyramid-tm==0.12.1
pyramid==1.6.1
python-dateutil==2.5.3
python-editor==1.0.1 # via alembic
python-slugify==1.1.4
pytz==2016.6.1 # via celery
raven==5.10.2
redis==2.10.5 # via pyramid-redis-sessions
repoze.lru==0.6 # via pyramid
repoze.sendmail==4.1
requests==2.10.0
six==1.10.0 # via cryptography, python-dateutil
SQLAlchemy==1.0.14 # via alembic, zope.sqlalchemy
statsd==3.2.1
transaction==1.6.1 # via pyramid-tm, repoze.sendmail, zope.sqlalchemy
translationstring==1.3 # via colander, deform, pyramid
unicodecsv==0.14.1
Unidecode==0.4.19 # via python-slugify
urllib3==1.16 # via elasticsearch
venusian==1.0 # via pyramid
WebOb==1.6.1 # via pyramid
ws4py==0.3.5
wsaccel==0.6.2
zope.deprecation==4.1.2 # via deform, pyramid, pyramid-jinja2
zope.interface==4.2.0 # via pyramid, pyramid-services, repoze.sendmail, transaction, zope.sqlalchemy
zope.sqlalchemy==0.7.7

# The following packages are commented out because they are
# considered to be unsafe in a requirements file:
# setuptools # via cryptacular, cryptography, pyramid, repoze.sendmail, zope.deprecation, zope.interface, zope.sqlalchemy
10 changes: 0 additions & 10 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
[check-manifest]
ignore =
*/test
*/test/*
.*
h/browser
h/browser/*
node_modules
tox.ini

[flake8]
exclude = h/migrations/versions/*
max-line-length = 160
Expand Down
110 changes: 25 additions & 85 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

from __future__ import print_function

import os
import re
from codecs import open
from contextlib import contextmanager
from setuptools import find_packages
from setuptools import setup
from setuptools.command.sdist import sdist as _sdist
from setuptools.command.test import test as _test

###############################################################################

NAME = 'h'
DESC = 'Annotate with anyone, anywhere'
NAME = 'memex'
DESC = 'Memex: annotation storage and retrieval'
AUTHOR = 'Hypothes.is Project & contributors'
AUTHOR_EMAIL = '[email protected]'
URL = 'https://docs.hypothes.is'
URL = 'https://h.readthedocs.io'
LICENSE = 'Simplified (2-Clause) BSD License'
KEYWORDS = ['annotation', 'storage', 'hosting']
CLASSIFIERS = [
Expand All @@ -29,96 +29,36 @@
'Programming Language :: Python :: 2.7',
]
INSTALL_REQUIRES = [
'PyJWT>=1.0.0,<2.0.0',
'SQLAlchemy>=1.0.13',
'alembic>=0.7.0',
'blinker>=1.3,<1.4',
'celery>=3.1.23,<3.2',
'click>=6.6,<7.0',
'cryptacular>=1.4,<1.5',
'cryptography>=0.7',
'deform>=0.9,<1.0',
'deform-jinja2>=0.5,<0.6',
'elasticsearch>=1.1.0,<2.0.0',
'gevent>=1.1,<1.2',
'gunicorn>=19.2,<20',
'itsdangerous>=0.24',
'jsonpointer==1.0',
'jsonschema>=2.5.1,<2.6',
'kombu>=3.0.35,<3.1',
'pyramid>=1.6,<1.7',
'psycogreen>=1.0',
'psycopg2>=2.6.1',
'pyramid-multiauth>=0.8.0,<0.9.0',
'psycopg2>=2.6.1,<2.7',
'pyparsing>=2.1.5,<2.2',
'pyramid-services==0.4',
'pyramid_mailer>=0.13',
'pyramid-redis-sessions>=1.0.1,<1.2.0',
'pyramid_tm>=0.7',
'pyramid>=1.6,<1.7',
'python-dateutil>=2.1',
'python-slugify>=1.1.3,<1.2.0',
'pyramid-jinja2>=2.3.3',
'pyparsing>=2.1.5',
'raven>=5.10.2,<5.11.0',
'requests>=2.7.0',
'statsd>=3.2.1,<3.3.0',
'unicodecsv>=0.14.1,<0.15',
'ws4py>=0.3,<0.4',
'zope.sqlalchemy>=0.7.6,<0.8.0',

# Version pin for known bug
# https://github.com/repoze/repoze.sendmail/issues/31
'repoze.sendmail<4.2',
'transaction',
]
EXTRAS_REQUIRE = {
'dev': [
'flake8',
'honcho',
'pyramid_debugtoolbar>=2.1',
'prospector[with_pyroma]',
'sphinx_rtd_theme',
'py3kwarn',
'sphinxcontrib-httpdomain'
],
}
ENTRY_POINTS = {
'paste.app_factory': [
'main=h.app:create_app',
'websocket=h.websocket:create_app',
],
'console_scripts': [
'hypothesis=h.cli:main',
],
}
EXTRAS_REQUIRE = {}
ENTRY_POINTS = {}

with open('README.rst', encoding='utf-8') as fp:
LONGDESC = fp.read()

###############################################################################

VERSION = __import__('h').__version__
VERSION_FILE = 'h/_version.py'
VERSION_TPL = ("# This version file is autogenerated from Git data.\n"
"def get_version():\n"
" return '{version}'\n")
HERE = os.path.abspath(os.path.dirname(__file__))
VERSION_FILE = os.path.join(HERE, 'src', 'memex', '__init__.py')


@contextmanager
def static_version_file():
with open(VERSION_FILE) as fp:
previous = fp.read()
with open(VERSION_FILE, 'w') as fp:
fp.write(VERSION_TPL.format(version=VERSION))
print('updated {} with version {}'.format(VERSION_FILE, VERSION))
yield
with open(VERSION_FILE, 'w') as fp:
fp.write(previous)
print('replaced original {}'.format(VERSION_FILE))


class sdist(_sdist):
def run(self):
with static_version_file():
return _sdist.run(self)
def get_version():
"""Extract package __version__"""
with open(VERSION_FILE, encoding='utf-8') as fp:
content = fp.read()
match = re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', content, re.M)
if match:
return match.group(1)
raise RuntimeError("Could not extract package __version__")


class test(_test):
Expand All @@ -128,7 +68,7 @@ def run(self):

if __name__ == "__main__":
setup(name=NAME,
version=VERSION,
version=get_version(),
description=DESC,
long_description=LONGDESC,
classifiers=CLASSIFIERS,
Expand All @@ -140,7 +80,7 @@ def run(self):
install_requires=INSTALL_REQUIRES,
extras_require=EXTRAS_REQUIRE,
entry_points=ENTRY_POINTS,
cmdclass={'sdist': sdist,
'test': test},
packages=find_packages(include=['h', 'h.*']),
cmdclass={'test': test},
packages=find_packages(where='src'),
package_dir={'': 'src'},
zip_safe=False)
3 changes: 3 additions & 0 deletions src/memex/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-

__all__ = ('__version__',)
__version__ = '0.39.0+dev'


def includeme(config):
config.include('memex.eventqueue')
Expand Down
5 changes: 0 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,3 @@ passenv = CI TRAVIS*
commands =
coverage combine
codecov

[testenv:manifest]
deps = check-manifest
skip_install = true
commands = check-manifest

0 comments on commit e5caa07

Please sign in to comment.