| # Copyright 1999-2020 Gentoo Authors |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| import logging |
| import textwrap |
| |
| import portage |
| from portage import os |
| from portage.emaint.modules.logs.logs import CleanLogs |
| from portage.news import count_unread_news, display_news_notifications |
| from portage.output import colorize |
| from portage.util._dyn_libs.display_preserved_libs import display_preserved_libs |
| from portage.util._info_files import chk_updated_info_files |
| |
| from .chk_updated_cfg_files import chk_updated_cfg_files |
| from .emergelog import emergelog |
| from ._flush_elog_mod_echo import _flush_elog_mod_echo |
| |
| |
| def clean_logs(settings): |
| |
| if "clean-logs" not in settings.features: |
| return |
| |
| logdir = settings.get("PORTAGE_LOGDIR") |
| if logdir is None or not os.path.isdir(logdir): |
| return |
| |
| cleanlogs = CleanLogs() |
| returncode, msgs = cleanlogs.clean(settings=settings) |
| if not returncode: |
| out = portage.output.EOutput() |
| for msg in msgs: |
| out.eerror(msg) |
| |
| |
| def display_news_notification(root_config, myopts): |
| if "news" not in root_config.settings.features: |
| return False |
| portdb = root_config.trees["porttree"].dbapi |
| vardb = root_config.trees["vartree"].dbapi |
| news_counts = count_unread_news(portdb, vardb) |
| if all(v == 0 for v in news_counts.values()): |
| return False |
| display_news_notifications(news_counts) |
| return True |
| |
| |
| def show_depclean_suggestion(): |
| out = portage.output.EOutput() |
| msg = ( |
| "After world updates, it is important to remove " |
| + "obsolete packages with emerge --depclean. Refer " |
| + "to `man emerge` for more information." |
| ) |
| for line in textwrap.wrap(msg, 72): |
| out.ewarn(line) |
| |
| |
| def post_emerge(myaction, myopts, myfiles, target_root, trees, mtimedb, retval): |
| """ |
| Misc. things to run at the end of a merge session. |
| |
| Update Info Files |
| Update Config Files |
| Update News Items |
| Commit mtimeDB |
| Display preserved libs warnings |
| |
| @param myaction: The action returned from parse_opts() |
| @type myaction: String |
| @param myopts: emerge options |
| @type myopts: dict |
| @param myfiles: emerge arguments |
| @type myfiles: list |
| @param target_root: The target EROOT for myaction |
| @type target_root: String |
| @param trees: A dictionary mapping each ROOT to it's package databases |
| @type trees: dict |
| @param mtimedb: The mtimeDB to store data needed across merge invocations |
| @type mtimedb: MtimeDB class instance |
| @param retval: Emerge's return value |
| @type retval: Int |
| """ |
| |
| root_config = trees[target_root]["root_config"] |
| vardbapi = trees[target_root]["vartree"].dbapi |
| settings = vardbapi.settings |
| info_mtimes = mtimedb["info"] |
| |
| # Load the most current variables from ${ROOT}/etc/profile.env |
| settings.unlock() |
| settings.reload() |
| settings.regenerate() |
| settings.lock() |
| |
| config_protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")) |
| infodirs = settings.get("INFOPATH", "").split(":") + settings.get( |
| "INFODIR", "" |
| ).split(":") |
| |
| os.chdir("/") |
| |
| if retval == os.EX_OK: |
| exit_msg = " *** exiting successfully." |
| else: |
| exit_msg = " *** exiting unsuccessfully with status '%s'." % retval |
| emergelog("notitles" not in settings.features, exit_msg) |
| |
| _flush_elog_mod_echo() |
| |
| if not vardbapi._pkgs_changed: |
| # GLEP 42 says to display news *after* an emerge --pretend |
| if "--pretend" in myopts: |
| display_news_notification(root_config, myopts) |
| # If vdb state has not changed then there's nothing else to do. |
| return |
| |
| vdb_path = os.path.join(root_config.settings["EROOT"], portage.VDB_PATH) |
| portage.util.ensure_dirs(vdb_path) |
| vdb_lock = None |
| if os.access(vdb_path, os.W_OK) and not "--pretend" in myopts: |
| vardbapi.lock() |
| vdb_lock = True |
| |
| if vdb_lock: |
| try: |
| if "noinfo" not in settings.features: |
| chk_updated_info_files(target_root, infodirs, info_mtimes) |
| mtimedb.commit() |
| finally: |
| if vdb_lock: |
| vardbapi.unlock() |
| |
| # Explicitly load and prune the PreservedLibsRegistry in order |
| # to ensure that we do not display stale data. |
| vardbapi._plib_registry.load() |
| |
| if vardbapi._plib_registry.hasEntries(): |
| if "--quiet" in myopts: |
| print() |
| print(colorize("WARN", "!!!") + " existing preserved libs found") |
| else: |
| print() |
| print(colorize("WARN", "!!!") + " existing preserved libs:") |
| display_preserved_libs(vardbapi, verbose="--verbose" in myopts) |
| print( |
| "Use " |
| + colorize("GOOD", "emerge @preserved-rebuild") |
| + " to rebuild packages using these libraries" |
| ) |
| |
| chk_updated_cfg_files(settings["EROOT"], config_protect) |
| |
| display_news_notification(root_config, myopts) |
| |
| postemerge = os.path.join( |
| settings["PORTAGE_CONFIGROOT"], portage.USER_CONFIG_PATH, "bin", "post_emerge" |
| ) |
| if os.access(postemerge, os.X_OK): |
| hook_retval = portage.process.spawn([postemerge], env=settings.environ()) |
| if hook_retval != os.EX_OK: |
| portage.util.writemsg_level( |
| " %s spawn failed of %s\n" |
| % ( |
| colorize("BAD", "*"), |
| postemerge, |
| ), |
| level=logging.ERROR, |
| noiselevel=-1, |
| ) |
| |
| clean_logs(settings) |
| |
| if "--quiet" not in myopts and myaction is None and "@world" in myfiles: |
| show_depclean_suggestion() |