Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge master into develop (+fixes) #39

Merged
merged 6 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
repos:
- repo: git://github.com/pre-commit/mirrors-yapf
sha: v0.21.0
sha: v0.24.0
hooks:
- id: yapf
language: system

- repo: git://github.com/guykisel/prospector-mirror
sha: b27f281eb9398fc8504415d7fbdabf119ea8c5e1
- repo: local
hooks:
- id: prospector
language: system

- repo: local
hooks:
types: [file, python]
name: prospector
description: "This hook runs Prospector: https://github.com/landscapeio/prospector"
entry: prospector
- id: travis-linter
name: travis
entry: travis lint
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,useless-object-inheritance

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
13 changes: 9 additions & 4 deletions .travis-tests/host-pkg/reentry_test_host/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
from __future__ import print_function

import click
from py import path as py_path # pylint: disable=no-name-in-module

try:
# prefer the backport for Python <3.5
from pathlib2 import Path
except ImportError:
from pathlib import Path

from reentry import manager
from reentry.config import get_datafile
Expand All @@ -13,18 +18,18 @@
def main(with_noreg):
"""Test automatic scanning / registering"""
entry_point_map = manager.get_entry_map(groups='reentry_test', ep_names=['test-plugin', 'test-noreg', 'builtin'])
data_file = py_path.local(get_datafile())
data_file = Path(get_datafile())

assert entry_point_map, 'The test plugin entry point were not found\nMap:\n{}\n\nData File: {}\n\nContents:\n{}'.format(
manager.get_entry_map(), data_file.strpath, data_file.read())
manager.get_entry_map(), str(data_file), data_file.read_text())

