From 4bbf8d773be4af0ffb0c77dacf5cff82f96965a9 Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Thu, 6 Sep 2012 20:01:17 +0200 Subject: [PATCH] [entropy.client.trigger] implement support for automagic /usr/share/info/*/dir update --- lib/entropy/client/interfaces/package.py | 48 +++++++++++++++++++++++- lib/entropy/client/interfaces/trigger.py | 43 ++++++++++++++++++++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/lib/entropy/client/interfaces/package.py b/lib/entropy/client/interfaces/package.py index b412e3cd8..cfd6eb822 100644 --- a/lib/entropy/client/interfaces/package.py +++ b/lib/entropy/client/interfaces/package.py @@ -383,6 +383,23 @@ class Package: raise AttributeError("Action must be in %s" % ( self._valid_actions,)) + _INFO_EXTS = ( + const_convert_to_unicode(".gz"), + const_convert_to_unicode(".bz2") + ) + + def _get_info_directories(self): + """ + Return a list of `info` directories as declared in the + INFOPATH and INFODIR environment variable. + """ + info_dirs = os.getenv("INFOPATH", "").split(":") + info_dirs += os.getenv("INFODIR", "").split(":") + info_dirs = [const_convert_to_unicode( + os.path.normpath(x)) for x in info_dirs] + info_dirs.sort() + return info_dirs + @staticmethod def get_standard_fetch_disk_path(download): """ @@ -1842,6 +1859,7 @@ class Package: Body of the _remove_content_from_system() method. """ inst_repo = self._entropy.installed_repository() + info_dirs = self._get_info_directories() for _pkg_id, item, ftype in remove_content: @@ -1983,8 +2001,15 @@ class Package: continue # collect for Trigger - self.pkgmeta['affected_directories'].add( - os.path.dirname(item)) + dir_name = os.path.dirname(item) + self.pkgmeta['affected_directories'].add(dir_name) + + # account for info files, if any + if dir_name in info_dirs: + for _ext in self._INFO_EXTS: + if item.endswith(_ext): + self.pkgmeta['affected_infofiles'].add(item) + break # add its parent directory dirobj = const_convert_to_unicode( @@ -2422,6 +2447,8 @@ class Package: # this is needed to make postinstall trigger work properly self.pkgmeta['triggers']['install']['affected_directories'] = \ self.pkgmeta['affected_directories'] + self.pkgmeta['triggers']['install']['affected_infofiles'] = \ + self.pkgmeta['affected_infofiles'] # always set data['injected'] to False # installed packages database SHOULD never have more @@ -2599,6 +2626,7 @@ class Package: col_protect = misc_data['collisionprotect'] splitdebug, splitdebug_dirs = self.pkgmeta['splitdebug'], \ self.pkgmeta['splitdebug_dirs'] + info_dirs = self._get_info_directories() # setup image_dir properly image_dir = self.pkgmeta['imagedir'][:] @@ -2800,6 +2828,16 @@ class Package: self.pkgmeta['affected_directories'].add( rel_fromfile_dir_utf) + # account for info files, if any + if rel_fromfile_dir_utf in info_dirs: + rel_fromfile_utf = const_convert_to_unicode( + rel_fromfile) + for _ext in self._INFO_EXTS: + if rel_fromfile_utf.endswith(_ext): + self.pkgmeta['affected_infofiles'].add( + rel_fromfile_utf) + break + # splitdebug (.debug files) support # If splitdebug is not enabled, do not create # splitdebug directories and move on instead (return) @@ -4514,6 +4552,7 @@ class Package: # collects directories whose content has been modified # this information is then handed to the Trigger self.pkgmeta['affected_directories'] = set() + self.pkgmeta['affected_infofiles'] = set() self.pkgmeta['triggers']['remove'] = \ inst_repo.getTriggerData(idpackage) @@ -4522,6 +4561,8 @@ class Package: return 0 self.pkgmeta['triggers']['remove']['affected_directories'] = \ self.pkgmeta['affected_directories'] + self.pkgmeta['triggers']['remove']['affected_infofiles'] = \ + self.pkgmeta['affected_infofiles'] self.pkgmeta['triggers']['remove']['spm_repository'] = \ inst_repo.retrieveSpmRepository( @@ -4708,6 +4749,7 @@ class Package: # collects directories whose content has been modified # this information is then handed to the Trigger self.pkgmeta['affected_directories'] = set() + self.pkgmeta['affected_infofiles'] = set() # smartpackage ? self.pkgmeta['smartpackage'] = False @@ -4769,6 +4811,8 @@ class Package: # pass reference, not copy! nevva! self.pkgmeta['triggers']['remove']['affected_directories'] = \ self.pkgmeta['affected_directories'] + self.pkgmeta['triggers']['remove']['affected_infofiles'] = \ + self.pkgmeta['affected_infofiles'] self.pkgmeta['triggers']['remove']['spm_repository'] = \ inst_repo.retrieveSpmRepository(idpackage) diff --git a/lib/entropy/client/interfaces/trigger.py b/lib/entropy/client/interfaces/trigger.py index 11601771e..6761e0029 100644 --- a/lib/entropy/client/interfaces/trigger.py +++ b/lib/entropy/client/interfaces/trigger.py @@ -18,7 +18,7 @@ import codecs from entropy.client.interfaces.client import Client from entropy.const import etpConst, const_isunicode, etpSys, etpUi, \ const_convert_to_rawstring -from entropy.output import brown, bold, darkred, red +from entropy.output import brown, bold, darkred, red, teal, purple from entropy.i18n import _ import entropy.dep @@ -35,6 +35,7 @@ class Trigger: VALID_PHASES = ("setup", "preinstall", "postinstall", "preremove", "postremove",) + INSTALL_INFO_EXEC = "/usr/bin/install-info" def __init__(self, entropy_client, action, phase, package_metadata, action_metadata): @@ -142,6 +143,9 @@ class Trigger: if len(env_dirs) != len(env_dirs - cont_dirs): functions.insert(0, self._trigger_env_update) + if self._pkgdata['affected_infofiles']: + functions.append(self._trigger_infofile_install) + if self._pkgdata['trigger']: functions.append(self._trigger_call_ext_postinstall) return functions @@ -487,6 +491,43 @@ class Trigger: ) self._spm.environment_update() + def _trigger_infofile_install(self): + info_exec = Trigger.INSTALL_INFO_EXEC + if not os.path.isfile(info_exec): + self._entropy.logger.log( + "[Trigger]", + etpConst['logging']['normal_loglevel_id'], + "[POST] %s is not available" % (info_exec,) + ) + return 0 + if not os.access(info_exec, os.X_OK | os.R_OK): + self._entropy.logger.log( + "[Trigger]", + etpConst['logging']['normal_loglevel_id'], + "[POST] %s is not executable" % (info_exec,) + ) + return 0 + + env = os.environ.copy() + for info_file in self._pkgdata['affected_infofiles']: + self._entropy.output( + "%s: %s" % ( + teal(_("Installing info")), + info_file,), + importance = 0, + header = purple(" # ") + ) + info_root = os.path.dirname(info_file) + args = ( + info_exec, + "--dir-file=%s/dir" % (info_root,), + info_file) + proc = subprocess.Popen( + args, stdout = sys.stdout, stderr = sys.stderr, + env = env) + proc.wait() # ignore any error + return 0 + def _trigger_spm_postinstall(self): if self._spm is not None: self._entropy.output(