Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sjhbuild/sysdeps.py
blob: eaeeb9b7a363501e47755797501ea99f983a33d0 (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
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

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:
        pass

    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']:
        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)]

_unstable_names = {
    'debian': 'unstable',
    'fedora': 'rawhide',
    'mandrivalinux': 'cooker',
    'ubuntu': 'unstable',
}
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)]

_cached_packages = None
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