annotate python-daemon-2.0.5/version.py @ 47:b19e848f9886

update xena to v16
author jingchunzhu
date Fri, 07 Aug 2015 17:01:10 -0700
parents 7ceb967147c3
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
2
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
3 # version.py
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
4 # Part of ‘python-daemon’, an implementation of PEP 3143.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
5 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
6 # Copyright © 2008–2015 Ben Finney <ben+python@benfinney.id.au>
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
7 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
8 # This is free software: you may copy, modify, and/or distribute this work
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
9 # under the terms of the GNU General Public License as published by the
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
10 # Free Software Foundation; version 3 of that license or any later version.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
11 # No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
12
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
13 """ Version information unified for human- and machine-readable formats.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
14
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
15 The project ‘ChangeLog’ file is a reStructuredText document, with
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
16 each section describing a version of the project. The document is
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
17 intended to be readable as-is by end users.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
18
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
19 This module handles transformation from the ‘ChangeLog’ to a
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
20 mapping of version information, serialised as JSON. It also
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
21 provides functionality for Distutils to use this information.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
22
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
23 Requires:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
24
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
25 * Docutils <http://docutils.sourceforge.net/>
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
26 * JSON <https://docs.python.org/3/reference/json.html>
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
27
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
28 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
29
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
30 from __future__ import (absolute_import, unicode_literals)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
31
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
32 import sys
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
33 import os
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
34 import io
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
35 import errno
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
36 import json
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
37 import datetime
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
38 import textwrap
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
39 import re
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
40 import functools
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
41 import collections
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
42 import distutils
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
43 import distutils.errors
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
44 import distutils.cmd
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
45 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
46 # Python 2 has both ‘str’ (bytes) and ‘unicode’ (text).
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
47 basestring = basestring
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
48 unicode = unicode
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
49 except NameError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
50 # Python 3 names the Unicode data type ‘str’.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
51 basestring = str
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
52 unicode = str
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
53
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
54 import setuptools
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
55 import setuptools.command.egg_info
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
56
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
57
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
58 def ensure_class_bases_begin_with(namespace, class_name, base_class):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
59 """ Ensure the named class's bases start with the base class.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
60
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
61 :param namespace: The namespace containing the class name.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
62 :param class_name: The name of the class to alter.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
63 :param base_class: The type to be the first base class for the
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
64 newly created type.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
65 :return: ``None``.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
66
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
67 This function is a hack to circumvent a circular dependency:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
68 using classes from a module which is not installed at the time
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
69 this module is imported.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
70
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
71 Call this function after ensuring `base_class` is available,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
72 before using the class named by `class_name`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
73
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
74 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
75 existing_class = namespace[class_name]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
76 assert isinstance(existing_class, type)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
77
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
78 bases = list(existing_class.__bases__)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
79 if base_class is bases[0]:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
80 # Already bound to a type with the right bases.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
81 return
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
82 bases.insert(0, base_class)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
83
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
84 new_class_namespace = existing_class.__dict__.copy()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
85 # Type creation will assign the correct ‘__dict__’ attribute.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
86 del new_class_namespace['__dict__']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
87
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
88 metaclass = existing_class.__metaclass__
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
89 new_class = metaclass(class_name, tuple(bases), new_class_namespace)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
90
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
91 namespace[class_name] = new_class
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
92
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
93
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
94 class VersionInfoWriter(object):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
95 """ Docutils writer to produce a version info JSON data stream. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
96
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
97 # This class needs its base class to be a class from `docutils`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
98 # But that would create a circular dependency: Setuptools cannot
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
99 # ensure `docutils` is available before importing this module.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
100 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
101 # Use `ensure_class_bases_begin_with` after importing `docutils`, to
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
102 # re-bind the `VersionInfoWriter` name to a new type that inherits
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
103 # from `docutils.writers.Writer`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
104
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
105 __metaclass__ = type
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
106
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
107 supported = ['version_info']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
108 """ Formats this writer supports. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
109
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
110 def __init__(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
111 super(VersionInfoWriter, self).__init__()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
112 self.translator_class = VersionInfoTranslator
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
113
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
114 def translate(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
115 visitor = self.translator_class(self.document)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
116 self.document.walkabout(visitor)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
117 self.output = visitor.astext()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
118
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
119
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
120 rfc822_person_regex = re.compile(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
121 "^(?P<name>[^<]+) <(?P<email>[^>]+)>$")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
122
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
123 class ChangeLogEntry:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
124 """ An individual entry from the ‘ChangeLog’ document. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
125
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
126 __metaclass__ = type
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
127
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
128 field_names = [
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
129 'release_date',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
130 'version',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
131 'maintainer',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
132 'body',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
133 ]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
134
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
135 date_format = "%Y-%m-%d"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
136 default_version = "UNKNOWN"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
137 default_release_date = "UNKNOWN"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
138
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
139 def __init__(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
140 self,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
141 release_date=default_release_date, version=default_version,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
142 maintainer=None, body=None):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
143 self.validate_release_date(release_date)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
144 self.release_date = release_date
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
145
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
146 self.version = version
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
147
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
148 self.validate_maintainer(maintainer)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
149 self.maintainer = maintainer
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
150 self.body = body
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
151
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
152 @classmethod
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
153 def validate_release_date(cls, value):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
154 """ Validate the `release_date` value.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
155
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
156 :param value: The prospective `release_date` value.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
157 :return: ``None`` if the value is valid.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
158 :raises ValueError: If the value is invalid.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
159
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
160 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
161 if value in ["UNKNOWN", "FUTURE"]:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
162 # A valid non-date value.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
163 return None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
164
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
165 # Raises `ValueError` if parse fails.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
166 datetime.datetime.strptime(value, ChangeLogEntry.date_format)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
167
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
168 @classmethod
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
169 def validate_maintainer(cls, value):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
170 """ Validate the `maintainer` value.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
171
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
172 :param value: The prospective `maintainer` value.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
173 :return: ``None`` if the value is valid.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
174 :raises ValueError: If the value is invalid.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
175
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
176 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
177 valid = False
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
178
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
179 if value is None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
180 valid = True
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
181 elif rfc822_person_regex.search(value):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
182 valid = True
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
183
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
184 if not valid:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
185 raise ValueError("Not a valid person specification {value!r}")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
186 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
187 return None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
188
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
189 @classmethod
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
190 def make_ordered_dict(cls, fields):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
191 """ Make an ordered dict of the fields. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
192 result = collections.OrderedDict(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
193 (name, fields[name])
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
194 for name in cls.field_names)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
195 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
196
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
197 def as_version_info_entry(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
198 """ Format the changelog entry as a version info entry. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
199 fields = vars(self)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
200 entry = self.make_ordered_dict(fields)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
201
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
202 return entry
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
203
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
204
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
205 class InvalidFormatError(ValueError):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
206 """ Raised when the document is not a valid ‘ChangeLog’ document. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
207
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
208
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
209 class VersionInfoTranslator(object):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
210 """ Translator from document nodes to a version info stream. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
211
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
212 # This class needs its base class to be a class from `docutils`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
213 # But that would create a circular dependency: Setuptools cannot
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
214 # ensure `docutils` is available before importing this module.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
215 #
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
216 # Use `ensure_class_bases_begin_with` after importing `docutils`,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
217 # to re-bind the `VersionInfoTranslator` name to a new type that
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
218 # inherits from `docutils.nodes.SparseNodeVisitor`.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
219
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
220 __metaclass__ = type
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
221
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
222 wrap_width = 78
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
223 bullet_text = "* "
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
224
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
225 attr_convert_funcs_by_attr_name = {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
226 'released': ('release_date', unicode),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
227 'version': ('version', unicode),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
228 'maintainer': ('maintainer', unicode),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
229 }
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
230
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
231 def __init__(self, document):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
232 super(VersionInfoTranslator, self).__init__(document)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
233 self.settings = document.settings
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
234 self.current_section_level = 0
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
235 self.current_field_name = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
236 self.content = []
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
237 self.indent_width = 0
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
238 self.initial_indent = ""
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
239 self.subsequent_indent = ""
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
240 self.current_entry = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
241
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
242 # Docutils is not available when this class is defined.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
243 # Get the `docutils` module dynamically.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
244 self._docutils = sys.modules['docutils']
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
245
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
246 def astext(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
247 """ Return the translated document as text. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
248 text = json.dumps(self.content, indent=4)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
249 return text
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
250
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
251 def append_to_current_entry(self, text):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
252 if self.current_entry is not None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
253 if self.current_entry.body is not None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
254 self.current_entry.body += text
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
255
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
256 def visit_Text(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
257 raw_text = node.astext()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
258 text = textwrap.fill(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
259 raw_text,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
260 width=self.wrap_width,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
261 initial_indent=self.initial_indent,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
262 subsequent_indent=self.subsequent_indent)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
263 self.append_to_current_entry(text)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
264
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
265 def depart_Text(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
266 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
267
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
268 def visit_comment(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
269 raise self._docutils.nodes.SkipNode
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
270
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
271 def visit_field_body(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
272 field_list_node = node.parent.parent
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
273 if not isinstance(field_list_node, self._docutils.nodes.field_list):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
274 raise InvalidFormatError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
275 "Unexpected field within {node!r}".format(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
276 node=field_list_node))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
277 (attr_name, convert_func) = self.attr_convert_funcs_by_attr_name[
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
278 self.current_field_name]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
279 attr_value = convert_func(node.astext())
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
280 setattr(self.current_entry, attr_name, attr_value)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
281
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
282 def depart_field_body(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
283 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
284
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
285 def visit_field_list(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
286 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
287
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
288 def depart_field_list(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
289 self.current_field_name = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
290 self.current_entry.body = ""
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
291
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
292 def visit_field_name(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
293 field_name = node.astext()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
294 if self.current_section_level == 1:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
295 # At a top-level section.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
296 if field_name.lower() not in ["released", "maintainer"]:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
297 raise InvalidFormatError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
298 "Unexpected field name {name!r}".format(name=field_name))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
299 self.current_field_name = field_name.lower()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
300
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
301 def depart_field_name(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
302 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
303
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
304 def visit_bullet_list(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
305 self.current_context = []
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
306
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
307 def depart_bullet_list(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
308 self.current_entry.changes = self.current_context
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
309 self.current_context = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
310
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
311 def adjust_indent_width(self, delta):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
312 self.indent_width += delta
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
313 self.subsequent_indent = " " * self.indent_width
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
314 self.initial_indent = self.subsequent_indent
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
315
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
316 def visit_list_item(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
317 indent_delta = +len(self.bullet_text)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
318 self.adjust_indent_width(indent_delta)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
319 self.initial_indent = self.subsequent_indent[:-indent_delta]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
320 self.append_to_current_entry(self.initial_indent + self.bullet_text)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
321
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
322 def depart_list_item(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
323 indent_delta = +len(self.bullet_text)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
324 self.adjust_indent_width(-indent_delta)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
325 self.append_to_current_entry("\n")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
326
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
327 def visit_section(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
328 self.current_section_level += 1
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
329 if self.current_section_level == 1:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
330 # At a top-level section.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
331 self.current_entry = ChangeLogEntry()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
332 else:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
333 raise InvalidFormatError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
334 "Subsections not implemented for this writer")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
335
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
336 def depart_section(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
337 self.current_section_level -= 1
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
338 self.content.append(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
339 self.current_entry.as_version_info_entry())
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
340 self.current_entry = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
341
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
342 _expected_title_word_length = len("Version FOO".split(" "))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
343
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
344 def depart_title(self, node):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
345 title_text = node.astext()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
346 # At a top-level section.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
347 words = title_text.split(" ")
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
348 version = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
349 if len(words) != self._expected_title_word_length:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
350 raise InvalidFormatError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
351 "Unexpected title text {text!r}".format(text=title_text))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
352 if words[0].lower() not in ["version"]:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
353 raise InvalidFormatError(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
354 "Unexpected title text {text!r}".format(text=title_text))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
355 version = words[-1]
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
356 self.current_entry.version = version
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
357
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
358
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
359 def changelog_to_version_info_collection(infile):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
360 """ Render the ‘ChangeLog’ document to a version info collection.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
361
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
362 :param infile: A file-like object containing the changelog.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
363 :return: The serialised JSON data of the version info collection.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
364
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
365 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
366
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
367 # Docutils is not available when Setuptools needs this module, so
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
368 # delay the imports to this function instead.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
369 import docutils.core
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
370 import docutils.nodes
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
371 import docutils.writers
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
372
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
373 ensure_class_bases_begin_with(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
374 globals(), str('VersionInfoWriter'), docutils.writers.Writer)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
375 ensure_class_bases_begin_with(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
376 globals(), str('VersionInfoTranslator'),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
377 docutils.nodes.SparseNodeVisitor)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
378
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
379 writer = VersionInfoWriter()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
380 settings_overrides = {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
381 'doctitle_xform': False,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
382 }
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
383 version_info_json = docutils.core.publish_string(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
384 infile.read(), writer=writer,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
385 settings_overrides=settings_overrides)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
386
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
387 return version_info_json
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
388
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
389
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
390 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
391 lru_cache = functools.lru_cache
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
392 except AttributeError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
393 # Python < 3.2 does not have the `functools.lru_cache` function.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
394 # Not essential, so replace it with a no-op.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
395 lru_cache = lambda maxsize=None, typed=False: lambda func: func
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
396
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
397
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
398 @lru_cache(maxsize=128)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
399 def generate_version_info_from_changelog(infile_path):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
400 """ Get the version info for the latest version in the changelog.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
401
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
402 :param infile_path: Filesystem path to the input changelog file.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
403 :return: The generated version info mapping; or ``None`` if the
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
404 file cannot be read.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
405
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
406 The document is explicitly opened as UTF-8 encoded text.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
407
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
408 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
409 version_info = collections.OrderedDict()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
410
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
411 versions_all_json = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
412 try:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
413 with io.open(infile_path, 'rt', encoding="utf-8") as infile:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
414 versions_all_json = changelog_to_version_info_collection(infile)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
415 except EnvironmentError:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
416 # If we can't read the input file, leave the collection empty.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
417 pass
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
418
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
419 if versions_all_json is not None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
420 versions_all = json.loads(versions_all_json.decode('utf-8'))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
421 version_info = get_latest_version(versions_all)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
422
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
423 return version_info
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
424
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
425
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
426 def get_latest_version(versions):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
427 """ Get the latest version from a collection of changelog entries.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
428
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
429 :param versions: A collection of mappings for changelog entries.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
430 :return: An ordered mapping of fields for the latest version,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
431 if `versions` is non-empty; otherwise, an empty mapping.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
432
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
433 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
434 version_info = collections.OrderedDict()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
435
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
436 versions_by_release_date = {
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
437 item['release_date']: item
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
438 for item in versions}
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
439 if versions_by_release_date:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
440 latest_release_date = max(versions_by_release_date.keys())
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
441 version_info = ChangeLogEntry.make_ordered_dict(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
442 versions_by_release_date[latest_release_date])
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
443
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
444 return version_info
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
445
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
446
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
447 def serialise_version_info_from_mapping(version_info):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
448 """ Generate the version info serialised data.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
449
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
450 :param version_info: Mapping of version info items.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
451 :return: The version info serialised to JSON.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
452
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
453 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
454 content = json.dumps(version_info, indent=4)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
455
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
456 return content
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
457
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
458
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
459 changelog_filename = "ChangeLog"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
460
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
461 def get_changelog_path(distribution, filename=changelog_filename):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
462 """ Get the changelog file path for the distribution.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
463
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
464 :param distribution: The distutils.dist.Distribution instance.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
465 :param filename: The base filename of the changelog document.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
466 :return: Filesystem path of the changelog document, or ``None``
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
467 if not discoverable.
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
468
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
469 """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
470 setup_dirname = os.path.dirname(distribution.script_name)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
471 filepath = os.path.join(setup_dirname, filename)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
472
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
473 return filepath
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
474
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
475
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
476 def has_changelog(command):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
477 """ Return ``True`` iff the distribution's changelog file exists. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
478 result = False
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
479
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
480 changelog_path = get_changelog_path(command.distribution)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
481 if changelog_path is not None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
482 if os.path.exists(changelog_path):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
483 result = True
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
484
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
485 return result
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
486
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
487
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
488 class EggInfoCommand(setuptools.command.egg_info.egg_info, object):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
489 """ Custom ‘egg_info’ command for this distribution. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
490
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
491 sub_commands = ([
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
492 ('write_version_info', has_changelog),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
493 ] + setuptools.command.egg_info.egg_info.sub_commands)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
494
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
495 def run(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
496 """ Execute this command. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
497 super(EggInfoCommand, self).run()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
498
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
499 for command_name in self.get_sub_commands():
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
500 self.run_command(command_name)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
501
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
502
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
503 version_info_filename = "version_info.json"
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
504
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
505 class WriteVersionInfoCommand(EggInfoCommand, object):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
506 """ Setuptools command to serialise version info metadata. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
507
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
508 user_options = ([
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
509 ("changelog-path=", None,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
510 "Filesystem path to the changelog document."),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
511 ("outfile-path=", None,
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
512 "Filesystem path to the version info file."),
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
513 ] + EggInfoCommand.user_options)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
514
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
515 def initialize_options(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
516 """ Initialise command options to defaults. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
517 super(WriteVersionInfoCommand, self).initialize_options()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
518 self.changelog_path = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
519 self.outfile_path = None
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
520
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
521 def finalize_options(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
522 """ Finalise command options before execution. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
523 self.set_undefined_options(
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
524 'build',
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
525 ('force', 'force'))
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
526
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
527 super(WriteVersionInfoCommand, self).finalize_options()
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
528
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
529 if self.changelog_path is None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
530 self.changelog_path = get_changelog_path(self.distribution)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
531
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
532 if self.outfile_path is None:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
533 egg_dir = self.egg_info
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
534 self.outfile_path = os.path.join(egg_dir, version_info_filename)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
535
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
536 def run(self):
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
537 """ Execute this command. """
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
538 version_info = generate_version_info_from_changelog(self.changelog_path)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
539 content = serialise_version_info_from_mapping(version_info)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
540 self.write_file("version info", self.outfile_path, content)
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
541
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
542
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
543 # Local variables:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
544 # coding: utf-8
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
545 # mode: python
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
546 # End:
7ceb967147c3 start xena with no gui
jingchunzhu <jingchunzhu@gmail.com>
parents:
diff changeset
547 # vim: fileencoding=utf-8 filetype=python :