try:
test_entry_point = entry_point_map['reentry_test']['test-plugin']
builtin_entry_point = entry_point_map['reentry_test']['builtin']
if with_noreg:
noreg_entry_point = entry_point_map['reentry_test']['test-noreg']
except Exception as err:
print('datafile: {}'.format(data_file.strpath))
print('datafile: {}'.format(str(data_file)))
print('\nCurrent relevant entry point map:\n\n')
print(manager.format_map(entry_point_map))
print('\n')
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
include README.rst
include LICENSE
include setup.json
recursive-include reentry tests/*json
42 changes: 25 additions & 17 deletions ops/update_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import contextlib
import subprocess
try:
# prefer the backport for Python <3.5
from pathlib2 import Path
except ImportError:
from pathlib import Path
import collections

from packaging import version


Expand Down Expand Up @@ -44,36 +47,44 @@ class VersionUpdater(object):

version_pat = re.compile(r'\d+.\d+.\d+(-(alpha|beta|rc)(.\d+){0,3}){0,1}')
init_version_pat = re.compile(r'(__version__ = )([\'"])(.*?)([\'"])', re.DOTALL | re.MULTILINE)
setup_version_pat = re.compile(r'(VERSION = )([\'"])(.*?)([\'"])', re.DOTALL | re.MULTILINE)
replace_tmpl = r'\1\g<2>{}\4'

def __init__(self):
"""Initialize with documents that should be kept up to date and actual version."""
self.top_level_init = Path(subpath('reentry', '__init__.py'))
self.setup_py = Path(subpath('setup.py'))
self.setup_json = Path(subpath('setup.json'))
self.version = self.get_version()

def write_to_init(self):
init_content = self.top_level_init.read_text()
self.top_level_init.write_text(re.sub(self.init_version_pat, self.new_version_str, init_content, re.DOTALL | re.MULTILINE))

def write_to_setup(self):
"""Write the updated version number to the setup file."""
setup_content = self.setup_py.read_text()
new_content = re.sub(self.setup_version_pat, self.new_version_str, setup_content, re.DOTALL | re.MULTILINE)
self.setup_py.write_text(new_content)
"""Write the updated version number to setup.json."""
with open(str(self.setup_json), 'r') as setup_fo:
# preserve order
setup = json.load(setup_fo, object_pairs_hook=collections.OrderedDict)

setup['version'] = str(self.version)
with open(str(self.setup_json), 'w') as setup_fo:
json.dump(setup, setup_fo, indent=4, separators=(',', ': '))

@property
def new_version_str(self):
return self.replace_tmpl.format(str(self.version))

@property
def setup_version(self):
"""Grab the parsed version from the setup file."""
match = re.search(self.setup_version_pat, self.setup_py.read_text())
if not match:
raise AttributeError('No global variable VERSION found in setup.py')
return version.parse(match.groups()[2])
"""Grab the parsed version from setup.json."""
with open(str(self.setup_json), 'r') as setup_fo:
setup = json.load(setup_fo)

try:
version_string = setup['version']
except KeyError:
raise AttributeError('No version found in setup.json')

return version.parse(version_string)

@property
def init_version(self):
Expand All @@ -85,17 +96,14 @@ def init_version(self):

@property
def tag_version(self):
"""Get the current version number from ``git describe``, fall back to setup.py."""
"""Get the current version number from ``git describe``, fall back to setup.json."""
try:
describe_byte_string = subprocess.check_output(['git', 'describe', '--tags', '--match', 'v*.*.*'])
match = re.search(self.version_pat, describe_byte_string.decode(encoding='UTF-8'))
version_string = match.string[match.pos:match.end()]
return version.parse(version_string)
except subprocess.CalledProcessError:
with self.setup_py.open() as setup_fo:
setup = json.load(setup_fo)
version_string = setup['version']

return version.parse(version_string)
return self.setup_version

def get_version(self):
return max(self.setup_version, self.init_version, self.tag_version)
Expand Down
2 changes: 1 addition & 1 deletion reentry/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Expose the default manager"""
from reentry.default_manager import DEFAULT_MANAGER as manager

__version__ = '1.2.1'
__version__ = '1.2.2'
__all__ = ['manager']
11 changes: 9 additions & 2 deletions reentry/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def find_config():
"""
rc_file = Path.home().joinpath('.reentryrc')
config_file = _get_default_config_dir().joinpath('config')
# pylint: disable=no-else-return
if rc_file.exists(): # pylint: disable=no-member
return rc_file
elif config_file.exists(): # pylint: disable=no-member
Expand All @@ -37,6 +38,7 @@ def find_config():

def make_config_parser(*args, **kwargs):
"""Get the correct ConfigParser class depending on python version."""
# pylint: disable=no-else-return
if six.PY2:
return configparser.SafeConfigParser(*args, **kwargs)
elif six.PY3:
Expand All @@ -62,7 +64,10 @@ def get_config(config_file_name=str(find_config())):


def make_data_file_name():
"""Find the path to the reentry executable and mangle it into a file name."""
"""Find the path to the reentry executable and mangle it into a file name.

Note: In order to avoid long filenames (e.g. on conda forge), the relevant info is hashed.
"""
sep = os.path.sep
python_bin_dir = str(Path(sys.executable).resolve().parent)
py_version = 'UNKNOWN'
Expand All @@ -71,7 +76,9 @@ def make_data_file_name():
elif six.PY3:
py_version = 'PY3'
file_name = python_bin_dir.lstrip(sep).replace(sep, '.').replace('.', '_') + '_' + py_version
return file_name

file_name_hash = hashlib.sha256(file_name.encode('utf-8'))
return file_name_hash.hexdigest()


def hashed_data_file_name():
Expand Down
15 changes: 9 additions & 6 deletions reentry/jsonbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,16 +116,18 @@ def get_ep(self, group, name, dist=None):
spc = self.get_ep(group, name, dist=dist_name)
if spc:
specs.append(spc)
# pylint: disable=no-else-return
if len(specs) > 1:
return specs
elif len(specs) == 1:
return specs[0]
else:
distribution_map = self._epmap.get(dist, {})
group_map = distribution_map.get(group, {})
spec = group_map.get(name)
if spec:
return EntryPoint.parse(spec)

distribution_map = self._epmap.get(dist, {})
group_map = distribution_map.get(group, {})
spec = group_map.get(name)
if spec:
return EntryPoint.parse(spec)

return None

def get_dist_names(self):
Expand Down Expand Up @@ -284,6 +286,7 @@ def _flat_entry_points(self):
def _listify(sequence_or_name):
"""Wrap a single name in a list, leave sequences and None unchanged"""
from collections import Sequence
# pylint: disable=no-else-return
if sequence_or_name is None:
return None
elif not isinstance(sequence_or_name, Sequence) or isinstance(sequence_or_name, six.string_types):
Expand Down
2 changes: 2 additions & 0 deletions reentry/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# pylint: disable=unused-import,redefined-outer-name
"""Unit tests for config tools."""
try:
# prefer the backport for Python <3.5
from pathlib2 import Path
except ImportError:
from pathlib import Path

import pytest # pylint: disable=unused-import
import six
from six.moves import configparser
Expand Down
48 changes: 48 additions & 0 deletions setup.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "reentry",
"version": "1.2.2",
"author": "Rico Haeuselmann",
"license": "MIT License",
"description": "A plugin manager based on setuptools entry points mechanism",
"entry_points": {
"distutils.setup_keywords": [
"reentry_register = reentry.hooks:register_dist",
"reentry_scan = reentry.hooks:scan_for_installed"
],
"console_scripts": [
"reentry = reentry.cli:reentry"
],
"test_entry_points": [
"test = reentry.cli:reentry"
]
},
"classifiers": [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
"Development Status :: 5 - Production/Stable",
"Environment :: Plugins",
"Intended Audience :: Developers",
"Topic :: Software Development"
],
"install_requires": [
"setuptools >= 36.2",
"click",
"six",
"pathlib2; python_version < '3.5'"
],
"extras_require": {
"dev": [
"pre-commit",
"prospector==0.12.11",
"pylint",
"flake8",
"pytest",
"yapf",
"coverage",
"pytest-cov",
"tox",
"packaging"
]
}
}
32 changes: 9 additions & 23 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,20 @@
"""
from os import path
from setuptools import setup, find_packages
import json

README_PATH = path.join(path.dirname(path.abspath(__file__)), 'README.rst')
with open(README_PATH, 'r') as readme:
LONG_DESCRIPTION = readme.read()
JSON_PATH = path.join(path.dirname(path.abspath(__file__)), 'setup.json')

VERSION = '1.2.1'
# Provide static information in setup.json
# such that it can be discovered automatically
with open(JSON_PATH, 'r') as info:
kwargs = json.load(info)

setup(
name='reentry',
version=VERSION,
author='Rico Haeuselmann',
license='MIT License',
description='A plugin manager based on setuptools entry points mechanism',
long_description=LONG_DESCRIPTION,
packages=find_packages(),
include_package_data=True,
package_data={'': ['js_data', 'README.rst']},
entry_points={
'distutils.setup_keywords': ['reentry_register = reentry.hooks:register_dist', 'reentry_scan = reentry.hooks:scan_for_installed'],
'console_scripts': ['reentry = reentry.cli:reentry'],
'test_entry_points': ['test = reentry.cli:reentry']
},
classifiers=[
'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3',
'Development Status :: 5 - Production/Stable', 'Environment :: Plugins', 'Intended Audience :: Developers',
'Topic :: Software Development'
],
install_requires=['setuptools >= 36.2', 'click', 'six', 'pathlib2 ; python_version<"3.5"'],
extras_require={
'dev': ['pre-commit', 'prospector', 'pylint', 'flake8', 'pytest', 'yapf', 'coverage', 'pytest-cov', 'tox', 'packaging']
})
long_description=open(README_PATH).read(),
long_description_content_type='text/x-rst',
**kwargs)