diff --git a/pisi/install.py b/pisi/install.py index 45015e19..ed7fd1de 100644 --- a/pisi/install.py +++ b/pisi/install.py @@ -49,7 +49,7 @@ class Installer: self.ask_reinstall = ask_reinstall self.check_requirements() self.check_relations() - self.reinstall() + self.check_reinstall() self.extract_install() self.store_pisi_files() if ctx.comard: @@ -81,11 +81,12 @@ class Installer: ' not satisfied') raise InstallError("Package not installable") - def reinstall(self): - "check reinstall, confirm action, and remove package if reinstall" + def check_reinstall(self): + "check reinstall, confirm action, and schedule reinstall" pkg = self.pkginfo + self.reinstall = False if ctx.installdb.is_installed(pkg.name): # is this a reinstallation? (iversion, irelease, ibuild) = ctx.installdb.get_version(pkg.name) @@ -130,15 +131,28 @@ class Installer: if not ctx.ui.confirm(x): raise InstallError('Package downgrade declined') - # remove old package then - operations.remove_single(pkg.name) + # schedule for reinstall + self.old_files = ctx.installdb.files(pkg.name) + self.reinstall = True + operations.run_preremove(pkg.name) def extract_install(self): "unzip package in place" ctx.ui.info('Extracting files,') self.package.extract_dir_flat('install', ctx.config.destdir) - + + if self.reinstall: + # remove left over files + new = set(map(lambda x: str(x.path), self.files.list)) + old = set(map(lambda x: str(x.path), self.old_files.list)) + leftover = old - new + old_fileinfo = {} + for fileinfo in self.old_files.list: + old_fileinfo[str(fileinfo.path)] = fileinfo + for path in leftover: + operations.remove_file( old_fileinfo[path] ) + def store_pisi_files(self): """put files.xml, metadata.xml, actions.py and COMAR scripts somewhere in the file system. We'll need these in future...""" @@ -179,6 +193,9 @@ class Installer: def update_databases(self): "update databases" + if self.reinstall: + operations.remove_db(self.metadata.package.name) + # installdb ctx.installdb.install(self.metadata.package.name, self.metadata.package.version, diff --git a/pisi/operations.py b/pisi/operations.py index b5f9dc03..33ddb4f0 100644 --- a/pisi/operations.py +++ b/pisi/operations.py @@ -21,6 +21,45 @@ from pisi.uri import URI # single package operations +# remove stuff + +def remove_file(fileinfo): + fpath = os.path.join(ctx.config.destdir, fileinfo.path) + # TODO: We have to store configuration files for futher + # usage. Currently we'are doing it like rpm does, saving + # with a prefix and leaving the user to edit it. In the future + # we'll have a plan for these configuration files. + if fileinfo.type == ctx.const.conf: + if os.path.isfile(fpath): + os.rename(fpath, fpath + ".pisi") + else: + # check if file is removed manually. + # And we don't remove directories! + # TODO: remove directory if there is nothing under it? + if os.path.isfile(fpath) or os.path.islink(fpath): + os.unlink(fpath) + else: + ctx.ui.warning('Not removing non-file, non-link %d' % fpath) + +def run_preremove(package_name): + + if ctx.comard: + com = ctx.comard + + # TODO: run preremove scripts... + # com.call("System.Package", "preremove") + com.remove(package_name) + while 1: + reply = com.read_cmd() + if reply[0] == com.RESULT: + break + elif reply[1] == com.ERROR: + raise Error, "COMAR.remove failed!" + +def remove_db(package_name): + ctx.installdb.remove(package_name) + packagedb.remove_package(package_name) #FIXME: this looks like a mistake! + def remove_single(package_name): """Remove a single package""" inst_packagedb = packagedb.inst_packagedb @@ -31,38 +70,13 @@ def remove_single(package_name): if not ctx.installdb.is_installed(package_name): raise Exception('Trying to remove nonexistent package ' + package_name) - if ctx.comard: - com = ctx.comard - -# TODO: run preremove scripts... -# com.call("System.Package", "preremove") - com.remove(package_name) - while 1: - reply = com.read_cmd() - if reply[0] == com.RESULT: - break - elif reply[1] == com.ERROR: - raise Error, "COMAR.remove failed!" - + + run_preremove(package_name) + for fileinfo in ctx.installdb.files(package_name).list: - fpath = os.path.join(ctx.config.destdir, fileinfo.path) - # TODO: We have to store configuration files for futher - # usage. Currently we'are doing it like rpm does, saving - # with a prefix and leaving the user to edit it. In the future - # we'll have a plan for these configuration files. - if fileinfo.type == ctx.const.conf: - if os.path.isfile(fpath): - os.rename(fpath, fpath + ".pisi") - else: - # check if file is removed manually. - # And we don't remove directories! - # FIXME: should give a warning if it is... - if os.path.isfile(fpath) or os.path.islink(fpath): - os.unlink(fpath) + remove_file(fileinfo) - - ctx.installdb.remove(package_name) - packagedb.remove_package(package_name) + remove_db(package_name) def install_single(pkg, upgrade = False): """install a single package from URI or ID"""