diff options
author | necoro <> | 2006-11-24 12:02:21 +0000 |
---|---|---|
committer | necoro <> | 2006-11-24 12:02:21 +0000 |
commit | aaf3830acd70c3a40be92974f3a896f19ae29192 (patch) | |
tree | efcdf6c75ea289052b9076622798fbbd1b8c1a94 /portato/backend/portage_helper.py | |
parent | 7fbdc7d54fe592946ae30110afb59e3707aa9dba (diff) | |
download | portato-aaf3830acd70c3a40be92974f3a896f19ae29192.tar.gz portato-aaf3830acd70c3a40be92974f3a896f19ae29192.tar.bz2 portato-aaf3830acd70c3a40be92974f3a896f19ae29192.zip |
Renamed to portato
Diffstat (limited to 'portato/backend/portage_helper.py')
-rw-r--r-- | portato/backend/portage_helper.py | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/portato/backend/portage_helper.py b/portato/backend/portage_helper.py new file mode 100644 index 0000000..6e8fc84 --- /dev/null +++ b/portato/backend/portage_helper.py @@ -0,0 +1,374 @@ +# -*- coding: utf-8 -*- +# +# File: portato/backend/portage_helper.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2006 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann <necoro@necoro.net> + +import re, os, copy + +import portage, gentoolkit +from portage_util import unique_array + +from portato.backend import * +import package + +from portato.helper import debug + +def find_lambda (name): + """Returns the function needed by all the find_all_*-functions. Returns None if no name is given. + + @param name: name to build the function of + @type name: string + @returns: + 1. None if no name is given + 2. a lambda function + @rtype: function""" + + if name != None: + return lambda x: re.match(".*"+name+".*",x) + else: + return lambda x: True + +def geneticize_list (list_of_packages): + """Convertes a list of gentoolkit.Packages into L{backend.Package}s. + + @param list_of_packages: the list of packages + @type list_of_packages: list of gentoolkit.Packages + @returns: converted list + @rtype: backend.Package[]""" + + return [package.Package(x) for x in list_of_packages] + +def find_best_match (search_key, only_installed = False): + """Finds the best match in the portage tree. It does not find masked packages! + + @param search_key: the key to find in the portage tree + @type search_key: string + @param only_installed: if True, only installed packages are searched + @type only_installed: boolean + + @returns: the package found or None + @rtype: backend.Package""" + + t = None + if not only_installed: + t = porttree.dep_bestmatch(search_key) + else: + t = vartree.dep_bestmatch(search_key) + if t: + return package.Package(t) + return None + +def find_packages (search_key, masked=False): + """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible. + + @param search_key: the key to look for + @type search_key: string + @param masked: if True, also look for masked packages + @type masked: boolean + + @returns: list of found packages + @rtype: backend.Package[]""" + + return geneticize_list(gentoolkit.find_packages(search_key, masked)) + +def find_installed_packages (search_key, masked=False): + """This returns a list of packages which have to fit exactly. Additionally ranges like '<,>,=,~,!' et. al. are possible. + + @param search_key: the key to look for + @type search_key: string + @param masked: if True, also look for masked packages + @type masked: boolean + + @returns: list of found packages + @rtype: backend.Package[]""" + + return geneticize_list(gentoolkit.find_installed_packages(search_key, masked)) + +def find_system_packages (): + """Looks for all packages saved as "system-packages". + + @returns: a tuple of (resolved_packages, unresolved_packages). + @rtype: (backend.Package[], backend.Package[])""" + + list = gentoolkit.find_system_packages() + return (geneticize_list(list[0]), geneticize_list(list[1])) + +def find_world_packages (): + """Looks for all packages saved in the world-file. + + @returns: a tuple of (resolved_packages, unresolved_packages). + @rtype: (backend.Package[], backend.Package[])""" + + list = gentoolkit.find_world_packages() + return geneticize_list(list[0]),geneticize_list(list[1]) + +def find_all_installed_packages (name=None, withVersion=True): + """Finds all installed packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @param withVersion: if True version-specific packages are returned; else only the cat/package-strings a delivered + @type withVersion: boolean + + @returns: all packages/cp-strings found + @rtype: backend.Package[] or cp-string[]""" + + if withVersion: + return geneticize_list(gentoolkit.find_all_installed_packages(find_lambda(name))) + else: + t = vartree.dbapi.cp_all() + if name: + t = filter(find_lambda(name),t) + return t + +def find_all_uninstalled_packages (name=None): + """Finds all uninstalled packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @returns: all packages found + @rtype: backend.Package[]""" + + return geneticize_list(gentoolkit.find_all_uninstalled_packages(find_lambda(name))) + +def find_all_packages (name=None, withVersion=True): + """Finds all packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @param withVersion: if True version-specific packages are returned; else only the cat/package-strings a delivered + @type withVersion: boolean + + @returns: all packages/cp-strings found + @rtype: backend.Package[] or cp-string[]""" + + if (withVersion): + return geneticize_list(gentoolkit.find_all_packages(find_lambda(name))) + else: + t = porttree.dbapi.cp_all() + t += vartree.dbapi.cp_all() + t = unique_array(t) + if name: + t = filter(find_lambda(name),t) + return t + +def find_all_world_packages (name=None): + """Finds all world packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @returns: all packages found + @rtype: backend.Package[]""" + + world = filter(find_lambda(name), [x.get_cpv() for x in find_world_packages()[0]]) + world = unique_array(world) + return geneticize_list(world) + +def find_all_system_packages (name=None): + """Finds all system packages matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all packages are returned + @type name: string or None + @returns: all packages found + @rtype: backend.Package[]""" + + sys = filter(find_lambda(name), [x.get_cpv() for x in find_system_packages()[0]]) + sys = unique_array(sys) + return geneticize_list(sys) + +def get_all_versions (cp): + """Returns all versions of a certain package. + + @param cp: the package + @type cp: string (cat/pkg) + @returns: the list of found packages + @rtype: backend.Package[]""" + + t = porttree.dbapi.cp_list(cp) + t += vartree.dbapi.cp_list(cp) + t = unique_array(t) + return geneticize_list(t) + +def get_all_installed_versions (cp): + """Returns all installed versions of a certain package. + + @param cp: the package + @type cp: string (cat/pkg) + @returns: the list of found packages + @rtype: backend.Package[]""" + + return geneticize_list(vartree.dbapi.cp_list(cp)) + +def list_categories (name=None): + """Finds all categories matching a name or all if no name is specified. + + @param name: the name to look for - it is expanded to .*name.* ; if None, all categories are returned + @type name: string or None + @returns: all categories found + @rtype: string[]""" + + categories = gentoolkit.settings.categories + return filter(find_lambda(name), categories) + +def split_package_name (name): + """Splits a package name in its elements. + + @param name: name to split + @type name: string + @returns: list: [category, name, version, rev] whereby rev is "r0" if not specified in the name + @rtype: string[]""" + + return gentoolkit.split_package_name(name) + +def sort_package_list(pkglist): + """Sorts a package list in the same manner portage does. + + @param pkglist: list to sort + @type pkglist: Packages[]""" + + return gentoolkit.sort_package_list(pkglist) + +def reload_settings (): + """Reloads portage.""" + gentoolkit.settings = portage.config(config_incrementals = copy.deepcopy(gentoolkit.settings.incrementals)) + +def update_world (newuse = False, deep = False): + """Calculates the packages to get updated in an update world. + + @param newuse: Checks if a use-flag has a different state then to install time. + @type newuse: boolean + @param deep: Not only check world packages but also there dependencies. + @type deep: boolean + @returns: a list containing of the tuple (new_package, old_package) + @rtype: (backend.Package, backend.Package)[]""" + + # read world file + world = open(portage.WORLD_FILE) + packages = [] + for line in world: + line = line.strip() + if not len(line): continue # empty line + if line[0] == "#": continue + packages.append(line) + world.close() + + sys = gentoolkit.settings.packages + for x in sys: + if x[0] == "*": + x = x[1:] + packages.append(x.strip()) + + # Remove everything that is package.provided from our list + # This is copied from emerge.getlist() + for atom in packages[:]: + for expanded_atom in portage.flatten(portage.dep_virtual([atom], gentoolkit.settings)): + mykey = portage.dep_getkey(expanded_atom) + if mykey in gentoolkit.settings.pprovideddict and portage.match_from_list(expanded_atom, settings.pprovideddict[mykey]): + packages.remove(atom) + break + + packages = [find_best_match(x) for x in packages] + + checked = [] + updating = [] + raw_checked = [] + def check (p): + """Checks whether a package is updated or not.""" + if p.get_cp() in checked: return + else: checked.append(p.get_cp()) + + appended = False + tempDeep = False + + if not p.is_installed(): + oldList = find_installed_packages(p.get_cp()) + if oldList: + old = oldList[0] # assume we have only one there; FIXME: slotted packages + else: + debug("Bug? Not found installed one:",p.get_cp()) + return + updating.append((p, old)) + appended = True + p = old + + if newuse: + old = p.get_installed_use_flags() + new = p.get_settings("USE").split() + + for u in p.get_all_use_flags(): + if (u in new) != (u in old): + if not appended: + updating.append((p,p)) + tempDeep = True + + if deep or tempDeep: + for i in p.get_matched_dep_packages(): + if i not in raw_checked: + raw_checked.append(i) + bm = find_best_match(i) + if not bm: + debug("Bug? No best match could be found:",i) + else: + check(bm) + + for p in packages: + if not p: continue # if a masked package is installed we have "None" here + check(p) + + return updating + +use_descs = {} +local_use_descs = {} +def get_use_desc (flag, package = None): + """Returns the description of a specific useflag or None if no desc was found. + If a package is given (in the <cat>/<name> format) the local use descriptions are searched too. + + @param flag: flag to get the description for + @type flag: string + @param package: name of a package: if given local use descriptions are searched too + @type package: cp-string + @returns: found description + @rtype: string""" + + # In the first run the dictionaries 'use_descs' and 'local_use_descs' are filled. + + # fill cache if needed + if use_descs == {} or local_use_descs == {}: + # read use.desc + fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.desc") + for line in fd.readlines(): + line = line.strip() + if line != "" and line[0] != '#': + fields = [x.strip() for x in line.split(" - ",1)] + if len(fields) == 2: + use_descs[fields[0]] = fields[1] + + # read use.local.desc + fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.local.desc") + for line in fd.readlines(): + line = line.strip() + if line != "" and line[0] != '#': + fields = [x.strip() for x in line.split(":",1)] + if len(fields) == 2: + if not fields[0] in local_use_descs: # create + local_use_descs[fields[0]] = {} + subfields = [x.strip() for x in fields[1].split(" - ",1)] + if len(subfields) == 2: + local_use_descs[fields[0]][subfields[0]] = subfields[1] + + # start + desc = None + if flag in use_descs: + desc = use_descs[flag] + if package != None: + if package in local_use_descs: + if flag in local_use_descs[package]: + desc = local_use_descs[package][flag] + return desc |