Completed
Pull Request — develop (#5)
by Kale
57s
created

auxlib.SdistCommand   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 10
Duplicated Lines 0 %
Metric Value
dl 0
loc 10
rs 10
wmc 3

2 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 2 1
A make_release_tree() 0 6 2
1
# -*- coding: utf-8 -*-
2
from __future__ import print_function, division, absolute_import
3
from logging import getLogger
4
from os.path import basename, dirname, join, isdir
5
from pkg_resources import resource_string
6
from re import match
7
from setuptools.command.build_py import build_py
8
from setuptools.command.sdist import sdist
9
from setuptools.command.test import test as TestCommand
10
from subprocess import CalledProcessError, check_call, check_output
11
from sys import exit
12
13
from .path import absdirname
14
15
log = getLogger(__name__)
16
17
18
def _get_version_from_pkg_info(package_name):
19
    return resource_string(package_name, '.version')
20
21
22
def _get_version_from_git_tag():
23
    """Return a PEP440-compliant version derived from the git status.
24
    If that fails for any reason, return the first 7 chars of the changeset hash.
25
    """
26
27
    def _is_dirty():
28
        try:
29
            check_call(['git', 'diff', '--quiet'])
30
            check_call(['git', 'diff', '--cached', '--quiet'])
31
            return False
32
        except CalledProcessError:
33
            return True
34
35
    def _get_most_recent_tag():
36
        try:
37
            return check_output(["git", "describe", "--tags"]).strip()
38
        except CalledProcessError as e:
39
            if e.returncode == 128:
40
                return "0.0.0.0"
41
            else:
42
                raise
43
44
    def _get_hash():
45
        try:
46
            return check_output(["git", "rev-parse", "HEAD"]).strip()[:7]
47
        except CalledProcessError:
48
            return
49
50
    tag = _get_most_recent_tag()
51
    m = match("(?P<xyz>\d+\.\d+\.\d+)(?:-(?P<dev>\d+)-(?P<hash>.+))?", tag)
52
53
    version = m.group('xyz')
54
    if m.group('dev') or _is_dirty():
55
        version += ".dev{dev}+{hash}".format(dev=m.group('dev') or 0,
56
                                             hash=m.group('hash') or _get_hash())
57
    return version
58
59
60
def is_git_repo(path, package):
61
    if path == '/' or dirname(basename(path)) == package:
62
        return False
63
    else:
64
        return isdir(join(path, '.git')) or is_git_repo(dirname(path), package)
65
66
67
def get_version(file, package):
68
    """Returns a version string for the current package, derived
69
    either from the SCM (git currently) or from PKG-INFO.
70
71
    This function is expected to run in two contexts. In a development
72
    context, where .git/ exists, the version is pulled from git tags
73
    and written into PKG-INFO to create an sdist or bdist.
74
75
    In an installation context, the PKG-INFO file written above is the
76
    source of version string.
77
78
    """
79
    here = absdirname(file)
80
    if is_git_repo(here, package):
81
        return _get_version_from_git_tag()
82
83
    # fall back to .version file
84
    version_from_pkg = _get_version_from_pkg_info(package)
85
    if version_from_pkg:
86
        return version_from_pkg
87
88
    raise RuntimeError("Could not get package version (no .git or .version file)")
89
90
91
class BuildPyCommand(build_py):
92
    def run(self):
93
        # root = get_root()
94
        # cfg = get_config_from_root(root)
95
        # versions = get_versions()
96
        build_py.run(self)
97
        # locate .version in the new build/ directory and replace it with an updated value
98
        target_version_file = join(self.build_lib, self.distribution.metadata.name, ".version")
99
        print("UPDATING %s" % target_version_file)
100
        with open(target_version_file, 'w') as f:
101
            f.write(self.distribution.metadata.version)
102
103
104
class SdistCommand(sdist):
105
    def run(self):
106
        return sdist.run(self)
107
108
    def make_release_tree(self, base_dir, files):
109
        sdist.make_release_tree(self, base_dir, files)
110
        target_version_file = join(base_dir, self.distribution.metadata.name, ".version")
111
        print("UPDATING %s" % target_version_file)
112
        with open(target_version_file, 'w') as f:
113
            f.write(self.distribution.metadata.version)
114
115
116
class Tox(TestCommand):
117
    user_options = [('tox-args=', 'a', "Arguments to pass to tox")]
118
119
    def initialize_options(self):
120
        TestCommand.initialize_options(self)
121
        self.tox_args = None
122
123
    def finalize_options(self):
124
        TestCommand.finalize_options(self)
125
        self.test_args = []
126
        self.test_suite = True
127
128
    def run_tests(self):
129
        # import here, cause outside the eggs aren't loaded
130
        import tox
131
        import shlex
132
        args = self.tox_args
133
        if args:
134
            args = shlex.split(self.tox_args)
135
        else:
136
            args = ''
137
        errno = tox.cmdline(args=args)
138
        exit(errno)
139
140
141
if __name__ == "__main__":
142
    print(get_version(__file__, __package__))
143