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 . """ 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