mirror of
https://github.com/ansible/awx.git
synced 2026-05-22 16:27:42 -02:30
AC-505 Add vendored copies of ec2 and rax inventory scripts from Ansible (for now). Add vendored versions of boto and pyrax and all their dependencies, updated all vendored packages to latest versions.
This commit is contained in:
4
awx/lib/site-packages/d2to1/__init__.py
Normal file
4
awx/lib/site-packages/d2to1/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
try:
|
||||
__version__ = __import__('pkg_resources').get_distribution('d2to1').version
|
||||
except:
|
||||
__version__ = ''
|
||||
83
awx/lib/site-packages/d2to1/core.py
Normal file
83
awx/lib/site-packages/d2to1/core.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from distutils.core import Distribution as _Distribution
|
||||
from distutils.errors import DistutilsFileError, DistutilsSetupError
|
||||
from setuptools.dist import _get_unpatched
|
||||
|
||||
from .extern import six
|
||||
from .util import DefaultGetDict, IgnoreDict, cfg_to_args
|
||||
|
||||
|
||||
_Distribution = _get_unpatched(_Distribution)
|
||||
|
||||
|
||||
def d2to1(dist, attr, value):
|
||||
"""Implements the actual d2to1 setup() keyword. When used, this should be
|
||||
the only keyword in your setup() aside from `setup_requires`.
|
||||
|
||||
If given as a string, the value of d2to1 is assumed to be the relative path
|
||||
to the setup.cfg file to use. Otherwise, if it evaluates to true, it
|
||||
simply assumes that d2to1 should be used, and the default 'setup.cfg' is
|
||||
used.
|
||||
|
||||
This works by reading the setup.cfg file, parsing out the supported
|
||||
metadata and command options, and using them to rebuild the
|
||||
`DistributionMetadata` object and set the newly added command options.
|
||||
|
||||
The reason for doing things this way is that a custom `Distribution` class
|
||||
will not play nicely with setup_requires; however, this implementation may
|
||||
not work well with distributions that do use a `Distribution` subclass.
|
||||
"""
|
||||
|
||||
if not value:
|
||||
return
|
||||
if isinstance(value, six.string_types):
|
||||
path = os.path.abspath(value)
|
||||
else:
|
||||
path = os.path.abspath('setup.cfg')
|
||||
if not os.path.exists(path):
|
||||
raise DistutilsFileError(
|
||||
'The setup.cfg file %s does not exist.' % path)
|
||||
|
||||
# Converts the setup.cfg file to setup() arguments
|
||||
try:
|
||||
attrs = cfg_to_args(path)
|
||||
except:
|
||||
e = sys.exc_info()[1]
|
||||
raise DistutilsSetupError(
|
||||
'Error parsing %s: %s: %s' % (path, e.__class__.__name__,
|
||||
e.args[0]))
|
||||
|
||||
# Repeat some of the Distribution initialization code with the newly
|
||||
# provided attrs
|
||||
if attrs:
|
||||
# Skips 'options' and 'licence' support which are rarely used; may add
|
||||
# back in later if demanded
|
||||
for key, val in six.iteritems(attrs):
|
||||
if hasattr(dist.metadata, 'set_' + key):
|
||||
getattr(dist.metadata, 'set_' + key)(val)
|
||||
elif hasattr(dist.metadata, key):
|
||||
setattr(dist.metadata, key, val)
|
||||
elif hasattr(dist, key):
|
||||
setattr(dist, key, val)
|
||||
else:
|
||||
msg = 'Unknown distribution option: %s' % repr(key)
|
||||
warnings.warn(msg)
|
||||
|
||||
# Re-finalize the underlying Distribution
|
||||
_Distribution.finalize_options(dist)
|
||||
|
||||
# This bit comes out of distribute/setuptools
|
||||
if isinstance(dist.metadata.version, six.integer_types + (float,)):
|
||||
# Some people apparently take "version number" too literally :)
|
||||
dist.metadata.version = str(dist.metadata.version)
|
||||
|
||||
# This bit of hackery is necessary so that the Distribution will ignore
|
||||
# normally unsupport command options (namely pre-hooks and post-hooks).
|
||||
# dist.command_options is normally a dict mapping command names to dicts of
|
||||
# their options. Now it will be a defaultdict that returns IgnoreDicts for
|
||||
# the each command's options so we can pass through the unsupported options
|
||||
ignore = ['pre_hook.*', 'post_hook.*']
|
||||
dist.command_options = DefaultGetDict(lambda: IgnoreDict(ignore))
|
||||
0
awx/lib/site-packages/d2to1/extern/__init__.py
vendored
Normal file
0
awx/lib/site-packages/d2to1/extern/__init__.py
vendored
Normal file
386
awx/lib/site-packages/d2to1/extern/six.py
vendored
Normal file
386
awx/lib/site-packages/d2to1/extern/six.py
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
# Copyright (c) 2010-2011 Benjamin Peterson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
"""Utilities for writing code that runs on Python 2 and 3"""
|
||||
|
||||
import operator
|
||||
import sys
|
||||
import types
|
||||
|
||||
__author__ = "Benjamin Peterson <benjamin@python.org>"
|
||||
__version__ = "1.2.0"
|
||||
|
||||
|
||||
# True if we are running on Python 3.
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
if PY3:
|
||||
string_types = str,
|
||||
integer_types = int,
|
||||
class_types = type,
|
||||
text_type = str
|
||||
binary_type = bytes
|
||||
|
||||
MAXSIZE = sys.maxsize
|
||||
else:
|
||||
string_types = basestring,
|
||||
integer_types = (int, long)
|
||||
class_types = (type, types.ClassType)
|
||||
text_type = unicode
|
||||
binary_type = str
|
||||
|
||||
if sys.platform == "java":
|
||||
# Jython always uses 32 bits.
|
||||
MAXSIZE = int((1 << 31) - 1)
|
||||
else:
|
||||
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
|
||||
class X(object):
|
||||
def __len__(self):
|
||||
return 1 << 31
|
||||
try:
|
||||
len(X())
|
||||
except OverflowError:
|
||||
# 32-bit
|
||||
MAXSIZE = int((1 << 31) - 1)
|
||||
else:
|
||||
# 64-bit
|
||||
MAXSIZE = int((1 << 63) - 1)
|
||||
del X
|
||||
|
||||
|
||||
def _add_doc(func, doc):
|
||||
"""Add documentation to a function."""
|
||||
func.__doc__ = doc
|
||||
|
||||
|
||||
def _import_module(name):
|
||||
"""Import module, returning the module after the last dot."""
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
|
||||
|
||||
class _LazyDescr(object):
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __get__(self, obj, tp):
|
||||
result = self._resolve()
|
||||
setattr(obj, self.name, result)
|
||||
# This is a bit ugly, but it avoids running this again.
|
||||
delattr(tp, self.name)
|
||||
return result
|
||||
|
||||
|
||||
class MovedModule(_LazyDescr):
|
||||
|
||||
def __init__(self, name, old, new=None):
|
||||
super(MovedModule, self).__init__(name)
|
||||
if PY3:
|
||||
if new is None:
|
||||
new = name
|
||||
self.mod = new
|
||||
else:
|
||||
self.mod = old
|
||||
|
||||
def _resolve(self):
|
||||
return _import_module(self.mod)
|
||||
|
||||
|
||||
class MovedAttribute(_LazyDescr):
|
||||
|
||||
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
|
||||
super(MovedAttribute, self).__init__(name)
|
||||
if PY3:
|
||||
if new_mod is None:
|
||||
new_mod = name
|
||||
self.mod = new_mod
|
||||
if new_attr is None:
|
||||
if old_attr is None:
|
||||
new_attr = name
|
||||
else:
|
||||
new_attr = old_attr
|
||||
self.attr = new_attr
|
||||
else:
|
||||
self.mod = old_mod
|
||||
if old_attr is None:
|
||||
old_attr = name
|
||||
self.attr = old_attr
|
||||
|
||||
def _resolve(self):
|
||||
module = _import_module(self.mod)
|
||||
return getattr(module, self.attr)
|
||||
|
||||
|
||||
|
||||
class _MovedItems(types.ModuleType):
|
||||
"""Lazy loading of moved objects"""
|
||||
|
||||
|
||||
_moved_attributes = [
|
||||
MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
|
||||
MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
|
||||
MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
|
||||
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
|
||||
MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
|
||||
MovedAttribute("reduce", "__builtin__", "functools"),
|
||||
MovedAttribute("StringIO", "StringIO", "io"),
|
||||
MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
|
||||
MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
|
||||
|
||||
MovedModule("builtins", "__builtin__"),
|
||||
MovedModule("configparser", "ConfigParser"),
|
||||
MovedModule("copyreg", "copy_reg"),
|
||||
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
|
||||
MovedModule("http_cookies", "Cookie", "http.cookies"),
|
||||
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
|
||||
MovedModule("html_parser", "HTMLParser", "html.parser"),
|
||||
MovedModule("http_client", "httplib", "http.client"),
|
||||
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
|
||||
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
|
||||
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
|
||||
MovedModule("cPickle", "cPickle", "pickle"),
|
||||
MovedModule("queue", "Queue"),
|
||||
MovedModule("reprlib", "repr"),
|
||||
MovedModule("socketserver", "SocketServer"),
|
||||
MovedModule("tkinter", "Tkinter"),
|
||||
MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
|
||||
MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
|
||||
MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
|
||||
MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
|
||||
MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
|
||||
MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
|
||||
MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
|
||||
MovedModule("tkinter_colorchooser", "tkColorChooser",
|
||||
"tkinter.colorchooser"),
|
||||
MovedModule("tkinter_commondialog", "tkCommonDialog",
|
||||
"tkinter.commondialog"),
|
||||
MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
|
||||
MovedModule("tkinter_font", "tkFont", "tkinter.font"),
|
||||
MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
|
||||
MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
|
||||
"tkinter.simpledialog"),
|
||||
MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
|
||||
MovedModule("winreg", "_winreg"),
|
||||
]
|
||||
for attr in _moved_attributes:
|
||||
setattr(_MovedItems, attr.name, attr)
|
||||
del attr
|
||||
|
||||
moves = sys.modules["six.moves"] = _MovedItems("moves")
|
||||
|
||||
|
||||
def add_move(move):
|
||||
"""Add an item to six.moves."""
|
||||
setattr(_MovedItems, move.name, move)
|
||||
|
||||
|
||||
def remove_move(name):
|
||||
"""Remove item from six.moves."""
|
||||
try:
|
||||
delattr(_MovedItems, name)
|
||||
except AttributeError:
|
||||
try:
|
||||
del moves.__dict__[name]
|
||||
except KeyError:
|
||||
raise AttributeError("no such move, %r" % (name,))
|
||||
|
||||
|
||||
if PY3:
|
||||
_meth_func = "__func__"
|
||||
_meth_self = "__self__"
|
||||
|
||||
_func_code = "__code__"
|
||||
_func_defaults = "__defaults__"
|
||||
|
||||
_iterkeys = "keys"
|
||||
_itervalues = "values"
|
||||
_iteritems = "items"
|
||||
else:
|
||||
_meth_func = "im_func"
|
||||
_meth_self = "im_self"
|
||||
|
||||
_func_code = "func_code"
|
||||
_func_defaults = "func_defaults"
|
||||
|
||||
_iterkeys = "iterkeys"
|
||||
_itervalues = "itervalues"
|
||||
_iteritems = "iteritems"
|
||||
|
||||
|
||||
try:
|
||||
advance_iterator = next
|
||||
except NameError:
|
||||
def advance_iterator(it):
|
||||
return it.next()
|
||||
next = advance_iterator
|
||||
|
||||
|
||||
if PY3:
|
||||
def get_unbound_function(unbound):
|
||||
return unbound
|
||||
|
||||
Iterator = object
|
||||
|
||||
def callable(obj):
|
||||
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
|
||||
else:
|
||||
def get_unbound_function(unbound):
|
||||
return unbound.im_func
|
||||
|
||||
class Iterator(object):
|
||||
|
||||
def next(self):
|
||||
return type(self).__next__(self)
|
||||
|
||||
callable = callable
|
||||
_add_doc(get_unbound_function,
|
||||
"""Get the function out of a possibly unbound function""")
|
||||
|
||||
|
||||
get_method_function = operator.attrgetter(_meth_func)
|
||||
get_method_self = operator.attrgetter(_meth_self)
|
||||
get_function_code = operator.attrgetter(_func_code)
|
||||
get_function_defaults = operator.attrgetter(_func_defaults)
|
||||
|
||||
|
||||
def iterkeys(d):
|
||||
"""Return an iterator over the keys of a dictionary."""
|
||||
return iter(getattr(d, _iterkeys)())
|
||||
|
||||
def itervalues(d):
|
||||
"""Return an iterator over the values of a dictionary."""
|
||||
return iter(getattr(d, _itervalues)())
|
||||
|
||||
def iteritems(d):
|
||||
"""Return an iterator over the (key, value) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iteritems)())
|
||||
|
||||
|
||||
if PY3:
|
||||
def b(s):
|
||||
return s.encode("latin-1")
|
||||
def u(s):
|
||||
return s
|
||||
if sys.version_info[1] <= 1:
|
||||
def int2byte(i):
|
||||
return bytes((i,))
|
||||
else:
|
||||
# This is about 2x faster than the implementation above on 3.2+
|
||||
int2byte = operator.methodcaller("to_bytes", 1, "big")
|
||||
import io
|
||||
StringIO = io.StringIO
|
||||
BytesIO = io.BytesIO
|
||||
else:
|
||||
def b(s):
|
||||
return s
|
||||
def u(s):
|
||||
return unicode(s, "unicode_escape")
|
||||
int2byte = chr
|
||||
import StringIO
|
||||
StringIO = BytesIO = StringIO.StringIO
|
||||
_add_doc(b, """Byte literal""")
|
||||
_add_doc(u, """Text literal""")
|
||||
|
||||
|
||||
if PY3:
|
||||
import builtins
|
||||
exec_ = getattr(builtins, "exec")
|
||||
|
||||
|
||||
def reraise(tp, value, tb=None):
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
raise value
|
||||
|
||||
|
||||
print_ = getattr(builtins, "print")
|
||||
del builtins
|
||||
|
||||
else:
|
||||
def exec_(code, globs=None, locs=None):
|
||||
"""Execute code in a namespace."""
|
||||
if globs is None:
|
||||
frame = sys._getframe(1)
|
||||
globs = frame.f_globals
|
||||
if locs is None:
|
||||
locs = frame.f_locals
|
||||
del frame
|
||||
elif locs is None:
|
||||
locs = globs
|
||||
exec("""exec code in globs, locs""")
|
||||
|
||||
|
||||
exec_("""def reraise(tp, value, tb=None):
|
||||
raise tp, value, tb
|
||||
""")
|
||||
|
||||
|
||||
def print_(*args, **kwargs):
|
||||
"""The new-style print function."""
|
||||
fp = kwargs.pop("file", sys.stdout)
|
||||
if fp is None:
|
||||
return
|
||||
def write(data):
|
||||
if not isinstance(data, basestring):
|
||||
data = str(data)
|
||||
fp.write(data)
|
||||
want_unicode = False
|
||||
sep = kwargs.pop("sep", None)
|
||||
if sep is not None:
|
||||
if isinstance(sep, unicode):
|
||||
want_unicode = True
|
||||
elif not isinstance(sep, str):
|
||||
raise TypeError("sep must be None or a string")
|
||||
end = kwargs.pop("end", None)
|
||||
if end is not None:
|
||||
if isinstance(end, unicode):
|
||||
want_unicode = True
|
||||
elif not isinstance(end, str):
|
||||
raise TypeError("end must be None or a string")
|
||||
if kwargs:
|
||||
raise TypeError("invalid keyword arguments to print()")
|
||||
if not want_unicode:
|
||||
for arg in args:
|
||||
if isinstance(arg, unicode):
|
||||
want_unicode = True
|
||||
break
|
||||
if want_unicode:
|
||||
newline = unicode("\n")
|
||||
space = unicode(" ")
|
||||
else:
|
||||
newline = "\n"
|
||||
space = " "
|
||||
if sep is None:
|
||||
sep = space
|
||||
if end is None:
|
||||
end = newline
|
||||
for i, arg in enumerate(args):
|
||||
if i:
|
||||
write(sep)
|
||||
write(arg)
|
||||
write(end)
|
||||
|
||||
_add_doc(reraise, """Reraise an exception.""")
|
||||
|
||||
|
||||
def with_metaclass(meta, base=object):
|
||||
"""Create a base class with a metaclass."""
|
||||
return meta("NewBase", (base,), {})
|
||||
580
awx/lib/site-packages/d2to1/util.py
Normal file
580
awx/lib/site-packages/d2to1/util.py
Normal file
@@ -0,0 +1,580 @@
|
||||
"""The code in this module is mostly copy/pasted out of the distutils2 source
|
||||
code, as recommended by Tarek Ziade. As such, it may be subject to some change
|
||||
as distutils2 development continues, and will have to be kept up to date.
|
||||
|
||||
I didn't want to use it directly from distutils2 itself, since I do not want it
|
||||
to be an installation dependency for our packages yet--it is still too unstable
|
||||
(the latest version on PyPI doesn't even install).
|
||||
"""
|
||||
|
||||
# These first two imports are not used, but are needed to get around an
|
||||
# irritating Python bug that can crop up when using ./setup.py test.
|
||||
# See: http://www.eby-sarna.com/pipermail/peak/2010-May/003355.html
|
||||
try:
|
||||
import multiprocessing
|
||||
except ImportError:
|
||||
pass
|
||||
import logging
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
import distutils.ccompiler
|
||||
|
||||
from distutils import log
|
||||
from distutils.errors import (DistutilsOptionError, DistutilsModuleError,
|
||||
DistutilsFileError)
|
||||
from setuptools.command.egg_info import manifest_maker
|
||||
from setuptools.dist import Distribution
|
||||
from setuptools.extension import Extension
|
||||
|
||||
from .extern.six import moves as m
|
||||
RawConfigParser = m.configparser.RawConfigParser
|
||||
|
||||
|
||||
# A simplified RE for this; just checks that the line ends with version
|
||||
# predicates in ()
|
||||
_VERSION_SPEC_RE = re.compile(r'\s*(.*?)\s*\((.*)\)\s*$')
|
||||
|
||||
|
||||
# Mappings from setup() keyword arguments to setup.cfg options;
|
||||
# The values are (section, option) tuples, or simply (section,) tuples if
|
||||
# the option has the same name as the setup() argument
|
||||
D1_D2_SETUP_ARGS = {
|
||||
"name": ("metadata",),
|
||||
"version": ("metadata",),
|
||||
"author": ("metadata",),
|
||||
"author_email": ("metadata",),
|
||||
"maintainer": ("metadata",),
|
||||
"maintainer_email": ("metadata",),
|
||||
"url": ("metadata", "home_page"),
|
||||
"description": ("metadata", "summary"),
|
||||
"keywords": ("metadata",),
|
||||
"long_description": ("metadata", "description"),
|
||||
"download-url": ("metadata",),
|
||||
"classifiers": ("metadata", "classifier"),
|
||||
"platforms": ("metadata", "platform"), # **
|
||||
"license": ("metadata",),
|
||||
# Use setuptools install_requires, not
|
||||
# broken distutils requires
|
||||
"install_requires": ("metadata", "requires_dist"),
|
||||
"setup_requires": ("metadata", "setup_requires_dist"),
|
||||
"provides": ("metadata", "provides_dist"), # **
|
||||
"obsoletes": ("metadata", "obsoletes_dist"), # **
|
||||
"package_dir": ("files", 'packages_root'),
|
||||
"packages": ("files",),
|
||||
"package_data": ("files",),
|
||||
"data_files": ("files",),
|
||||
"scripts": ("files",),
|
||||
"py_modules": ("files", "modules"), # **
|
||||
"cmdclass": ("global", "commands"),
|
||||
# Not supported in distutils2, but provided for
|
||||
# backwards compatibility with setuptools
|
||||
"use_2to3": ("backwards_compat", "use_2to3"),
|
||||
"zip_safe": ("backwards_compat", "zip_safe"),
|
||||
"tests_require": ("backwards_compat", "tests_require"),
|
||||
"dependency_links": ("backwards_compat",),
|
||||
"include_package_data": ("backwards_compat",),
|
||||
}
|
||||
|
||||
# setup() arguments that can have multiple values in setup.cfg
|
||||
MULTI_FIELDS = ("classifiers",
|
||||
"platforms",
|
||||
"install_requires",
|
||||
"provides",
|
||||
"obsoletes",
|
||||
"packages",
|
||||
"package_data",
|
||||
"data_files",
|
||||
"scripts",
|
||||
"py_modules",
|
||||
"dependency_links",
|
||||
"setup_requires",
|
||||
"tests_require",
|
||||
"cmdclass")
|
||||
|
||||
# setup() arguments that contain boolean values
|
||||
BOOL_FIELDS = ("use_2to3", "zip_safe", "include_package_data")
|
||||
|
||||
|
||||
CSV_FIELDS = ("keywords",)
|
||||
|
||||
|
||||
log.set_verbosity(log.INFO)
|
||||
|
||||
|
||||
def resolve_name(name):
|
||||
"""Resolve a name like ``module.object`` to an object and return it.
|
||||
|
||||
Raise ImportError if the module or name is not found.
|
||||
"""
|
||||
|
||||
parts = name.split('.')
|
||||
cursor = len(parts) - 1
|
||||
module_name = parts[:cursor]
|
||||
attr_name = parts[-1]
|
||||
|
||||
while cursor > 0:
|
||||
try:
|
||||
ret = __import__('.'.join(module_name), fromlist=[attr_name])
|
||||
break
|
||||
except ImportError:
|
||||
if cursor == 0:
|
||||
raise
|
||||
cursor -= 1
|
||||
module_name = parts[:cursor]
|
||||
attr_name = parts[cursor]
|
||||
ret = ''
|
||||
|
||||
for part in parts[cursor:]:
|
||||
try:
|
||||
ret = getattr(ret, part)
|
||||
except AttributeError:
|
||||
raise ImportError(name)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def cfg_to_args(path='setup.cfg'):
|
||||
""" Distutils2 to distutils1 compatibility util.
|
||||
|
||||
This method uses an existing setup.cfg to generate a dictionary of
|
||||
keywords that can be used by distutils.core.setup(kwargs**).
|
||||
|
||||
:param file:
|
||||
The setup.cfg path.
|
||||
:raises DistutilsFileError:
|
||||
When the setup.cfg file is not found.
|
||||
|
||||
"""
|
||||
|
||||
# The method source code really starts here.
|
||||
parser = RawConfigParser()
|
||||
if not os.path.exists(path):
|
||||
raise DistutilsFileError("file '%s' does not exist" %
|
||||
os.path.abspath(path))
|
||||
parser.read(path)
|
||||
config = {}
|
||||
for section in parser.sections():
|
||||
config[section] = dict(parser.items(section))
|
||||
|
||||
# Run setup_hooks, if configured
|
||||
setup_hooks = has_get_option(config, 'global', 'setup_hooks')
|
||||
package_dir = has_get_option(config, 'files', 'packages_root')
|
||||
|
||||
# Add the source package directory to sys.path in case it contains
|
||||
# additional hooks, and to make sure it's on the path before any existing
|
||||
# installations of the package
|
||||
if package_dir:
|
||||
package_dir = os.path.abspath(package_dir)
|
||||
sys.path.insert(0, package_dir)
|
||||
|
||||
try:
|
||||
if setup_hooks:
|
||||
setup_hooks = split_multiline(setup_hooks)
|
||||
for hook in setup_hooks:
|
||||
hook_fn = resolve_name(hook)
|
||||
try :
|
||||
hook_fn(config)
|
||||
except SystemExit:
|
||||
log.error('setup hook %s terminated the installation')
|
||||
except:
|
||||
e = sys.exc_info()[1]
|
||||
log.error('setup hook %s raised exception: %s\n' %
|
||||
(hook, e))
|
||||
log.error(traceback.format_exc())
|
||||
sys.exit(1)
|
||||
|
||||
kwargs = setup_cfg_to_setup_kwargs(config)
|
||||
|
||||
register_custom_compilers(config)
|
||||
|
||||
ext_modules = get_extension_modules(config)
|
||||
if ext_modules:
|
||||
kwargs['ext_modules'] = ext_modules
|
||||
|
||||
entry_points = get_entry_points(config)
|
||||
if entry_points:
|
||||
kwargs['entry_points'] = entry_points
|
||||
|
||||
wrap_commands(kwargs)
|
||||
|
||||
# Handle the [files]/extra_files option
|
||||
extra_files = has_get_option(config, 'files', 'extra_files')
|
||||
if extra_files:
|
||||
extra_files = split_multiline(extra_files)
|
||||
# Let's do a sanity check
|
||||
for filename in extra_files:
|
||||
if not os.path.exists(filename):
|
||||
raise DistutilsFileError(
|
||||
'%s from the extra_files option in setup.cfg does not '
|
||||
'exist' % filename)
|
||||
# Unfortunately the only really sensible way to do this is to
|
||||
# monkey-patch the manifest_maker class
|
||||
@monkeypatch_method(manifest_maker)
|
||||
def add_defaults(self, extra_files=extra_files, log=log):
|
||||
log.info('[d2to1] running patched manifest_maker command '
|
||||
'with extra_files support')
|
||||
add_defaults._orig(self)
|
||||
self.filelist.extend(extra_files)
|
||||
|
||||
finally:
|
||||
# Perform cleanup if any paths were added to sys.path
|
||||
if package_dir:
|
||||
sys.path.pop(0)
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def setup_cfg_to_setup_kwargs(config):
|
||||
"""Processes the setup.cfg options and converts them to arguments accepted
|
||||
by setuptools' setup() function.
|
||||
"""
|
||||
|
||||
kwargs = {}
|
||||
|
||||
for arg in D1_D2_SETUP_ARGS:
|
||||
if len(D1_D2_SETUP_ARGS[arg]) == 2:
|
||||
# The distutils field name is different than distutils2's.
|
||||
section, option = D1_D2_SETUP_ARGS[arg]
|
||||
|
||||
elif len(D1_D2_SETUP_ARGS[arg]) == 1:
|
||||
# The distutils field name is the same thant distutils2's.
|
||||
section = D1_D2_SETUP_ARGS[arg][0]
|
||||
option = arg
|
||||
|
||||
in_cfg_value = has_get_option(config, section, option)
|
||||
if not in_cfg_value:
|
||||
# There is no such option in the setup.cfg
|
||||
if arg == "long_description":
|
||||
in_cfg_value = has_get_option(config, section,
|
||||
"description_file")
|
||||
if in_cfg_value:
|
||||
in_cfg_value = split_multiline(in_cfg_value)
|
||||
value = ''
|
||||
for filename in in_cfg_value:
|
||||
description_file = open(filename)
|
||||
try:
|
||||
value += description_file.read().strip() + '\n\n'
|
||||
finally:
|
||||
description_file.close()
|
||||
in_cfg_value = value
|
||||
else:
|
||||
continue
|
||||
|
||||
if arg in CSV_FIELDS:
|
||||
in_cfg_value = split_csv(in_cfg_value)
|
||||
if arg in MULTI_FIELDS:
|
||||
in_cfg_value = split_multiline(in_cfg_value)
|
||||
elif arg in BOOL_FIELDS:
|
||||
# Provide some flexibility here...
|
||||
if in_cfg_value.lower() in ('true', 't', '1', 'yes', 'y'):
|
||||
in_cfg_value = True
|
||||
else:
|
||||
in_cfg_value = False
|
||||
|
||||
if in_cfg_value:
|
||||
if arg in ('install_requires', 'tests_require'):
|
||||
# Replaces PEP345-style version specs with the sort expected by
|
||||
# setuptools
|
||||
in_cfg_value = [_VERSION_SPEC_RE.sub(r'\1\2', pred)
|
||||
for pred in in_cfg_value]
|
||||
elif arg == 'package_dir':
|
||||
in_cfg_value = {'': in_cfg_value}
|
||||
elif arg in ('package_data', 'data_files'):
|
||||
data_files = {}
|
||||
firstline = True
|
||||
prev = None
|
||||
for line in in_cfg_value:
|
||||
if '=' in line:
|
||||
key, value = line.split('=', 1)
|
||||
key, value = (key.strip(), value.strip())
|
||||
if key in data_files:
|
||||
# Multiple duplicates of the same package name;
|
||||
# this is for backwards compatibility of the old
|
||||
# format prior to d2to1 0.2.6.
|
||||
prev = data_files[key]
|
||||
prev.extend(value.split())
|
||||
else:
|
||||
prev = data_files[key.strip()] = value.split()
|
||||
elif firstline:
|
||||
raise DistutilsOptionError(
|
||||
'malformed package_data first line %r (misses '
|
||||
'"=")' % line)
|
||||
else:
|
||||
prev.extend(line.strip().split())
|
||||
firstline = False
|
||||
if arg == 'data_files':
|
||||
# the data_files value is a pointlessly different structure
|
||||
# from the package_data value
|
||||
data_files = list(data_files.items())
|
||||
in_cfg_value = data_files
|
||||
elif arg == 'cmdclass':
|
||||
cmdclass = {}
|
||||
dist = Distribution()
|
||||
for cls in in_cfg_value:
|
||||
cls = resolve_name(cls)
|
||||
cmd = cls(dist)
|
||||
cmdclass[cmd.get_command_name()] = cls
|
||||
in_cfg_value = cmdclass
|
||||
|
||||
kwargs[arg] = in_cfg_value
|
||||
|
||||
return kwargs
|
||||
|
||||
|
||||
def register_custom_compilers(config):
|
||||
"""Handle custom compilers; this has no real equivalent in distutils, where
|
||||
additional compilers could only be added programmatically, so we have to
|
||||
hack it in somehow.
|
||||
"""
|
||||
|
||||
compilers = has_get_option(config, 'global', 'compilers')
|
||||
if compilers:
|
||||
compilers = split_multiline(compilers)
|
||||
for compiler in compilers:
|
||||
compiler = resolve_name(compiler)
|
||||
|
||||
# In distutils2 compilers these class attributes exist; for
|
||||
# distutils1 we just have to make something up
|
||||
if hasattr(compiler, 'name'):
|
||||
name = compiler.name
|
||||
else:
|
||||
name = compiler.__name__
|
||||
if hasattr(compiler, 'description'):
|
||||
desc = compiler.description
|
||||
else:
|
||||
desc = 'custom compiler %s' % name
|
||||
|
||||
module_name = compiler.__module__
|
||||
# Note; this *will* override built in compilers with the same name
|
||||
# TODO: Maybe display a warning about this?
|
||||
cc = distutils.ccompiler.compiler_class
|
||||
cc[name] = (module_name, compiler.__name__, desc)
|
||||
|
||||
# HACK!!!! Distutils assumes all compiler modules are in the
|
||||
# distutils package
|
||||
sys.modules['distutils.' + module_name] = sys.modules[module_name]
|
||||
|
||||
|
||||
def get_extension_modules(config):
|
||||
"""Handle extension modules"""
|
||||
|
||||
EXTENSION_FIELDS = ("sources",
|
||||
"include_dirs",
|
||||
"define_macros",
|
||||
"undef_macros",
|
||||
"library_dirs",
|
||||
"libraries",
|
||||
"runtime_library_dirs",
|
||||
"extra_objects",
|
||||
"extra_compile_args",
|
||||
"extra_link_args",
|
||||
"export_symbols",
|
||||
"swig_opts",
|
||||
"depends")
|
||||
|
||||
ext_modules = []
|
||||
for section in config:
|
||||
if ':' in section:
|
||||
labels = section.split(':', 1)
|
||||
else:
|
||||
# Backwards compatibility for old syntax; don't use this though
|
||||
labels = section.split('=', 1)
|
||||
labels = [l.strip() for l in labels]
|
||||
if (len(labels) == 2) and (labels[0] == 'extension'):
|
||||
ext_args = {}
|
||||
for field in EXTENSION_FIELDS:
|
||||
value = has_get_option(config, section, field)
|
||||
# All extension module options besides name can have multiple
|
||||
# values
|
||||
if not value:
|
||||
continue
|
||||
value = split_multiline(value)
|
||||
if field == 'define_macros':
|
||||
macros = []
|
||||
for macro in value:
|
||||
macro = macro.split('=', 1)
|
||||
if len(macro) == 1:
|
||||
macro = (macro[0].strip(), None)
|
||||
else:
|
||||
macro = (macro[0].strip(), macro[1].strip())
|
||||
macros.append(macro)
|
||||
value = macros
|
||||
ext_args[field] = value
|
||||
if ext_args:
|
||||
if 'name' not in ext_args:
|
||||
ext_args['name'] = labels[1]
|
||||
ext_modules.append(Extension(ext_args.pop('name'),
|
||||
**ext_args))
|
||||
return ext_modules
|
||||
|
||||
|
||||
def get_entry_points(config):
|
||||
"""Process the [entry_points] section of setup.cfg to handle setuptools
|
||||
entry points. This is, of course, not a standard feature of
|
||||
distutils2/packaging, but as there is not currently a standard alternative
|
||||
in packaging, we provide support for them.
|
||||
"""
|
||||
|
||||
if not 'entry_points' in config:
|
||||
return {}
|
||||
|
||||
return dict((option, split_multiline(value))
|
||||
for option, value in config['entry_points'].items())
|
||||
|
||||
|
||||
def wrap_commands(kwargs):
|
||||
dist = Distribution()
|
||||
|
||||
# This should suffice to get the same config values and command classes
|
||||
# that the actual Distribution will see (not counting cmdclass, which is
|
||||
# handled below)
|
||||
dist.parse_config_files()
|
||||
|
||||
for cmd, _ in dist.get_command_list():
|
||||
hooks = {}
|
||||
for opt, val in dist.get_option_dict(cmd).items():
|
||||
val = val[1]
|
||||
if opt.startswith('pre_hook.') or opt.startswith('post_hook.'):
|
||||
hook_type, alias = opt.split('.', 1)
|
||||
hook_dict = hooks.setdefault(hook_type, {})
|
||||
hook_dict[alias] = val
|
||||
if not hooks:
|
||||
continue
|
||||
|
||||
if 'cmdclass' in kwargs and cmd in kwargs['cmdclass']:
|
||||
cmdclass = kwargs['cmdclass'][cmd]
|
||||
else:
|
||||
cmdclass = dist.get_command_class(cmd)
|
||||
|
||||
new_cmdclass = wrap_command(cmd, cmdclass, hooks)
|
||||
kwargs.setdefault('cmdclass', {})[cmd] = new_cmdclass
|
||||
|
||||
|
||||
def wrap_command(cmd, cmdclass, hooks):
|
||||
def run(self, cmdclass=cmdclass):
|
||||
self.run_command_hooks('pre_hook')
|
||||
cmdclass.run(self)
|
||||
self.run_command_hooks('post_hook')
|
||||
|
||||
return type(cmd, (cmdclass, object),
|
||||
{'run': run, 'run_command_hooks': run_command_hooks,
|
||||
'pre_hook': hooks.get('pre_hook'),
|
||||
'post_hook': hooks.get('post_hook')})
|
||||
|
||||
|
||||
def run_command_hooks(cmd_obj, hook_kind):
|
||||
"""Run hooks registered for that command and phase.
|
||||
|
||||
*cmd_obj* is a finalized command object; *hook_kind* is either
|
||||
'pre_hook' or 'post_hook'.
|
||||
"""
|
||||
|
||||
if hook_kind not in ('pre_hook', 'post_hook'):
|
||||
raise ValueError('invalid hook kind: %r' % hook_kind)
|
||||
|
||||
hooks = getattr(cmd_obj, hook_kind, None)
|
||||
|
||||
if hooks is None:
|
||||
return
|
||||
|
||||
for hook in hooks.values():
|
||||
if isinstance(hook, str):
|
||||
try:
|
||||
hook_obj = resolve_name(hook)
|
||||
except ImportError:
|
||||
err = sys.exc_info()[1] # For py3k
|
||||
raise DistutilsModuleError('cannot find hook %s: %s' %
|
||||
(hook,err))
|
||||
else:
|
||||
hook_obj = hook
|
||||
|
||||
if not hasattr(hook_obj, '__call__'):
|
||||
raise DistutilsOptionError('hook %r is not callable' % hook)
|
||||
|
||||
log.info('running %s %s for command %s',
|
||||
hook_kind, hook, cmd_obj.get_command_name())
|
||||
|
||||
try :
|
||||
hook_obj(cmd_obj)
|
||||
except:
|
||||
e = sys.exc_info()[1]
|
||||
log.error('hook %s raised exception: %s\n' % (hook, e))
|
||||
log.error(traceback.format_exc())
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def has_get_option(config, section, option):
|
||||
if section in config and option in config[section]:
|
||||
return config[section][option]
|
||||
elif section in config and option.replace('_', '-') in config[section]:
|
||||
return config[section][option.replace('_', '-')]
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def split_multiline(value):
|
||||
"""Special behaviour when we have a multi line options"""
|
||||
|
||||
value = [element for element in
|
||||
(line.strip() for line in value.split('\n'))
|
||||
if element]
|
||||
return value
|
||||
|
||||
|
||||
def split_csv(value):
|
||||
"""Special behaviour when we have a comma separated options"""
|
||||
|
||||
value = [element for element in
|
||||
(chunk.strip() for chunk in value.split(','))
|
||||
if element]
|
||||
return value
|
||||
|
||||
|
||||
def monkeypatch_method(cls):
|
||||
"""A function decorator to monkey-patch a method of the same name on the
|
||||
given class.
|
||||
"""
|
||||
|
||||
def wrapper(func):
|
||||
orig = getattr(cls, func.__name__, None)
|
||||
if orig and not hasattr(orig, '_orig'): # Already patched
|
||||
setattr(func, '_orig', orig)
|
||||
setattr(cls, func.__name__, func)
|
||||
return func
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
# The following classes are used to hack Distribution.command_options a bit
|
||||
class DefaultGetDict(defaultdict):
|
||||
"""Like defaultdict, but the get() method also sets and returns the default
|
||||
value.
|
||||
"""
|
||||
|
||||
def get(self, key, default=None):
|
||||
if default is None:
|
||||
default = self.default_factory()
|
||||
return super(DefaultGetDict, self).setdefault(key, default)
|
||||
|
||||
|
||||
class IgnoreDict(dict):
|
||||
"""A dictionary that ignores any insertions in which the key is a string
|
||||
matching any string in `ignore`. The ignore list can also contain wildcard
|
||||
patterns using '*'.
|
||||
"""
|
||||
|
||||
def __init__(self, ignore):
|
||||
self.__ignore = re.compile(r'(%s)' % ('|'.join(
|
||||
[pat.replace('*', '.*')
|
||||
for pat in ignore])))
|
||||
|
||||
def __setitem__(self, key, val):
|
||||
if self.__ignore.match(key):
|
||||
return
|
||||
super(IgnoreDict, self).__setitem__(key, val)
|
||||
161
awx/lib/site-packages/d2to1/zestreleaser.py
Normal file
161
awx/lib/site-packages/d2to1/zestreleaser.py
Normal file
@@ -0,0 +1,161 @@
|
||||
"""zest.releaser entry points to support projects using distutils2-like
|
||||
setup.cfg files. The only actual functionality this adds is to update the
|
||||
version option in a setup.cfg file, if it exists. If setup.cfg does not exist,
|
||||
or does not contain a version option, then this does nothing.
|
||||
|
||||
TODO: d2to1 theoretically supports using a different filename for setup.cfg;
|
||||
this does not support that. We could hack in support, though I'm not sure how
|
||||
useful the original functionality is to begin with (and it might be removed) so
|
||||
we ignore that for now.
|
||||
|
||||
TODO: There exists a proposal
|
||||
(http://mail.python.org/pipermail/distutils-sig/2011-March/017628.html) to add
|
||||
a 'version-from-file' option (or something of the like) to distutils2; if this
|
||||
is added then support for it should be included here as well.
|
||||
"""
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from .extern.six import print_
|
||||
from .extern.six import moves as m
|
||||
ConfigParser = m.configparser.ConfigParser
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
def update_setupcfg_version(filename, version):
|
||||
"""Opens the given setup.cfg file, locates the version option in the
|
||||
[metadata] section, updates it to the new version.
|
||||
"""
|
||||
|
||||
setup_cfg = open(filename).readlines()
|
||||
current_section = None
|
||||
updated = False
|
||||
|
||||
for idx, line in enumerate(setup_cfg):
|
||||
m = ConfigParser.SECTCRE.match(line)
|
||||
if m:
|
||||
if current_section == 'metadata':
|
||||
# We already parsed the entire metadata section without finding
|
||||
# a version line, and are now moving into a new section
|
||||
break
|
||||
current_section = m.group('header')
|
||||
continue
|
||||
|
||||
if '=' not in line:
|
||||
continue
|
||||
|
||||
opt, val = line.split('=', 1)
|
||||
opt, val = opt.strip(), val.strip()
|
||||
if current_section == 'metadata' and opt == 'version':
|
||||
setup_cfg[idx] = 'version = %s\n' % version
|
||||
updated = True
|
||||
break
|
||||
|
||||
if updated:
|
||||
open(filename, 'w').writelines(setup_cfg)
|
||||
logger.info("Set %s's version to %r" % (os.path.basename(filename),
|
||||
version))
|
||||
|
||||
|
||||
def prereleaser_middle(data):
|
||||
filename = os.path.join(data['workingdir'], 'setup.cfg')
|
||||
if os.path.exists(filename):
|
||||
update_setupcfg_version(filename, data['new_version'])
|
||||
|
||||
|
||||
def releaser_middle(data):
|
||||
"""
|
||||
releaser.middle hook to monkey-patch zest.releaser to support signed
|
||||
tagging--currently this is the only way to do this. Also monkey-patches to
|
||||
disable an annoyance where zest.releaser only creates .zip source
|
||||
distributions. This is supposedly a workaround for a bug in Python 2.4,
|
||||
but we don't care about Python 2.4.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from zest.releaser.git import Git
|
||||
from zest.releaser.release import Releaser
|
||||
|
||||
# Copied verbatim from zest.releaser, but with the cmd string modified to
|
||||
# use the -s option to create a signed tag
|
||||
def _my_create_tag(self, version):
|
||||
msg = "Tagging %s" % (version,)
|
||||
cmd = 'git tag -s %s -m "%s"' % (version, msg)
|
||||
if os.path.isdir('.git/svn'):
|
||||
print_("\nEXPERIMENTAL support for git-svn tagging!\n")
|
||||
cur_branch = open('.git/HEAD').read().strip().split('/')[-1]
|
||||
print_("You are on branch %s." % (cur_branch,))
|
||||
if cur_branch != 'master':
|
||||
print_("Only the master branch is supported for git-svn "
|
||||
"tagging.")
|
||||
print_("Please tag yourself.")
|
||||
print_("'git tag' needs to list tag named %s." % (version,))
|
||||
sys.exit()
|
||||
cmd = [cmd]
|
||||
local_head = open('.git/refs/heads/master').read()
|
||||
trunk = open('.git/refs/remotes/trunk').read()
|
||||
if local_head != trunk:
|
||||
print_("Your local master diverges from trunk.\n")
|
||||
# dcommit before local tagging
|
||||
cmd.insert(0, 'git svn dcommit')
|
||||
# create tag in svn
|
||||
cmd.append('git svn tag -m "%s" %s' % (msg, version))
|
||||
return cmd
|
||||
|
||||
# Similarly copied from zer.releaser to support use of 'v' in front
|
||||
# of the version number
|
||||
def _my_make_tag(self):
|
||||
from zest.releaser import utils
|
||||
from os import system
|
||||
|
||||
if self.data['tag_already_exists']:
|
||||
return
|
||||
cmds = self.vcs.cmd_create_tag(self.data['version'])
|
||||
if not isinstance(cmds, list):
|
||||
cmds = [cmds]
|
||||
if len(cmds) == 1:
|
||||
print_("Tag needed to proceed, you can use the following command:")
|
||||
for cmd in cmds:
|
||||
print_(cmd)
|
||||
if utils.ask("Run this command"):
|
||||
print_(system(cmd))
|
||||
else:
|
||||
# all commands are needed in order to proceed normally
|
||||
print_("Please create a tag for %s yourself and rerun." % \
|
||||
(self.data['version'],))
|
||||
sys.exit()
|
||||
if not self.vcs.tag_exists('v' + self.data['version']):
|
||||
print_("\nFailed to create tag %s!" % (self.data['version'],))
|
||||
sys.exit()
|
||||
|
||||
# Normally all this does is to return '--formats=zip', which is currently
|
||||
# hard-coded as an option to always add to the sdist command; they ought to
|
||||
# make this actually optional
|
||||
def _my_sdist_options(self):
|
||||
return ''
|
||||
|
||||
Git.cmd_create_tag = _my_create_tag
|
||||
Releaser._make_tag = _my_make_tag
|
||||
Releaser._sdist_options = _my_sdist_options
|
||||
|
||||
|
||||
def postreleaser_before(data):
|
||||
"""
|
||||
Fix the irritating .dev0 default appended to new development versions by
|
||||
zest.releaser to just append ".dev" without the "0".
|
||||
"""
|
||||
|
||||
data['dev_version_template'] = '%(new_version)s.dev'
|
||||
|
||||
|
||||
def postreleaser_middle(data):
|
||||
filename = os.path.join(data['workingdir'], 'setup.cfg')
|
||||
if os.path.exists(filename):
|
||||
update_setupcfg_version(filename, data['dev_version'])
|
||||
Reference in New Issue
Block a user