]> git.ipfire.org Git - pakfire.git/commitdiff
Add support to remove content of packages in the filesystem.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 30 Jul 2011 19:21:32 +0000 (21:21 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 30 Jul 2011 19:21:32 +0000 (21:21 +0200)
pakfire/actions.py
pakfire/cli.py
pakfire/packages/base.py
pakfire/packages/file.py
pakfire/packages/installed.py
pakfire/repository/database.py
pakfire/transaction.py

index ac1cbc3ed5f580651f538a46a8e5d570324e710f..a4c77d9fa747550ab7fd137cfd052dbf3a6f3dd4 100644 (file)
@@ -10,7 +10,7 @@ from i18n import _
 class Action(object):
        def __init__(self, pakfire, pkg):
                self.pakfire = pakfire
-               self.pkg = pkg
+               self.pkg_solv = self.pkg = pkg
 
                # Try to get the binary version of the package from the cache if
                # any.
@@ -18,10 +18,6 @@ class Action(object):
                if binary_package:
                        self.pkg = binary_package
 
-       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)
 
@@ -98,16 +94,20 @@ class ActionUpdate(Action):
                self._extract(_("Updating"))
 
 
-class ActionRemove(ActionCleanup):
+class ActionRemove(Action):
        type = "erase"
 
-       def run(self):
-               files = self.pkg.filelist
+       def __init__(self, *args, **kwargs):
+               Action.__init__(self, *args, **kwargs)
 
-               if not files:
-                       return
+               # XXX This is ugly, but works for the moment.
+               self.pkg = self.local.index.db.get_package_from_solv(self.pkg_solv)
+               assert self.pkg
+
+       def run(self):
+               self.pkg.remove(_("Removing"), prefix=self.pakfire.path)
 
-               self.remove_files(_("Removing: %s") % self.pkg.name, files)
+               # XXX Remove package from database
 
 
 class ActionReinstall(Action):
index 87d747584b6342a23537d6bbd29e4954984557e1..0fc56e74e686623c8b141a1a3e81aef86b35f681 100644 (file)
@@ -329,6 +329,8 @@ class CliBuilder(Cli):
 
                sub_shell.add_argument("-a", "--arch",
                        help=_("Emulated architecture in the shell."))
+               sub_shell.add_argument("-m", "--mode", nargs="?", default="development",
+                       help=_("Mode to run in. Is either 'release' or 'development' (default)."))
 
        def parse_command_dist(self):
                # Implement the "dist" command.
@@ -382,7 +384,8 @@ class CliBuilder(Cli):
                        "arch" : self.args.arch,
                }
 
-               pakfire.shell(pkg, distro_config=distro_config, **self.pakfire_args)
+               pakfire.shell(pkg, builder_mode=self.args.mode,
+                       distro_config=distro_config, **self.pakfire_args)
 
        def handle_dist(self):
                # Get the packages from the command line options
index ecf7f99cf4410b61f26455cf52a1ab07ea91f45d..a068831a51860f0ab71b4520df04d44f3117efae 100644 (file)
@@ -2,12 +2,15 @@
 
 import datetime
 import logging
+import os
 import xml.sax.saxutils
 
 import util
 
 from pakfire.i18n import _
 
+from pakfire.util import make_progress
+
 class Package(object):
        def __init__(self, pakfire, repo=None):
                self.pakfire = pakfire
@@ -350,3 +353,75 @@ class Package(object):
 
        def extract(self, path, prefix=None):
                raise NotImplementedError, "%s" % repr(self)
+
+       def remove(self, message=None, prefix=None):
+               if prefix in ("/", None):
+                       prefix = ""
+
+               # Make two filelists. One contains all binary files that need to be
+               # removed, the other one contains the configuration files which are
+               # kept. files and configfiles are disjunct.
+               files = []
+               configfiles = self.configfiles
+
+               for file in self.filelist:
+                       if file in configfiles:
+                               continue
+
+                       assert file.startswith("/")
+                       files.append(file)
+
+               # Load progressbar.
+               pb = None
+               if message:
+                       message = "%-10s : %s" % (message, self.friendly_name)
+                       pb = make_progress(message, len(files), eta=False)
+
+               # Sort files by the length of their name to remove all files in
+               # a directory first and then check, if there are any files left.
+               files.sort(cmp=lambda x,y: cmp(len(x), len(y)), reverse=True)
+
+               i = 0
+               for _file in files:
+                       # Update progress.
+                       if pb:
+                               i += 1
+                               pb.update(i)
+
+                       logging.debug("Removing file: %s" % _file)
+
+                       if prefix:
+                               file = os.path.join(prefix, file[1:])
+                               assert file.startswith("%s/" % prefix)
+                       else:
+                               file = _file
+
+                       # If the file was removed by the user, we can skip it.
+                       if not os.path.exists(file):
+                               continue
+
+                       # Handle regular files and symlinks.
+                       if os.path.isfile(file) or os.path.islink(file):
+                               try:
+                                       os.remove(file)
+                               except OSError:
+                                       logging.error("Cannot remove file: %s. Remove manually." % _file)
+
+                       # Handle directories.
+                       # Skip removal if the directory is a mountpoint.
+                       elif os.path.isdir(file) and not os.path.ismount(file):
+                               # Try to remove the directory. If it is not empty, OSError is raised,
+                               # but we are okay with that.
+                               try:
+                                       os.rmdir(file)
+                               except OSError:
+                                       pass
+
+                       # Log all unhandled types.
+                       else:
+                               logging.warning("Cannot remove file: %s. Filetype is unhandled." % _file)
+
+               if pb:
+                       pb.finish()
+
+               # XXX Rename config files
index 3ee069dcf45dfc462aef939a1635294df87cfc37..a07cab99d1f95b28bb82c7ae015f91be9e857187 100644 (file)
@@ -305,6 +305,10 @@ class FilePackage(Package):
 
                return self.__filelist
 
+       @property
+       def configfiles(self):
+               return [] # XXX to be done
+
        @property
        def payload_compression(self):
                """
index 31b03b4f20787371955b283aedeaf4f005889d08..bf044af6d994629c8b14220ce647d431d746a006 100644 (file)
@@ -151,6 +151,10 @@ class DatabasePackage(Package):
                finally:
                        c.close()
 
+       @property
+       def configfiles(self):
+               return [] # XXX to be done
+
        def _does_provide_file(self, requires):
                """
                        A faster version to find a file in the database.
index 89579152a8fd104ba520678d3ee88925a0b72d7c..e6d5aa7cb920a17bbd76cf1bf216397dcf03a6dd 100644 (file)
@@ -227,3 +227,14 @@ class DatabaseLocal(Database):
                        yield packages.DatabasePackage(self.pakfire, self.repo, self, row)
 
                c.close()
+
+       def get_package_from_solv(self, solv_pkg):
+               c = self.cursor()
+               c.execute("SELECT * FROM packages WHERE uuid = ? LIMIT 1", (solv_pkg.uuid,))
+
+               try:
+                       for row in c:
+                               return packages.DatabasePackage(self.pakfire, self.repo, self, row)
+
+               finally:
+                       c.close()
index 944e6e1313ae1fc639790dabdc83b303b3a14d7d..5f22550799df20c664faff528d5f051fc5e34daf 100644 (file)
@@ -200,3 +200,5 @@ class Transaction(object):
                                action.run()
                        except ActionError, e:
                                logging.error("Action finished with an error: %s - %s" % (action, e))
+
+               logging.info("")