Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sjhbuild/sysdeps.py
blob: cf851aff65aa170934606ec35a368d40597082e1 (plain)
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
import operator
import os
import subprocess
import sys

from xml.dom import minidom

scripts_dir = os.path.dirname(__file__)
base_dir = os.path.dirname(scripts_dir)

_cached_dname, _cached_dversion = None, None
_cached_packages = None
_UNSTABLE_NAMES = {
    'debian': 'unstable',
    'fedora': 'rawhide',
    'mandrivalinux': 'cooker',
    'ubuntu': 'unstable',
    'tuquito':'unstable',
}


def _pipe_lower(args):
    out, err_ = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()
    return out.strip().lower()


def get_distribution():
    global _cached_dname, _cached_dversion

    if _cached_dname:
        return _cached_dname, _cached_dversion

    if 'SJH_DISTRIBUTION' in os.environ:
        _cached_dname, _cached_dversion = \
            os.environ['SJH_DISTRIBUTION'].split('-')
        return _cached_dname, _cached_dversion

    try:
        _cached_dname = _pipe_lower(['lsb_release', '-is'])
        _cached_dversion = _pipe_lower(['lsb_release', '-rs'])

    except OSError:
        sys.stderr.write('ERROR: Could not run lsb_release. Is it installed?\n')

    return _cached_dname, _cached_dversion


def check_package(package):
    name, version_ = get_distribution()
    if name in ['fedora', 'mandrivalinux']:
        ret = subprocess.call(['rpm', '--quiet', '-q', package])
        return ret == 0
    elif name in ['ubuntu', 'debian', 'tuquito']:
        cmd = ["dpkg-query", "-f='${status}'", "-W", package]
        out, err_ = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()
        return out.find('install ok installed') != -1

    return None


def _check_suffix(name, suffixes):
    """
    Returns a list of all matching suffixes for <name>.
    """
    return [name for suffix in suffixes if name.endswith(suffix)]


def _parse_dependencies(dname, dversion):
    if not (dname and dversion):
        return []

    suffixes = ['alldistros.xml', '%s-allversions.xml' % (dname, ),
                '%s-%s.xml' % (dname, dversion)]

    dirname = os.path.join(base_dir, 'config', 'sysdeps')
    filenames = [os.path.join(dirname, fname)
        for fname in os.listdir(dirname)
        if _check_suffix(fname, suffixes)]

    # check whether we have a file matching the exact distro version
    if not [name for name in filenames if name.endswith(suffixes[-1])]:
        if dname not in _UNSTABLE_NAMES:
            sys.stderr.write('ERROR: %r is not a supported distro. If you '
                'think it is sufficiently recent to contain everything the '
                'latest development version of Sugar needs and would like to '
                'see it supported, please file a ticket at dev.sugarlabs.org.'
                '\n' % (dname, ))
            return []

        uversion = _UNSTABLE_NAMES[dname]
        if (dversion == uversion):
            # no config for unstable
            return []

        sys.stderr.write('Warning: unknown distro version, automatic fallback '
            'to %s.\n' % (uversion, ))
        return _parse_dependencies(dname, uversion)


    return [minidom.parse(fname)
            for fname in filenames if os.path.exists(fname)]


def get_packages():
    global _cached_packages

    if _cached_packages is not None:
        return _cached_packages

    dname, dversion = get_distribution()
    documents = _parse_dependencies(dname, dversion)
    _cached_packages = []

    if not documents:
        return _cached_packages

    roots = [doc.childNodes[0] for doc in documents]

    for node in reduce(operator.add, [root.childNodes for root in roots]):
        if node.nodeType == node.ELEMENT_NODE:
            if node.nodeName == 'package':
                name = node.getAttribute('name')
                if node.hasAttribute('source'):
                    source = node.getAttribute('source')
                else:
                    source = None

                _cached_packages.append((name, source))

    return _cached_packages