Commit 6dcf67af authored by Jan Dittberner's avatar Jan Dittberner

Import python-releases_1.0.0.orig.tar.gz

parent 97996da2
Copyright (c) 2014, Jeff Forcier
Copyright (c) 2015, Jeff Forcier
All rights reserved.
Redistribution and use in source and binary forms, with or without
......
Metadata-Version: 1.0
Metadata-Version: 1.1
Name: releases
Version: 0.7.0
Version: 1.0.0
Summary: A Sphinx extension for changelog manipulation
Home-page: https://github.com/bitprophet/releases
Author: Jeff Forcier
......
......@@ -2,7 +2,7 @@
invoke>=0.6.0
invocations>=0.4.1
# Tests (N.B. integration suite also uses Invoke as above)
spec>=0.11.1
spec>=0.11.3
mock==1.0.1
# Just for tests...heh
six>=1.4.1
......@@ -10,3 +10,6 @@ six>=1.4.1
-e .
sphinx>=1.1
sphinx_rtd_theme>=0.1.5
# Builds
wheel==0.24
twine==1.5
......@@ -2,6 +2,12 @@
Changelog
=========
* :release:`1.0.0 <2015-11-05>`
* :feature:`42` For readability, issues within each release so they are
displayed in feature->bug->support order.
* :feature:`41` Clean up changelog discovery so one can have comments,
paragraphs or other non-bullet-list elements above or below the changelog.
Thanks to Rodrigue Cloutier for the original request/patch.
* :release:`0.7.0 <2014-09-04>`
* :bug:`30 major` Add LICENSE (plus a handful of other administrative files) to
a ``MANIFEST.in`` so sdists pick it up. Thanks to Zygmunt Krynicki for catch
......
......@@ -14,4 +14,3 @@ Table of Contents
concepts
usage
changelog
todo
====
TODO
====
* Possibly add more keywords to allow control over additional edge cases.
* Add shortcut format option for the release/issue URI settings - GitHub users
can just give their GitHub acct/repo and we will fill in the rest.
* Maybe say pre-1.0 releases consider all bugs 'major' (so one can e.g. put out
an 0.4.0 which is all bugfixes). Iffy because what if you *wanted* regular
feature-vs-bugfix releases pre-1.0? (which is common.)
* Make sure regular ``:issue:`` is documented.
......@@ -5,7 +5,7 @@ Usage
To use Releases, mimic the format seen in `its own changelog
<https://raw.github.com/bitprophet/releases/master/docs/changelog.rst>`_ or in
`Fabric's changelog
<https://raw.github.com/fabric/fabric/master/docs/changelog.rst>`_.
<https://raw.github.com/fabric/fabric/master/sites/www/changelog.rst>`_.
Specifically:
* Install ``releases`` and update your Sphinx ``conf.py`` to include it in the
......@@ -32,13 +32,16 @@ Specifically:
* You may optionally set ``releases_debug = True`` to see debug output
while building your docs.
* Create a Sphinx document named ``changelog.rst`` with a top-level header
followed by a bulleted list.
* Create a Sphinx document named ``changelog.rst`` containing a bulleted list
somewhere at its topmost level.
* If you wish to use a different document name, use another config option
(as per previous bullet point), ``releases_document_name``. E.g.
``releases_document_name = "CHANGES"`` would cause Releases to mutate a
file called ``CHANGES.rst`` instead of ``changelog.rst``.
* Elements before or after this bulleted list will be untouched by
Releases, allowing you to place e.g. paragraphs, comments etc at the top
(or bottom) of the document.
* List items are to be ordered chronologically with the newest ones on top.
......@@ -97,7 +100,7 @@ Then build your docs; in the rendered output, ``changelog.html`` should show
issues grouped by release, as per the above rules. Examples: `Releases' own
rendered changelog
<http://releases.readthedocs.org/en/latest/changelog.html>`_, `Fabric's
rendered changelog <http://docs.fabfile.org/en/latest/changelog.html>`_.
rendered changelog <http://www.fabfile.org/changelog.html>`_.
Optional styling additions
......
Metadata-Version: 1.0
Metadata-Version: 1.1
Name: releases
Version: 0.7.0
Version: 1.0.0
Summary: A Sphinx extension for changelog manipulation
Home-page: https://github.com/bitprophet/releases
Author: Jeff Forcier
......
......@@ -2,13 +2,14 @@ LICENSE
MANIFEST.in
README.rst
dev-requirements.txt
setup.cfg
setup.py
tasks.py
docs/.changelog.rst.swp
docs/changelog.rst
docs/concepts.rst
docs/conf.py
docs/index.rst
docs/todo.rst
docs/usage.rst
releases/__init__.py
releases/_version.py
......
......@@ -72,7 +72,8 @@ def issues_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
if ported not in ('backported', 'major', ''):
match = release_line_re.match(ported)
if not match:
raise ValueError("Gave unknown issue metadata '%s' for issue no. %s" % (ported, issue_no))
err = "Gave unknown issue metadata '{0} for issue no. {1}"
raise ValueError(err.format(ported, issue_no))
else:
line = match.groups()[0]
# Create temporary node w/ data & final nodes to publish
......@@ -105,7 +106,8 @@ def release_nodes(text, slug, date, config):
datespan = ''
if date:
datespan = ' <span style="font-size: 75%%;">{0}</span>'.format(date)
header = '<h2 style="margin-bottom: 0.3em;">{0}{1}</h2>'.format(link, datespan)
header = '<h2 style="margin-bottom: 0.3em;">{0}{1}</h2>'.format(
link, datespan)
return nodes.section('',
nodes.raw(rawtext='', text=header, format='html'),
ids=[text]
......@@ -161,6 +163,16 @@ def append_unreleased_entries(app, lines, releases):
})
def reorder_release_entries(releases):
"""
Mutate ``releases`` so the entrylist in each is ordered by feature/bug/etc.
"""
order = {'feature': 0, 'bug': 1, 'support': 2}
for release in releases:
entries = release['entries'][:]
release['entries'] = sorted(entries, key=lambda x: order[x.type])
def construct_entry_with_release(focus, issues, lines, log, releases, rest):
"""
Releases 'eat' the entries in their line's list and get added to the
......@@ -346,7 +358,9 @@ def construct_releases(entries, app):
# Release lines, once the release obj is removed, should be empty or a
# comma-separated list of issue numbers.
if isinstance(focus, Release):
construct_entry_with_release(focus, issues, lines, log, releases, rest)
construct_entry_with_release(
focus, issues, lines, log, releases, rest
)
# Entries get copied into release line buckets as follows:
# * Features and support go into 'unreleased_feature' for use in new
......@@ -368,6 +382,8 @@ def construct_releases(entries, app):
append_unreleased_entries(app, lines, releases)
reorder_release_entries(releases)
return releases
......@@ -414,17 +430,36 @@ def construct_nodes(releases):
return result
class BulletListVisitor(nodes.NodeVisitor):
def __init__(self, document, app):
nodes.NodeVisitor.__init__(self, document)
self.found_changelog = False
self.app = app
def visit_bullet_list(self, node):
# The first found bullet list (which should be the first one at the top
# level of the document) is the changelog.
if not self.found_changelog:
self.found_changelog = True
# Walk + parse into release mapping
releases = construct_releases(node.children, self.app)
# Construct new set of nodes to replace the old, and we're done
node.replace_self(construct_nodes(releases))
def unknown_visit(self, node):
pass
def generate_changelog(app, doctree):
# Don't scan/mutate documents that don't match the configured document name
# (which by default is changelog.rst).
if app.env.docname != app.config.releases_document_name:
return
# Second item inside main document is the 'modern' changelog bullet-list
# object, whose children are the nodes we care about.
source = doctree[0]
changelog = source.children.pop(1)
# Walk + parse into release mapping
releases = construct_releases(changelog.children, app)
# Construct new set of nodes to replace the old, and we're done
source[1:1] = construct_nodes(releases)
# Find the first bullet-list node & replace it with our organized/parsed
# elements.
changelog_visitor = BulletListVisitor(doctree, app)
doctree.walk(changelog_visitor)
def setup(app):
......
__version_info__ = (0, 7, 0)
__version_info__ = (1, 0, 0)
__version__ = '.'.join(map(str, __version_info__))
[bdist_wheel]
universal = 1
[egg_info]
tag_build =
tag_date = 0
......
......@@ -7,10 +7,13 @@ from invoke import run
from invoke import task
@task()
def integration_tests():
@task(help={
'pty': "Whether to run tests under a pseudo-tty",
})
def integration(pty=True):
"""Runs integration tests."""
run('inv test -o --tests=integration')
cmd = 'inv test -o --tests=integration'
run(cmd + ('' if pty else ' --no-pty'), pty=pty)
ns = Collection(test, integration_tests, release, docs)
ns = Collection(test, integration, release, docs)
......@@ -2,13 +2,13 @@ from tempfile import mkdtemp
from shutil import rmtree
import six
from spec import Spec, skip, eq_, raises
from spec import Spec, eq_, raises
from mock import Mock
from docutils.nodes import (
reference, bullet_list, list_item, title, raw, paragraph, Text, section,
reference, bullet_list, list_item, raw, paragraph, Text,
)
from docutils.utils import new_document
from sphinx.application import Sphinx
import sphinx
from releases import (
Issue,
......@@ -17,7 +17,6 @@ from releases import (
release_role,
construct_releases,
construct_nodes,
generate_changelog,
)
from releases import setup as releases_setup # avoid unittest crap
......@@ -26,14 +25,14 @@ def _app(**kwargs):
# Create a real Sphinx app, with stupid temp dirs because it assumes.
# Helps catch things like "testing a config option but forgot
# app.add_config_value()"
src, doctree = mkdtemp(), mkdtemp()
src, dst, doctree = mkdtemp(), mkdtemp(), mkdtemp()
try:
# STFU Sphinx :(
Sphinx._log = lambda self, message, wfile, nonl=False: None
app = Sphinx(
srcdir=src,
confdir=None,
outdir=None,
outdir=dst,
doctreedir=doctree,
buildername='html',
)
......@@ -54,7 +53,11 @@ def _app(**kwargs):
config['releases_{0}'.format(name)] = kwargs[name]
# Stitch together as the sphinx app init() usually does w/ real conf files
app.config._raw_config = config
app.config.init_values()
# init_values() requires a 'warn' runner on Sphinx 1.3+, give it no-op.
init_args = []
if sphinx.version_info[:2] > (1, 2):
init_args = [lambda x: x]
app.config.init_values(*init_args)
return app
def _inliner(app=None):
......@@ -329,6 +332,22 @@ class releases(Spec):
cl = _changelog2dict(cl)
assert len(cl['1.0.1']) == 2
def issues_are_sorted_by_type_within_releases(self):
b1 = _issue('bug', '123', major=True)
b2 = _issue('bug', '124', major=True)
s1 = _issue('support', '25')
s2 = _issue('support', '26')
f1 = _issue('feature', '3455')
f2 = _issue('feature', '3456')
# Semi random definitely-not-in-desired-order order
changelog = _changelog2dict(_releases('1.1', b1, s1, s2, f1, b2, f2))
# Order should be feature, bug, support. While it doesn't REALLY
# matter, assert that within each category the order matches the old
# 'reverse chronological' order.
eq_(changelog['1.1'], [f2, f1, b2, b1, s2, s1])
def _obj2name(obj):
cls = obj if isinstance(obj, type) else obj.__class__
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment