Completed
Push — master ( b7c2a4...7e68bf )
by Haibao
32s
created

SetupHelper.check_version()   A

Complexity

Conditions 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
1
#!/usr/bin/env python
2
# -*- coding: UTF-8 -*-
3
4
import sys
5
import subprocess
6
import pkg_resources
7
8
9
class SetupHelper (object):
10
    """
11
    SetupHelper streamlines the population of setup() function calls with
12
    contents from __init__.py and README.md.
13
    """
14
15
    def __init__(self, initfile="__init__.py", readmefile="README.md"):
16
        self.author, self.email, self.license, self.version = \
17
                self.get_init(initfile)
18
        self.author = ", ".join(self.author)
19
        self.long_description = self.get_long_description(readmefile)
20
21
    def check_version(self, name, majorv=2, minorv=7):
22
        """ Make sure the package runs on the supported Python version
23
        """
24
        if sys.version_info.major == majorv and sys.version_info.minor != minorv:
25
            sys.stderr.write("ERROR: %s is only for >= Python %d.%d but you are running %d.%d\n" %\
26
                        (name, majorv, minorv, sys.version_info.major, sys.version_info.minor))
27
            sys.exit(1)
28
29
    def get_init(self, filename="__init__.py"):
30
        """ Get various info from the package without importing them
31
        """
32
        import ast
33
34
        with open(filename) as init_file:
35
            module = ast.parse(init_file.read())
36
37
        itr = lambda x: (ast.literal_eval(node.value) for node in ast.walk(module) \
38
            if isinstance(node, ast.Assign) and node.targets[0].id == x)
39
40
        try:
41
            return next(itr("__author__")), \
42
                   next(itr("__email__")), \
43
                   next(itr("__license__")), \
44
                   next(itr("__version__"))
45
        except StopIteration:
46
            raise ValueError("One of author, email, license, or version"
47
                        " cannot be found in {}".format(filename))
48
49
    def missing_requirements(self, specifiers):
50
        """ Find what's missing
51
        """
52
        for specifier in specifiers:
53
            try:
54
                pkg_resources.require(specifier)
55
            except pkg_resources.DistributionNotFound:
56
                yield specifier
57
58
    def install_requirements(self, requires):
59
        """ Install the listed requirements
60
        """
61
        # Temporarily install dependencies required by setup.py before trying to import them.
62
        sys.path[0:0] = ['setup-requires']
63
        pkg_resources.working_set.add_entry('setup-requires')
64
65
        to_install = list(self.missing_requirements(requires))
66
        if to_install:
67
            cmd = [sys.executable, "-m", "pip", "install",
68
                "-t", "setup-requires"] + to_install
69
            subprocess.call(cmd)
70
71
    def get_long_description(self, filename='README.md'):
72
        """ I really prefer Markdown to reStructuredText. PyPi does not.
73
        """
74
        try:
75
            import pypandoc
76
            description = pypandoc.convert_file('README.md', 'rst', 'md')
77
        except (IOError, ImportError):
78
            description = open("README.md").read()
79
        return description
80