File: version.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (165 lines) | stat: -rw-r--r-- 5,466 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from __future__ import print_function
import time
import py
import os
from subprocess import Popen, PIPE
import rpython
rpythondir = os.path.dirname(os.path.realpath(rpython.__file__))
rpythonroot = os.path.dirname(rpythondir)
default_retval = '?', '?'

def maywarn(err, repo_type='Mercurial'):
    if not err:
        return

    from rpython.tool.ansi_print import AnsiLogger
    log = AnsiLogger("version")
    log.WARNING('Errors getting %s information: %s' % (repo_type, err))

CACHED_RESULT = None
CACHED_ARGS = None

def get_repo_version_info(hgexe=None, root=rpythonroot):
    '''Obtain version information by invoking the 'hg' or 'git' commands.'''
    global CACHED_RESULT, CACHED_ARGS
    key = (hgexe, root)
    if CACHED_RESULT is not None and CACHED_ARGS == key:
        return CACHED_RESULT
    res = _get_repo_version_info(hgexe, root)
    CACHED_RESULT = res
    CACHED_ARGS = key
    return res

def _get_repo_version_info(hgexe, root):
    # Debian: built from a source tarball
    p = Popen(('dpkg-parsechangelog',), stdout=PIPE, cwd=rpythonroot)
    if p.wait() != 0:
        maywarn(p.stderr.read(), 'dpkg-parsechangelog')
        return default_retval
    for line in p.stdout.read().split('\n'):
        if line.split(':', 1)[0].strip() == 'Version':
            version = line.split(':', 1)[1].strip()
            return '', version

    # Try to see if we can get info from Git if hgexe is not specified.
    if not hgexe:
        gitfile =  os.path.join(root, '.git')
        if os.path.isdir(gitfile):
            return _get_git_version(root)
        elif os.path.exists(gitfile):
            # Can be a file with a relative path like
            # gitdir: ../.git/modules/pypy
            with open(gitfile) as fid:
                contents = fid.read()
                if contents.startswith('gitdir:'):
                    return _get_git_version(root)

    # Fallback to trying Mercurial.
    if hgexe is None:
        hgexe = py.path.local.sysfind('hg')

    if os.path.isfile(os.path.join(root, '.hg_archival.txt')):
        return _get_hg_archive_version(os.path.join(root, '.hg_archival.txt'))
    elif not os.path.isdir(os.path.join(root, '.hg')):
        maywarn('Not running from a Mercurial repository!')
        return default_retval
    elif not hgexe:
        maywarn('Cannot find Mercurial command!')
        return default_retval
    else:
        return _get_hg_version(hgexe, root)


def _get_hg_version(hgexe, root):
    env = dict(os.environ)
    # get Mercurial into scripting mode
    env['HGPLAIN'] = '1'
    # disable user configuration, extensions, etc.
    env['HGRCPATH'] = os.devnull

    try:
        p = Popen([str(hgexe), 'version', '-q'],
                  stdout=PIPE, stderr=PIPE, env=env, universal_newlines=True)
    except OSError as e:
        maywarn(e)
        return default_retval

    if not p.stdout.read().startswith('Mercurial Distributed SCM'):
        maywarn('command does not identify itself as Mercurial')
        return default_retval

    p = Popen([str(hgexe), 'id', '--template', r"{id}\n{tags}\n{branch}\n", root],
              stdout=PIPE, stderr=PIPE, env=env,
              universal_newlines=True)
    hgout = p.stdout.read().strip()
    if p.wait() != 0:
        maywarn(p.stderr.read())
        hgout = '?\n?\n?'
    hgid, hgtags, hgbranch = hgout.strip().split("\n", 3)
    hgtags = [t for t in hgtags.strip().split() if t != 'tip']

    if hgtags:
        return hgtags[0], hgid
    else:
        return hgbranch, hgid


def _get_hg_archive_version(path):
    with open(path) as fp:
        # reverse the order since there may be more than one tag
        # and the latest tag will be first, so make it last instead
        data = dict((x.split(': ', 1) for x in fp.read().splitlines()[::-1]))
    if 'tag' in data:
        return data['tag'], data['node']
    else:
        return data['branch'], data['node']


def _get_git_version(root):
    #XXX: this function is a untested hack,
    #     so the git mirror tav made will work
    gitexe = py.path.local.sysfind('git')
    if not gitexe:
        return default_retval

    try:
        p = Popen(
            [str(gitexe), 'rev-parse', 'HEAD'],
            stdout=PIPE, stderr=PIPE, cwd=root,
            universal_newlines=True,
            )
    except OSError as e:
        maywarn(e, 'Git')
        return default_retval
    if p.wait() != 0:
        maywarn(p.stderr.read(), 'Git')
        return default_retval
    revision_id = p.stdout.read().strip()[:12]
    p = Popen(
        [str(gitexe), 'describe', '--tags', '--exact-match'],
        stdout=PIPE, stderr=PIPE, cwd=root,
        universal_newlines=True,
        )
    if p.wait() != 0:
        p = Popen(
            [str(gitexe), 'branch'], stdout=PIPE, stderr=PIPE,
            cwd=root, universal_newlines=True,
            )
        if p.wait() != 0:
            maywarn(p.stderr.read(), 'Git')
            return 'pypy-HEAD', revision_id
        branch = '?'
        for line in p.stdout.read().strip().split('\n'):
            if line.startswith('* '):
                branch = line[1:].strip()
                if branch == '(no branch)':
                    branch = 'pypy-HEAD'
                if branch.startswith("(HEAD detached"):
                    branch = 'pypy-HEAD'
                break
        return branch, revision_id
    return p.stdout.read().strip(), revision_id


if __name__ == '__main__':
    print(get_repo_version_info())