import builder
import config
-import depsolve
import distro
import logger
-import packages
import repository
-import transaction
+import packages
import util
from constants import *
from i18n import _
class Pakfire(object):
- def __init__(self, builder=False, configs=[], disable_repos=None,
- distro_config=None):
+ def __init__(self, builder=False, configs=[], enable_repos=None,
+ disable_repos=None, distro_config=None):
# Check if we are operating as the root user.
self.check_root_user()
# Get more information about the distribution we are running
# or building
self.distro = distro.Distribution(self, distro_config)
- self.repos = repository.Repositories(self)
+ self.repos = repository.Repositories(self,
+ enable_repos=enable_repos, disable_repos=disable_repos)
- # Disable repositories if passed on command line
- if disable_repos:
- for repo in disable_repos:
- self.repos.disable_repo(repo)
-
- # Update all indexes of the repositories (not force) so that we will
- # always work with valid data.
- self.repos.update()
+ # Create a short reference to the solver of this pakfire instance.
+ self.solver = self.repos.solver
def destroy(self):
if not self.path == "/":
raise BuildError, arch
def install(self, requires):
- ds = depsolve.DependencySet(pakfire=self)
-
+ # Create a new request.
+ request = self.solver.create_request()
for req in requires:
- if isinstance(req, packages.BinaryPackage):
- ds.add_package(req)
- else:
- ds.add_requires(req)
+ request.install(req)
- ds.resolve()
- ds.dump()
+ # Do the solving.
+ t = self.solver.solve(request)
- ret = cli.ask_user(_("Is this okay?"))
- if not ret:
+ if not t:
return
- ts = transaction.Transaction(self, ds)
- ts.run()
+ t.run()
def update(self, pkgs):
- ds = depsolve.DependencySet(pakfire=self)
-
- for pkg in ds.packages:
- # Skip unwanted packages (passed on command line)
- if pkgs and not pkg.name in pkgs:
- continue
-
- updates = self.repos.get_by_name(pkg.name)
- updates = packages.PackageListing(updates)
-
- latest = updates.get_most_recent()
-
- # If the current package is already the latest
- # we skip it.
- if latest == pkg:
- continue
-
- # Otherwise we want to update the package.
- ds.add_package(latest)
-
- ds.resolve()
- ds.dump()
-
- ret = cli.ask_user(_("Is this okay?"))
- if not ret:
- return
-
- ts = transaction.Transaction(self, ds)
- ts.run()
+ # XXX needs to be done
+ pass
def info(self, patterns):
pkgs = []
def provides(self, patterns):
pkgs = []
for pattern in patterns:
- requires = depsolve.Requires(None, pattern)
- pkgs += self.repos.get_by_provides(requires)
+ pkgs += self.repos.get_by_provides(pattern)
pkgs = packages.PackageListing(pkgs)
#pkgs.unique()
def requires(self, patterns):
pkgs = []
for pattern in patterns:
- requires = depsolve.Requires(None, pattern)
- pkgs += self.repos.get_by_requires(requires)
+ pkgs += self.repos.get_by_requires(pattern)
pkgs = packages.PackageListing(pkgs)
#pkgs.unique()
import base
import chroot
-import depsolve
import logger
import packages
import repository
-import transaction
import util
from constants import *
"""
return self.distro.arch
+ @property
+ def solver(self):
+ return self.pakfire.solver
+
@property
def info(self):
return {
if not requires:
return
- ds = depsolve.DependencySet(self.pakfire)
- for r in requires:
- if isinstance(r, packages.BinaryPackage):
- ds.add_package(r)
- else:
- ds.add_requires(r)
- ds.resolve()
- ds.dump(logger=self.log)
+ # Create a request and fill it with what we need.
+ request = self.solver.create_request()
+
+ for req in requires:
+ if isinstance(req, packages.BinaryPackage):
+ req = req.friendly_name
+
+ req = self.solver.create_relation(req)
- ts = transaction.Transaction(self.pakfire, ds)
- ts.run()
+ request.install(req)
+
+ # Do the solving.
+ transaction = self.solver.solve(request)
+
+ # Show the user what is going to be done.
+ transaction.dump(logger=self.log)
+
+ # Run the transaction.
+ transaction.run()
def install_test(self):
+ return # XXX currently disabled
+
pkgs = []
# Connect packages to the FS repository.
+++ /dev/null
-#!/usr/bin/python
-
-import logging
-import re
-
-import packages
-import repository
-import transaction
-import util
-
-from errors import *
-
-from i18n import _
-
-PKG_DUMP_FORMAT = " %-21s %-8s %-21s %-19s %5s "
-
-class Requires(object):
- def __init__(self, pkg, requires, dep=False):
- self.pkg = pkg
- self.requires = requires
- self.dep = dep
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, self.requires)
-
- def __str__(self):
- return self.requires
-
- def __cmp__(self, other):
- return cmp(self.requires, other.requires)
-
- def __hash__(self):
- return hash(self.requires)
-
- @property
- def type(self):
- if self.requires.startswith("/"):
- return "file"
-
- elif "(" in self.requires:
- return "virtual"
-
- elif ">" in self.requires or "<" in self.requires or "=" in self.requires:
- return "expr"
-
- elif not re.match("^lib.*\.so.*", self.requires):
- return "lib"
-
- return "generic"
-
-
-class Conflicts(object):
- def __init__(self, pkg, conflicts):
- self.pkg = pkg
- self.conflicts = conflicts
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, self.conflicts)
-
- def __str__(self):
- return self.conflicts
-
- def __hash__(self):
- return hash(self.conflicts)
-
-
-class Obsoletes(object):
- def __init__(self, pkg, obsoletes):
- self.pkg = pkg
- self.obsoletes = obsoletes
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, self.obsoletes)
-
- def __str__(self):
- return self.obsoletes
-
- def __hash__(self):
- return hash(self.obsoletes)
-
-
-class DependencySet(object):
- def __init__(self, pakfire):
- # Reference all repositories
- self.repos = pakfire.repos #repository.Repositories()
-
- # List of packages in this set
- self.__packages = set()
-
- # Helper lists
- self.__conflicts = set()
- self.__requires = set()
- self.__obsoletes = set()
-
- # Create a new transaction set.
- self.ts = transaction.TransactionSet()
-
- # Read-in all packages from the database that have
- # been installed previously and need to be taken into
- # account when resolving dependencies.
- for pkg in self.repos.local.packages:
- self.add_package(pkg, transaction=False)
-
- def add_requires(self, requires, pkg=None, dep=False):
- requires = Requires(pkg, requires, dep)
-
- if requires in self.__requires:
- return
-
- for pkg in self.__packages:
- if pkg.does_provide(requires):
- logging.debug("Skipping requires '%s' which is already provided by %s" % (requires.requires, pkg))
- return
-
- #logging.debug("Adding requires: %s" % requires)
- self.__requires.add(requires)
-
- def add_obsoletes(self, obsoletes, pkg=None):
- obsoletes = Obsoletes(pkg, obsoletes)
-
- self.__obsoletes.add(obsoletes)
-
- def add_package(self, pkg, dep=False, transaction=True):
- #print pkg, sorted(self.__packages)
- #assert not pkg in self.__packages
- if pkg in self.__packages:
- logging.debug("Trying to add package which is already in the dependency set: %s" % pkg)
- return
-
- if transaction:
- transaction_mode = "install"
- for p in self.__packages:
- if pkg.name == p.name:
- transaction_mode = "update"
-
- # Set pointer to package that is updated.
- pkg.old_package = p
-
- # Remove old package from list of packages.
- self.__packages.remove(pkg.old_package)
- break
-
- # Add package to transaction set
- func = getattr(self.ts, transaction_mode)
- func(pkg, dep=dep)
-
- #if not isinstance(pkg, packages.DatabasePackage):
- # logging.info(" --> Adding package to dependency set: %s" % pkg.friendly_name)
- self.__packages.add(pkg)
-
- # Add the requirements of the newly added package.
- for req in pkg.requires:
- self.add_requires(req, pkg, dep=True)
-
- # Remove all requires that are fulfilled by this package.
- # For that we copy the matching requires to _requires and remove them
- # afterwards, because changing self.__requires in a "for" loop is not
- # a good idea.
- _requires = []
- for req in self.__requires:
- if pkg.does_provide(req):
- _requires.append(req)
-
- for req in _requires:
- self.__requires.remove(req)
-
- @property
- def packages(self):
- if not self.__requires:
- return self.__packages[:]
-
- def resolve(self):
- unresolveable_reqs = []
-
- while self.__requires:
- requires = self.__requires.pop()
- logging.debug("Resolving requirement \"%s\"" % requires)
-
- # Fetch all candidates from the repositories and save the
- # best one
- if requires.type == "file":
- candidates = self.repos.get_by_file(requires.requires)
- else:
- candidates = self.repos.get_by_provides(requires)
-
- # Turn the candidates into a package listing.
- candidates = packages.PackageListing(candidates)
-
- if not candidates:
- logging.debug(" Got no candidates for that")
- unresolveable_reqs.append(requires)
- continue
-
- logging.debug(" Got candidates for that:")
- for candidate in candidates:
- logging.debug(" --> %s" % candidate)
-
- best = candidates.get_most_recent()
- if best:
- self.add_package(best, dep=requires.dep)
-
- if unresolveable_reqs:
- raise DependencyError, "Cannot resolve %s" % \
- " ".join([r.requires for r in unresolveable_reqs])
-
- def dump_pkg(self, format, pkg):
- return format % (
- pkg.name,
- pkg.arch,
- pkg.friendly_version,
- pkg.repo.name,
- util.format_size(pkg.size),
- )
-
- def dump_pkgs(self, caption, pkgs):
- if not pkgs:
- return []
-
- s = [caption,]
- for pkg in sorted(pkgs):
- s.append(self.dump_pkg(PKG_DUMP_FORMAT, pkg))
- s.append("")
- return s
-
- def dump(self, logger=None):
- # If no logger was given, we use the root logger.
- if not logger:
- logger = logging.getLogger()
-
- width = 80
- line = "=" * width
-
- s = []
- s.append(line)
- s.append(PKG_DUMP_FORMAT % (_("Package"), _("Arch"), _("Version"), _("Repository"), _("Size")))
- s.append(line)
-
- s += self.dump_pkgs(_("Installing:"), self.ts.installs)
- s += self.dump_pkgs(_("Installing for dependencies:"), self.ts.install_deps)
- s += self.dump_pkgs(_("Updating:"), self.ts.updates)
- s += self.dump_pkgs(_("Updating for dependencies:"), self.ts.update_deps)
- s += self.dump_pkgs(_("Removing:"), self.ts.removes)
- s += self.dump_pkgs(_("Removing for dependencies:"), self.ts.remove_deps)
-
- s.append(_("Transaction Summary"))
- s.append(line)
-
- format = "%-20s %-4d %s"
-
- if self.ts.installs or self.ts.install_deps:
- s.append(format % (_("Install"),
- len(self.ts.installs + self.ts.install_deps), _("Package(s)")))
-
- if self.ts.updates or self.ts.update_deps:
- s.append(format % (_("Updates"),
- len(self.ts.updates + self.ts.update_deps), _("Package(s)")))
-
- if self.ts.removes or self.ts.remove_deps:
- s.append(format % (_("Remove"),
- len(self.ts.removes + self.ts.remove_deps), _("Package(s)")))
-
- # Calculate the size of all files that need to be downloaded this this
- # transaction.
- download_size = sum([p.size for p in self.ts.downloads])
- if download_size:
- s.append(_("Total download size: %s") % util.format_size(download_size))
- s.append("")
-
- for line in s:
- logger.info(line)
#!/usr/bin/python
-
-import fnmatch
import logging
-import re
import util
-import pakfire.depsolve
from pakfire.i18n import _
class Package(object):
def supported_arches(self):
return self.metadata.get("PKG_SUPPORTED_ARCHES", "all")
+ @property
+ def vendor(self):
+ return self.metadata.get("PKG_VENDOR", "")
+
@property
def requires(self):
ret = ""
return set(ret.split())
@property
- def _provides(self):
- # Make package identifyable by its name and version/release tuples.
- provides = [
- self.name,
- "%s=%s-%s" % (self.name, self.version, self.release),
- "%s=%s:%s-%s" % (self.name, self.epoch, self.version, self.release),
- ]
+ def provides(self):
+ provides = self.metadata.get("PKG_PROVIDES", "").split()
return set(provides)
- ### methods ###
-
- def _does_provide_file(self, requires):
- for file in self.filelist:
- if fnmatch.fnmatch(file, requires.requires):
- return True
-
- return False
-
- def does_provide(self, requires):
- if not isinstance(requires, pakfire.depsolve.Requires):
- requires = pakfire.depsolve.Requires(self, requires)
-
- # Get all provide strings from the package data
- # and return true if requires is matched.
- if requires.requires in self.provides:
- return True
-
- if requires.type == "file":
- return self._does_provide_file(requires)
-
- elif requires.type == "expr":
- # Handle all expressions like "gcc>=4.0.0-1"
- (e_expr, e_name, e_epoch, e_version, e_release) = \
- util.parse_pkg_expr(requires.requires)
-
- # If the package names do not match, we do not provide this:
- if not self.name == e_name:
- return False
-
- ret = util.version_compare(self.version_tuple, (e_epoch, e_version, e_release))
-
- # If we equal the version, we provide this
- if "=" in e_expr and ret == 0:
- return True
-
- elif ">" in e_expr and ret > 0:
- return True
-
- elif "<" in e_expr and ret < 0:
- return True
-
- return False
-
- elif requires.type == "virtual":
- (r_type, r_expr, r_name, r_version) = \
- util.parse_virtual_expr(requires.requires)
-
- # If we get an invalid expression with no name, we
- # do not provide this.
- if not r_name:
- return False
-
- for provides in self.provides:
- (p_type, p_expr, p_name, p_version) = \
- util.parse_virtual_expr(provides)
-
- # If name does not match, we have no match at all.
- if not p_type == r_type or not p_name == r_name:
- continue
-
- # Check if the expression is fulfilled.
- if r_expr == "=":
- return p_version == r_version
-
- elif r_expr == ">=":
- return p_version >= r_version
-
- elif r_expr == ">":
- return p_version > r_version
-
- elif r_expr == "<":
- return p_version < r_version
-
- elif r_expr == "<=":
- return p_version <= r_version
-
- elif not r_expr:
- # If we get here, the name matches and there was no version
- # required.
- return True
+ @property
+ def obsoletes(self):
+ obsoletes = self.metadata.get("PKG_OBSOLETES", "").split()
- # No match was found at all
- return False
+ return set(obsoletes)
- def extract(self, path):
- raise NotImplementedError
+ def extract(self, path, prefix=None):
+ raise NotImplementedError, "%s" % type(self)
#!/usr/bin/python
-import sys
-
from file import FilePackage
class BinaryPackage(FilePackage):
def arch(self):
return self.metadata.get("PKG_ARCH")
- @property
- def provides(self):
- if not hasattr(self, "__provides"):
- # Get automatic provides
- provides = self._provides
-
- # Add other provides
- for prov in self.metadata.get("PKG_PROVIDES", "").split():
- provides.add(prov)
-
- self.__provides = provides
-
- return self.__provides
-
@property
def conflicts(self):
conflicts = self.metadata.get("PKG_CONFLICTS", "").split()
@property
def provides(self):
- if not hasattr(self, "__provides"):
- # Get automatic provides
- provides = self._provides
+ provides = self.metadata.get("provides", "").split()
- # Add other provides
- for prov in self.metadata.get("provides", "").split():
- provides.add(prov)
-
- self.__provides = provides
-
- return self.__provides
+ return set(provides)
@property
def requires(self):
- requires = self.metadata.get("requires")
-
- if requires:
- return requires.split()
+ requires = self.metadata.get("requires", "").split()
- return []
+ return set(requires)
@property
def conflicts(self):
- conflicts = self.metadata.get("conflicts")
+ conflicts = self.metadata.get("conflicts", "").split()
- if conflicts:
- return conflicts.split()
+ return set(conflicts)
+
+ @property
+ def obsoletes(self):
+ obsoletes = self.metadata.get("obsoletes", "").split()
- return []
+ return set(obsoletes)
@property
def hash1(self):
@property
def filelist(self):
- if not hasattr(self, "__filelist"):
- c = self.db.cursor()
+ c = self.db.cursor()
+ try:
c.execute("SELECT name FROM files WHERE pkg = ?", (self.id,))
- self.__filelist = []
- for f in c:
- self.__filelist.append(f["name"])
-
+ return [f["name"] for f in c]
+ finally:
c.close()
- return self.__filelist
-
def _does_provide_file(self, requires):
"""
A faster version to find a file in the database.
Return the requirements for the build.
"""
return self.metadata.get("PKG_REQUIRES", "").split()
-
- @property
- def provides(self):
- # XXX just a dummy
- return []
import logging
+import solver
+
from installed import InstalledRepository
from local import LocalRepository, LocalBuildRepository, LocalSourceRepository
from oddments import DummyRepository, FileSystemRepository
This is the place where repositories can be activated or deactivated.
"""
- def __init__(self, pakfire):
+ def __init__(self, pakfire, enable_repos=None, disable_repos=None):
self.pakfire = pakfire
self.config = pakfire.config
for repo_name, repo_args in self.config.get_repos():
self._parse(repo_name, repo_args)
+ # XXX need to process enable_repos and disable_repos here
+
+ # Update all indexes of the repositories (not force) so that we will
+ # always work with valid data.
+ self.update()
+
+ # Initialize the solver.
+ self.solver = solver.Solver(self.pakfire, self)
+
def __len__(self):
"""
Return the count of enabled repositories.
for repo in self.enabled:
repo.update(force=force)
+ def get_repo_by_name(self, name):
+ for repo in self.enabled:
+ if repo.name == name:
+ return repo
+
def get_all(self):
for repo in self.enabled:
for pkg in repo.get_all():
yield pkg
def get_by_name(self, name):
- for repo in self.enabled:
- for pkg in repo.get_by_name(name):
- yield pkg
+ #for repo in self.enabled:
+ # for pkg in repo.get_by_name(name):
+ # yield pkg
+ return self.solver.get_by_name(name)
def get_by_glob(self, pattern):
for repo in self.enabled:
for pkg in repo.get_by_glob(pattern):
yield pkg
- def get_by_provides(self, requires):
- if requires.type == "file":
- for pkg in self.get_by_file(requires.requires):
- yield pkg
-
- else:
- for repo in self.enabled:
- for pkg in repo.get_by_provides(requires):
- yield pkg
+ #def get_by_provides(self, requires):
+ # if requires.type == "file":
+ # for pkg in self.get_by_file(requires.requires):
+ # yield pkg
+ #
+ # else:
+ # for repo in self.enabled:
+ # for pkg in repo.get_by_provides(requires):
+ # yield pkg
+ get_by_provides = get_by_name
def get_by_requires(self, requires):
for repo in self.enabled:
for pkg in repo.get_by_requires(requires):
yield pkg
- def get_by_file(self, filename):
- for repo in self.enabled:
- for pkg in repo.get_by_file(filename):
- yield pkg
+ #def get_by_file(self, filename):
+ # for repo in self.enabled:
+ # for pkg in repo.get_by_file(filename):
+ # yield pkg
+ get_by_file = get_by_name
def get_by_group(self, group):
for repo in self.enabled:
if group in pkg.groups:
yield pkg
+ def get_by_friendly_name(self, name):
+ for pkg in self.packages:
+ if pkg.friendly_name == name:
+ return pkg
+
def search(self, pattern):
"""
Returns a list of packages, that match the given pattern,
Returns all packages.
"""
return self.index.packages
+
+ @property
+ def size(self):
+ """
+ Return the number of packages.
+ """
+ return self.index.size
+
+ @property
+ def filelist(self):
+ if hasattr(self.index, "filelist"):
+ return self.index.filelist
+
+ return {}
for pkg in self._packages:
yield pkg
+ @property
+ def size(self):
+ i = 0
+ for pkg in self.packages:
+ i += 1
+
+ return i
+
def update(self, force=False):
pass
c.close()
+ @property
+ def filelist(self):
+ c = self.db.cursor()
+ c.execute("SELECT pkg, name FROM files")
+
+ files = {}
+
+ for entry in c:
+ file = entry["name"]
+ try:
+ files[pkg_id].append(file)
+ except KeyError:
+ files[pkg_id] = [file,]
+
+ c.close()
+
+ return files
class InstalledIndex(DatabaseIndexFactory):
def open_database(self):
--- /dev/null
+#!/usr/bin/python
+
+import logging
+import satsolver
+import time
+
+from transaction import Transaction
+
+import pakfire.util as util
+
+from pakfire.constants import *
+from pakfire.i18n import _
+
+class Solver(object):
+ RELATIONS = (
+ (">=", satsolver.REL_GE,),
+ ("<=", satsolver.REL_LE,),
+ ("=" , satsolver.REL_EQ,),
+ ("<" , satsolver.REL_LT,),
+ (">" , satsolver.REL_GT,),
+ )
+
+ def __init__(self, pakfire, repos, arch=None):
+ self.pakfire = pakfire
+ self.repos = repos
+
+ if not arch:
+ arch = self.pakfire.distro.arch
+
+ # Mapping from solver ID to a package.
+ self.id2pkg = {}
+
+ # Initialize the pool and set the architecture.
+ self.pool = satsolver.Pool()
+ self.pool.set_arch(arch)
+
+ # Initialize all repositories.
+ self.repos = self.init_repos()
+
+ self.pool.prepare()
+
+ def create_relation(self, s):
+ s = str(s)
+
+ if s.startswith("/"):
+ return satsolver.Relation(self.pool, s)
+
+ for pattern, type in self.RELATIONS:
+ if not pattern in s:
+ continue
+
+ name, version = s.split(pattern, 1)
+
+ return satsolver.Relation(self.pool, name, type, version)
+
+ return satsolver.Relation(self.pool, s)
+
+ def init_repos(self):
+ repos = []
+
+ for repo in self.repos.enabled:
+ solvrepo = self.pool.create_repo(repo.name)
+ if repo.name == "installed":
+ self.pool.set_installed(solvrepo)
+
+ pb = util.make_progress(_("Loading %s") % repo.name, repo.size)
+ i = 0
+
+ for pkg in repo.get_all():
+ if pb:
+ i += 1
+ pb.update(i)
+
+ self.add_package(pkg)
+
+ logging.debug("Initialized new repo '%s' with %s packages." % \
+ (solvrepo.name(), solvrepo.size()))
+
+ if pb:
+ pb.finish()
+
+ repos.append(solvrepo)
+
+ return repos
+
+ def get_repo(self, name):
+ for repo in self.pool.repos():
+ if not repo.name() == name:
+ continue
+
+ return repo
+
+ def add_package(self, pkg, repo_name=None):
+ if not repo_name:
+ repo_name = pkg.repo.name
+
+ solvrepo = self.get_repo(repo_name)
+ assert solvrepo
+
+ solvable = satsolver.Solvable(solvrepo, str(pkg.name),
+ str(pkg.friendly_version), str(pkg.arch))
+
+ # Store the solver's ID.
+ self.id2pkg[solvable.id()] = pkg
+
+ # Set vendor.
+ solvable.set_vendor(pkg.vendor)
+
+ # Import all requires.
+ for req in pkg.requires:
+ rel = self.create_relation(req)
+ solvable.requires().add(rel)
+
+ # Import all provides.
+ for prov in pkg.provides:
+ rel = self.create_relation(prov)
+ solvable.provides().add(rel)
+
+ # Import all conflicts.
+ for conf in pkg.conflicts:
+ rel = self.create_relation(conf)
+ solvable.conflicts().add(rel)
+
+ # Import all obsoletes.
+ for obso in pkg.obsoletes:
+ rel = self.create_relation(obso)
+ solvable.obsoletes().add(rel)
+
+ # Import all files that are in the package.
+ rel = self.create_relation("solvable:filemarker")
+ solvable.provides().add(rel)
+ for file in pkg.filelist:
+ rel = self.create_relation(file)
+ solvable.provides().add(rel)
+
+ def create_request(self):
+ return self.pool.create_request()
+
+ def solve(self, request):
+ solver = self.pool.create_solver()
+ solver.set_allow_uninstall(True)
+
+ while True:
+ # Save start time.
+ time_start = time.time()
+
+ # Acutally run the solver.
+ res = solver.solve(request)
+
+ # Log time and status of the solver.
+ logging.debug("Solving took %s" % (time.time() - time_start))
+ logging.debug("Solver status: %s" % res)
+
+ # If the solver succeeded, we return the transaction and return.
+ if res:
+ # Return a resulting Transaction.
+ return Transaction.from_solver(self.pakfire, self, solver)
+
+ # Solver had an error and we now see what we can do:
+ logging.info("The solver returned %s problems." % solver.problems_count())
+
+ for p in solver.problems(request):
+ logging.info("Problem: %s" % p)
+ for s in p.solutions():
+ s = "%s" % s
+ logging.info(s.strip())
+
+ break
+
+ def solvables2packages(self, solvables):
+ pkgs = []
+
+ for solv in solvables:
+ pkg = self.id2pkg[solv.id()]
+ pkgs.append(pkg)
+
+ return pkgs
+
+ def get_by_provides(self, provides):
+ print provides
+ provides = self.create_relation(provides)
+
+ pkgs = self.solvables2packages(self.pool.providers(provides))
+
+ return pkgs
+
+ get_by_name = get_by_provides
--- /dev/null
+#!/usr/bin/python
+
+import logging
+import os
+import progressbar
+import sys
+
+import pakfire.packages as packages
+import pakfire.util as util
+
+from pakfire.i18n import _
+
+PKG_DUMP_FORMAT = " %-21s %-8s %-21s %-19s %5s "
+
+class ActionError(Exception):
+ pass
+
+
+class Action(object):
+ def __init__(self, pakfire, pkg, deps=None):
+ self.pakfire = pakfire
+ self.pkg = pkg
+ self.deps = deps or []
+
+ def __cmp__(self, other):
+ # XXX ugly
+ return cmp(self.__repr__(), other.__repr__())
+
+ def __repr__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.pkg.friendly_name)
+
+ def remove_dep(self, dep):
+ if not self.deps:
+ return
+
+ while dep in self.deps:
+ logging.debug("Removing dep %s from %s" % (dep, self))
+ self.deps.remove(dep)
+
+ def run(self):
+ raise NotImplementedError
+
+ @property
+ def local(self):
+ """
+ Reference to local repository (database).
+ """
+ return self.pakfire.repos.local
+
+
+class ActionCleanup(Action):
+ def gen_files(self):
+ """
+ Return a list of all files that are not in the package anymore
+ and so to be removed.
+ """
+ files = []
+
+ # Compare the filelist of the old and the new package and save the
+ # difference.
+
+ for f in self.pkg.old_package.filelist:
+ if f in self.pkg.filelist:
+ continue
+
+ # Save absolute path.
+ f = os.path.join(self.pakfire.path, f)
+ files.append(f)
+
+ return files
+
+ def remove_files(self, message, files):
+ if not files:
+ return
+
+ pb = util.make_progress(message, len(files))
+ i = 0
+
+ for f in self.gen_files():
+ # Update progress if any.
+ i += 1
+ if pb:
+ pb.update(i)
+
+ # Skip non-existant files (mabye the user removed it already?)
+ if not os.path.exists(f):
+ continue
+
+ logging.debug("Going to remove file: %s" % f)
+
+ try:
+ os.unlink(f)
+ except:
+ logging.critical("Could not remove file: %s. Do it manually." % f)
+
+ # XXX remove file from database
+
+ if pb:
+ pb.finish()
+
+ def run(self):
+ files = self.gen_files()
+
+ if not files:
+ return
+
+ self.remove_files(_("Cleanup: %s") % self.pkg.name, files)
+
+
+class ActionScript(Action):
+ def run(self):
+ pass # XXX TBD
+
+
+class ActionScriptPreIn(ActionScript):
+ pass
+
+
+class ActionScriptPostIn(ActionScript):
+ pass
+
+
+class ActionScriptPreUn(ActionScript):
+ pass
+
+
+class ActionScriptPostUn(ActionScript):
+ pass
+
+
+class ActionInstall(Action):
+ type = "install"
+
+ def extract(self, message, prefix=None):
+ logging.debug("Extracting package %s" % self.pkg.friendly_name)
+
+ if prefix is None:
+ prefix = self.pakfire.path
+
+ self.pkg.extract(message, prefix=prefix)
+
+ # Create package in the database
+ self.local.index.add_package(self.pkg)
+
+ def run(self):
+ self.extract(_("Installing: %s") % self.pkg.name)
+
+ self.pakfire.solver.add_package(self.pkg, "installed")
+
+
+class ActionUpdate(ActionInstall):
+ type = "update"
+
+ def run(self):
+ self.extract(_("Updating: %s") % self.pkg.name)
+
+
+class ActionRemove(ActionCleanup):
+ type = "remove"
+
+ def run(self):
+ files = self.pkg.filelist
+
+ if not files:
+ return
+
+ self.remove_files(_("Removing: %s") % self.pkg.name, files)
+
+
+class Transaction(object):
+ action_classes = [
+ ActionInstall,
+ ActionUpdate,
+ ActionRemove,
+ ]
+
+ def __init__(self, pakfire):
+ self.pakfire = pakfire
+ self.actions = []
+
+ self.downloads = []
+
+ @classmethod
+ def from_solver(cls, pakfire, solver1, solver2):
+ # Grab the original transaction object from the solver.
+ _transaction = solver2.transaction()
+
+ # Order the objects in the transaction in that way we will run the
+ # installation.
+ _transaction.order()
+
+ # Create a new instance of our own transaction class.
+ transaction = cls(pakfire)
+
+ for step in _transaction.steps():
+ action = step.type_s()
+ pkg = solver1.id2pkg[step.solvable().id()]
+
+ if not isinstance(pkg, packages.BinaryPackage):
+ transaction.downloads.append(pkg)
+
+ for action_cls in cls.action_classes:
+ if action_cls.type == action:
+ action = action_cls(pakfire, pkg)
+
+ if not isinstance(action, Action):
+ raise Exception, "Unknown action required: %s" % action
+
+ transaction.add_action(action)
+
+ return transaction
+
+ def download(self):
+ if not self.downloads:
+ return
+
+ i = 0
+ for pkg in self.downloads:
+ i += 1
+
+ # Actually download the package.
+ pkg_bin = pkg.download(text="(%2d/%02d): " % (i, len(self.downloads)))
+
+ # Replace the package in all actions where it matches.
+ actions = [a for a in self.actions if a.pkg == pkg]
+
+ for action in actions:
+ action.pkg = pkg_bin
+
+ # Reset packages to be downloaded.
+ self.downloads = []
+ print
+
+ @property
+ def installs(self):
+ return [a for a in self.actions if a.type == "install"]
+
+ @property
+ def removes(self):
+ return [a for a in self.actions if a.type == "remove"]
+
+ @property
+ def updates(self):
+ return [a for a in self.actions if a.type == "update"]
+
+ def dump_pkg(self, pkg):
+ ret = []
+
+ name = pkg.name
+ if len(name) > 21:
+ ret.append(" %s" % name)
+ name = ""
+
+ ret.append(PKG_DUMP_FORMAT % (name, pkg.arch, pkg.friendly_version,
+ pkg.repo.name, util.format_size(pkg.size)))
+
+ return ret
+
+ def dump_pkgs(self, caption, pkgs):
+ if not pkgs:
+ return []
+
+ s = [caption,]
+ for pkg in sorted(pkgs):
+ s += self.dump_pkg(pkg)
+ s.append("")
+ return s
+
+ def dump(self, logger=None):
+ if not logger:
+ logger = logging.getLogger()
+
+ width = 80
+ line = "=" * width
+
+ s = []
+ s.append(line)
+ s.append(PKG_DUMP_FORMAT % (_("Package"), _("Arch"), _("Version"), _("Repository"), _("Size")))
+ s.append(line)
+
+ s += self.dump_pkgs(_("Installing:"), [a.pkg for a in self.installs])
+ s += self.dump_pkgs(_("Updating:"), [a.pkg for a in self.updates])
+ s += self.dump_pkgs(_("Removing:"), [a.pkg for a in self.removes])
+
+ s.append(_("Transaction Summary"))
+ s.append(line)
+
+ format = "%-20s %-4d %s"
+
+ if self.installs:
+ s.append(format % (_("Install"), len(self.installs), _("Package(s)")))
+
+ if self.updates:
+ s.append(format % (_("Updates"), len(self.updates), _("Package(s)")))
+
+ if self.removes:
+ s.append(format % (_("Remove"), len(self.removes), _("Package(s)")))
+
+ # Calculate the size of all files that need to be downloaded this this
+ # transaction.
+ download_size = sum([p.size for p in self.downloads])
+ if download_size:
+ s.append(_("Total download size: %s") % util.format_size(download_size))
+ s.append("")
+
+ for line in s:
+ logger.info(line)
+
+ def run_action(self, action):
+ try:
+ action.run()
+ except ActionError, e:
+ logging.error("Action finished with an error: %s - %s" % (action, e))
+
+ def add_action(self, action):
+ logging.debug("New action added: %s" % action)
+
+ self.actions.append(action)
+
+ def remove_action(self, action):
+ logging.debug("Removing action: %s" % action)
+
+ self.actions.remove(action)
+ for action in self.actions:
+ action.remove_dep(action)
+
+ def run(self):
+ # Download all packages.
+ self.download()
+
+ while True:
+ if not [a for a in self.actions]:
+ break
+
+ for action in self.actions:
+ if action.deps:
+ #logging.debug("Skipping %s which cannot be run now." % action)
+ continue
+
+ self.run_action(action)
+ self.remove_action(action)
+++ /dev/null
-#!/usr/bin/python
-
-import logging
-import os
-import progressbar
-import sys
-import tarfile
-
-import depsolve
-import packages
-import util
-
-from i18n import _
-
-class ActionError(Exception):
- pass
-
-
-class Action(object):
- def __init__(self, pakfire, pkg, deps=None):
- self.pakfire = pakfire
- self.pkg = pkg
- self.deps = deps or []
-
- def __cmp__(self, other):
- # XXX ugly
- return cmp(self.__repr__(), other.__repr__())
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, self.pkg.friendly_name)
-
- def remove_dep(self, dep):
- if not self.deps:
- return
-
- while dep in self.deps:
- logging.debug("Removing dep %s from %s" % (dep, self))
- self.deps.remove(dep)
-
- def run(self):
- raise NotImplementedError
-
- @property
- def local(self):
- """
- Reference to local repository (database).
- """
- return self.pakfire.repos.local
-
-
-class ActionCleanup(Action):
- def gen_files(self):
- """
- Return a list of all files that are not in the package anymore
- and so to be removed.
- """
- files = []
-
- # Compare the filelist of the old and the new package and save the
- # difference.
-
- for f in self.pkg.old_package.filelist:
- if f in self.pkg.filelist:
- continue
-
- # Save absolute path.
- f = os.path.join(self.pakfire.path, f)
- files.append(f)
-
- return files
-
- def remove_files(self, message, files):
- if not files:
- return
-
- pb = util.make_progress(message, len(files))
- i = 0
-
- for f in self.gen_files():
- # Update progress if any.
- i += 1
- if pb:
- pb.update(i)
-
- # Skip non-existant files (mabye the user removed it already?)
- if not os.path.exists(f):
- continue
-
- logging.debug("Going to remove file: %s" % f)
-
- try:
- os.unlink(f)
- except:
- logging.critical("Could not remove file: %s. Do it manually." % f)
-
- # XXX remove file from database
-
- if pb:
- pb.finish()
-
- def run(self):
- files = self.gen_files()
-
- if not files:
- return
-
- self.remove_files(_("Cleanup: %s") % self.pkg.name, files)
-
-
-class ActionScript(Action):
- def run(self):
- pass # XXX TBD
-
-
-class ActionScriptPreIn(ActionScript):
- pass
-
-
-class ActionScriptPostIn(ActionScript):
- pass
-
-
-class ActionScriptPreUn(ActionScript):
- pass
-
-
-class ActionScriptPostUn(ActionScript):
- pass
-
-
-class ActionInstall(Action):
- def extract(self, message, prefix=None):
- logging.debug("Extracting package %s" % self.pkg.friendly_name)
-
- if prefix is None:
- prefix = self.pakfire.path
-
- self.pkg.extract(message, prefix=prefix)
-
- # Create package in the database
- self.local.index.add_package(self.pkg)
-
- def run(self):
- self.extract(_("Installing: %s") % self.pkg.name)
-
-
-class ActionUpdate(ActionInstall):
- def run(self):
- self.extract(_("Updating: %s") % self.pkg.name)
-
-
-class ActionRemove(ActionCleanup):
- def run(self):
- files = self.pkg.filelist
-
- if not files:
- return
-
- self.remove_files(_("Removing: %s") % self.pkg.name, files)
-
-
-class TransactionSet(object):
- def __init__(self):
- self.installs = []
- self.install_deps = []
-
- self.updates = []
- self.update_deps = []
-
- self.removes = []
- self.remove_deps = []
-
- @property
- def download_lists(self):
- # All elements in these lists must be local.
- return (self.installs, self.install_deps, self.updates, self.update_deps)
-
- @property
- def downloads(self):
- """
- Return a list containing all packages that need to be downloaded.
- """
- pkgs = []
- for dl_list in self.download_lists:
- pkgs += dl_list
-
- pkgs.sort()
-
- for pkg in pkgs:
- # Skip all packages that are already local.
- if pkg.local:
- continue
-
- yield pkg
-
- def install(self, pkg, dep=False):
- logging.info(" --> Marking package for install: %s" % pkg.friendly_name)
-
- if dep:
- self.install_deps.append(pkg)
- else:
- self.installs.append(pkg)
-
- def remove(self, pkg, dep=False):
- logging.info(" --> Marking package for remove: %s" % pkg.friendly_name)
-
- if dep:
- self.remove_deps.append(pkg)
- else:
- self.removes.append(pkg)
-
- def update(self, pkg, dep=False):
- assert pkg.old_package
-
- logging.info(" --> Marking package for update: %s (was %s)" % \
- (pkg.friendly_name, pkg.old_package.friendly_version))
-
- if dep:
- self.update_deps.append(pkg)
- else:
- self.updates.append(pkg)
-
- def download(self):
- """
- Convert all packages to BinaryPackage.
- """
- pkgs = []
- for pkg in self.downloads:
- pkgs.append(pkg)
-
- # If there are no packages to download skip the rest.
- if not pkgs:
- return
-
- logging.info("Downloading packages:")
- i = 0
- for download in pkgs:
- i += 1
- pkg = download.download(text="(%2d/%02d): " % (i, len(pkgs)))
-
- for download_list in self.download_lists:
- if download in download_list:
- download_list.remove(download)
- download_list.append(pkg)
- break
-
- # Just an empty line to seperate the downloads from the extractions.
- logging.info("")
-
-
-class Transaction(object):
- def __init__(self, pakfire, ds):
- self.pakfire = pakfire
- self.ds = ds
-
- self._actions = []
-
- def _install_pkg(self, pkg):
- assert isinstance(pkg, packages.BinaryPackage)
-
- # XXX add dependencies for running the script here
- action_prein = ActionScriptPreIn(self.pakfire, pkg)
-
- action_install = ActionInstall(self.pakfire, pkg, deps=[action_prein])
-
- # XXX add dependencies for running the script here
- action_postin = ActionScriptPostIn(self.pakfire, pkg, deps=[action_install])
-
- for action in (action_prein, action_install, action_postin):
- self.add_action(action)
-
- def _update_pkg(self, pkg):
- assert isinstance(pkg, packages.BinaryPackage)
-
- action_update = ActionUpdate(self.pakfire, pkg)
-
- action_cleanup = ActionCleanup(self.pakfire, pkg, deps=[action_update])
-
- for action in (action_update, action_cleanup):
- self.add_action(action)
-
- def _remove_pkg(self, pkg):
- # XXX add scripts
- action_remove = ActionRemove(self.pakfire, pkg)
-
- for action in (action_remove):
- self.add_action(action)
-
- def populate(self):
- # Determine which packages we have to add
- # and which we have to remove.
-
- # Add all packages that need to be installed.
- for pkg in self.ds.ts.installs + self.ds.ts.install_deps:
- self._install_pkg(pkg)
-
- # Add all packages that need to be updated.
- for pkg in self.ds.ts.updates + self.ds.ts.update_deps:
- self._update_pkg(pkg)
-
- # Add all packages that need to be removed.
- for pkg in self.ds.ts.removes + self.ds.ts.remove_deps:
- self._remove_pkg(pkg)
-
- def add_action(self, action):
- logging.debug("New action added: %s" % action)
-
- self._actions.append(action)
-
- def remove_action(self, action):
- logging.debug("Removing action: %s" % action)
-
- self._actions.remove(action)
- for _action in self.actions:
- _action.remove_dep(action)
-
- @property
- def actions(self):
- for action in self._actions:
- yield action
-
- @property
- def packages(self):
- for action in self._actions:
- yield action.pkg
-
- def run_action(self, action):
- try:
- action.run()
- except ActionError, e:
- logging.error("Action finished with an error: %s - %s" % (action, e))
-
- def run(self):
- # Download all packages.
- self.ds.ts.download()
-
- # Create all the actions that need to be done.
- self.populate()
-
- while True:
- if not [a for a in self.actions]:
- break
-
- for action in self.actions:
- if action.deps:
- #logging.debug("Skipping %s which cannot be run now." % action)
- continue
-
- self.run_action(action)
- self.remove_action(action)
-
-pakfire/base.py
-pakfire/builder.py
-pakfire/cli.py
-pakfire/config.py
-pakfire/constants.py
-pakfire/depsolve.py
+pakfire/util.py
+pakfire/api.py
pakfire/distro.py
-pakfire/downloader.py
-pakfire/errors.py
-pakfire/i18n.py
-pakfire/__init__.py
-pakfire/logger.py
+pakfire/packages/util.py
pakfire/packages/base.py
-pakfire/packages/binary.py
-pakfire/packages/file.py
-pakfire/packages/__init__.py
-pakfire/packages/installed.py
-pakfire/packages/listing.py
pakfire/packages/make.py
-pakfire/packages/packager.py
+pakfire/packages/__init__.py
pakfire/packages/source.py
-pakfire/packages/util.py
+pakfire/packages/packager.py
+pakfire/packages/file.py
+pakfire/packages/installed.py
pakfire/packages/virtual.py
+pakfire/packages/listing.py
+pakfire/packages/binary.py
+pakfire/chroot.py
+pakfire/downloader.py
+pakfire/compress.py
+pakfire/base.py
+pakfire/i18n.py
+pakfire/__init__.py
+pakfire/server/base.py
+pakfire/server/slave.py
+pakfire/server/__init__.py
+pakfire/server/master.py
pakfire/repository/base.py
-pakfire/repository/cache.py
pakfire/repository/database.py
-pakfire/repository/index.py
pakfire/repository/__init__.py
-pakfire/repository/installed.py
+pakfire/repository/solver.py
+pakfire/repository/transaction.py
pakfire/repository/local.py
-pakfire/repository/metadata.py
-pakfire/repository/oddments.py
pakfire/repository/remote.py
-pakfire/transaction.py
-pakfire/util.py
-scripts/pakfire
+pakfire/repository/oddments.py
+pakfire/repository/metadata.py
+pakfire/repository/installed.py
+pakfire/repository/actions.py
+pakfire/repository/cache.py
+pakfire/repository/index.py
+pakfire/config.py
+pakfire/logger.py
+pakfire/builder.py
+pakfire/cli.py
+pakfire/errors.py
+pakfire/constants.py
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-04-23 12:44+0200\n"
+"POT-Creation-Date: 2011-04-29 21:17+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../pakfire/base.py:106 ../pakfire/base.py:137
-msgid "Is this okay?"
+#: ../pakfire/packages/base.py:67
+msgid "Name"
+msgstr ""
+
+#: ../pakfire/packages/base.py:68 ../pakfire/repository/transaction.py:278
+msgid "Arch"
msgstr ""
-#: ../pakfire/builder.py:208
+#: ../pakfire/packages/base.py:69 ../pakfire/repository/transaction.py:278
+msgid "Version"
+msgstr ""
+
+#: ../pakfire/packages/base.py:70
+msgid "Release"
+msgstr ""
+
+#: ../pakfire/packages/base.py:71 ../pakfire/repository/transaction.py:278
+msgid "Size"
+msgstr ""
+
+#: ../pakfire/packages/base.py:72
+msgid "Repo"
+msgstr ""
+
+#: ../pakfire/packages/base.py:73
+msgid "Summary"
+msgstr ""
+
+#: ../pakfire/packages/base.py:74
+msgid "Groups"
+msgstr ""
+
+#: ../pakfire/packages/base.py:75
+msgid "URL"
+msgstr ""
+
+#: ../pakfire/packages/base.py:76
+msgid "License"
+msgstr ""
+
+#: ../pakfire/packages/base.py:79
+msgid "Description"
+msgstr ""
+
+#: ../pakfire/packages/base.py:85
+msgid "UUID"
+msgstr ""
+
+#: ../pakfire/packages/base.py:86
+msgid "Build ID"
+msgstr ""
+
+#: ../pakfire/packages/base.py:87
+msgid "Build date"
+msgstr ""
+
+#: ../pakfire/packages/base.py:88
+msgid "Build host"
+msgstr ""
+
+#: ../pakfire/packages/base.py:90
+msgid "Provides"
+msgstr ""
+
+#: ../pakfire/packages/base.py:95
+msgid "Requires"
+msgstr ""
+
+#: ../pakfire/repository/solver.py:66
+#, python-format
+msgid "Loading %s"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:107
+#, python-format
+msgid "Cleanup: %s"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:146
+#, python-format
+msgid "Installing: %s"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:155
+#, python-format
+msgid "Updating: %s"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:167
+#, python-format
+msgid "Removing: %s"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:278
+msgid "Package"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:278 ../pakfire/cli.py:237
+msgid "Repository"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:281
+msgid "Installing:"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:282
+msgid "Updating:"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:283
+msgid "Removing:"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:285
+msgid "Transaction Summary"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:291
+msgid "Install"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:291
+#: ../pakfire/repository/transaction.py:294
+#: ../pakfire/repository/transaction.py:297
+msgid "Package(s)"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:294
+msgid "Updates"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:297
+msgid "Remove"
+msgstr ""
+
+#: ../pakfire/repository/transaction.py:303
+#, python-format
+msgid "Total download size: %s"
+msgstr ""
+
+#: ../pakfire/repository/index.py:335
+#, python-format
+msgid "%s: package database"
+msgstr ""
+
+#: ../pakfire/builder.py:254
#, python-format
msgid "Extracting: %s (source)"
msgstr ""
msgid "List all currently enabled repositories."
msgstr ""
-#: ../pakfire/cli.py:237 ../pakfire/depsolve.py:229
-msgid "Repository"
-msgstr ""
-
#: ../pakfire/cli.py:237
msgid "Enabled"
msgstr ""
#: ../pakfire/cli.py:498
msgid "Send a keepalive to the server."
msgstr ""
-
-#: ../pakfire/depsolve.py:229
-msgid "Package"
-msgstr ""
-
-#: ../pakfire/depsolve.py:229 ../pakfire/packages/base.py:72
-msgid "Arch"
-msgstr ""
-
-#: ../pakfire/depsolve.py:229 ../pakfire/packages/base.py:73
-msgid "Version"
-msgstr ""
-
-#: ../pakfire/depsolve.py:229 ../pakfire/packages/base.py:75
-msgid "Size"
-msgstr ""
-
-#: ../pakfire/depsolve.py:232
-msgid "Installing:"
-msgstr ""
-
-#: ../pakfire/depsolve.py:233
-msgid "Installing for dependencies:"
-msgstr ""
-
-#: ../pakfire/depsolve.py:234
-msgid "Updating:"
-msgstr ""
-
-#: ../pakfire/depsolve.py:235
-msgid "Updating for dependencies:"
-msgstr ""
-
-#: ../pakfire/depsolve.py:236
-msgid "Removing:"
-msgstr ""
-
-#: ../pakfire/depsolve.py:237
-msgid "Removing for dependencies:"
-msgstr ""
-
-#: ../pakfire/depsolve.py:239
-msgid "Transaction Summary"
-msgstr ""
-
-#: ../pakfire/depsolve.py:245
-msgid "Install"
-msgstr ""
-
-#: ../pakfire/depsolve.py:246 ../pakfire/depsolve.py:250
-#: ../pakfire/depsolve.py:254
-msgid "Package(s)"
-msgstr ""
-
-#: ../pakfire/depsolve.py:249
-msgid "Updates"
-msgstr ""
-
-#: ../pakfire/depsolve.py:253
-msgid "Remove"
-msgstr ""
-
-#: ../pakfire/depsolve.py:260
-#, python-format
-msgid "Total download size: %s"
-msgstr ""
-
-#: ../pakfire/packages/base.py:71
-msgid "Name"
-msgstr ""
-
-#: ../pakfire/packages/base.py:74
-msgid "Release"
-msgstr ""
-
-#: ../pakfire/packages/base.py:76
-msgid "Repo"
-msgstr ""
-
-#: ../pakfire/packages/base.py:77
-msgid "Summary"
-msgstr ""
-
-#: ../pakfire/packages/base.py:78
-msgid "Groups"
-msgstr ""
-
-#: ../pakfire/packages/base.py:79
-msgid "URL"
-msgstr ""
-
-#: ../pakfire/packages/base.py:80
-msgid "License"
-msgstr ""
-
-#: ../pakfire/packages/base.py:83
-msgid "Description"
-msgstr ""
-
-#: ../pakfire/packages/base.py:89
-msgid "UUID"
-msgstr ""
-
-#: ../pakfire/packages/base.py:90
-msgid "Build ID"
-msgstr ""
-
-#: ../pakfire/packages/base.py:91
-msgid "Build date"
-msgstr ""
-
-#: ../pakfire/packages/base.py:92
-msgid "Build host"
-msgstr ""
-
-#: ../pakfire/packages/base.py:94
-msgid "Provides"
-msgstr ""
-
-#: ../pakfire/packages/base.py:99
-msgid "Requires"
-msgstr ""
-
-#: ../pakfire/repository/index.py:310
-#, python-format
-msgid "%s: package database"
-msgstr ""
-
-#: ../pakfire/transaction.py:107
-#, python-format
-msgid "Cleanup: %s"
-msgstr ""
-
-#: ../pakfire/transaction.py:144
-#, python-format
-msgid "Installing: %s"
-msgstr ""
-
-#: ../pakfire/transaction.py:149
-#, python-format
-msgid "Updating: %s"
-msgstr ""
-
-#: ../pakfire/transaction.py:159
-#, python-format
-msgid "Removing: %s"
-msgstr ""