def emergelog(xterm_titles, mystr, short_msg=None): if _disable: return mystr = _unicode_decode(mystr) if short_msg is not None: short_msg = _unicode_decode(short_msg) if xterm_titles and short_msg: if "HOSTNAME" in os.environ: short_msg = os.environ["HOSTNAME"]+": "+short_msg xtermTitle(short_msg) try: file_path = os.path.join(_emerge_log_dir, 'emerge.log') existing_log = os.path.isfile(file_path) mylogfile = io.open(_unicode_encode(file_path, encoding=_encodings['fs'], errors='strict'), mode='a', encoding=_encodings['content'], errors='backslashreplace') if not existing_log: portage.util.apply_secpass_permissions(file_path, uid=portage.portage_uid, gid=portage.portage_gid, mode=0o660) mylock = portage.locks.lockfile(file_path) try: mylogfile.write(_log_fmt % (time.time(), mystr)) mylogfile.close() finally: portage.locks.unlockfile(mylock) except (IOError,OSError,portage.exception.PortageException) as e: if secpass >= 1: print("emergelog():",e, file=sys.stderr)
def emergelog(xterm_titles, mystr, short_msg=None): if _disable: return mystr = _unicode_decode(mystr) if short_msg is not None: short_msg = _unicode_decode(short_msg) if xterm_titles and short_msg: if "HOSTNAME" in os.environ: short_msg = os.environ["HOSTNAME"]+": "+short_msg xtermTitle(short_msg) try: file_path = os.path.join(_emerge_log_dir, 'emerge.log') existing_log = os.path.exists(file_path) mylogfile = io.open(_unicode_encode(file_path, encoding=_encodings['fs'], errors='strict'), mode='a', encoding=_encodings['content'], errors='backslashreplace') if not existing_log: portage.util.apply_secpass_permissions(file_path, uid=portage.portage_uid, gid=portage.portage_gid, mode=0o660) mylock = portage.locks.lockfile(file_path) try: mylogfile.write("%.0f: %s\n" % (time.time(), mystr)) mylogfile.close() finally: portage.locks.unlockfile(mylock) except (IOError,OSError,portage.exception.PortageException) as e: if secpass >= 1: portage.util.writemsg("emergelog(): %s\n" % (e,), noiselevel=-1)
def emergelog(xterm_titles, mystr, short_msg=None): if _disable: return mystr = portage._unicode_decode(mystr) if short_msg is not None: short_msg = portage._unicode_decode(short_msg) if xterm_titles and short_msg: if "HOSTNAME" in os.environ: short_msg = os.environ["HOSTNAME"] + ": " + short_msg xtermTitle(short_msg) try: file_path = os.path.join(_emerge_log_dir, 'emerge.log') mylogfile = codecs.open(_unicode_encode(file_path, encoding=_encodings['fs'], errors='strict'), mode='a', encoding=_encodings['content'], errors='backslashreplace') portage.util.apply_secpass_permissions(file_path, uid=portage.portage_uid, gid=portage.portage_gid, mode=0o660) mylock = None try: mylock = portage.locks.lockfile(mylogfile) # seek because we may have gotten held up by the lock. # if so, we may not be positioned at the end of the file. mylogfile.seek(0, 2) mylogfile.write(str(time.time())[:10] + ": " + mystr + "\n") mylogfile.flush() finally: if mylock: portage.locks.unlockfile(mylock) mylogfile.close() except (IOError, OSError, portage.exception.PortageException) as e: if secpass >= 1: print("emergelog():", e, file=sys.stderr)
def emergelog(xterm_titles, mystr, short_msg=None): if _disable: return mystr = _unicode_decode(mystr) if short_msg is not None: short_msg = _unicode_decode(short_msg) if xterm_titles and short_msg: if "HOSTNAME" in os.environ: short_msg = os.environ["HOSTNAME"] + ": " + short_msg xtermTitle(short_msg) try: file_path = os.path.join(_emerge_log_dir, "emerge.log") existing_log = os.path.exists(file_path) mylogfile = io.open( _unicode_encode(file_path, encoding=_encodings["fs"], errors="strict"), mode="a", encoding=_encodings["content"], errors="backslashreplace", ) if not existing_log: portage.util.apply_secpass_permissions(file_path, uid=portage.portage_uid, gid=portage.portage_gid, mode=0o660) mylock = portage.locks.lockfile(file_path) try: mylogfile.write("%.0f: %s\n" % (time.time(), mystr)) mylogfile.close() finally: portage.locks.unlockfile(mylock) except (IOError, OSError, portage.exception.PortageException) as e: if secpass >= 1: portage.util.writemsg("emergelog(): %s\n" % (e, ), noiselevel=-1)
def emergelog(xterm_titles, mystr, short_msg=None): if _disable: return mystr = portage._unicode_decode(mystr) if short_msg is not None: short_msg = portage._unicode_decode(short_msg) if xterm_titles and short_msg: if "HOSTNAME" in os.environ: short_msg = os.environ["HOSTNAME"]+": "+short_msg xtermTitle(short_msg) try: file_path = os.path.join(_emerge_log_dir, 'emerge.log') mylogfile = codecs.open(_unicode_encode(file_path, encoding=_encodings['fs'], errors='strict'), mode='a', encoding=_encodings['content'], errors='backslashreplace') portage.util.apply_secpass_permissions(file_path, uid=portage.portage_uid, gid=portage.portage_gid, mode=0o660) mylock = None try: mylock = portage.locks.lockfile(mylogfile) # seek because we may have gotten held up by the lock. # if so, we may not be positioned at the end of the file. mylogfile.seek(0, 2) mylogfile.write(str(time.time())[:10]+": "+mystr+"\n") mylogfile.flush() finally: if mylock: portage.locks.unlockfile(mylock) mylogfile.close() except (IOError,OSError,portage.exception.PortageException) as e: if secpass >= 1: print("emergelog():",e, file=sys.stderr)
def _display_status(self): # Don't use len(self._completed_tasks) here since that also # can include uninstall tasks. curval_str = str(self.curval) maxval_str = str(self.maxval) running_str = str(self.running) failed_str = str(self.failed) load_avg_str = self._load_avg_str() color_output = StringIO() plain_output = StringIO() style_file = portage.output.ConsoleStyleFile(color_output) style_file.write_listener = plain_output style_writer = portage.output.StyleWriter(file=style_file, maxcol=9999) style_writer.style_listener = style_file.new_styles f = formatter.AbstractFormatter(style_writer) number_style = "INFORM" f.add_literal_data(_unicode_decode("Jobs: ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(curval_str)) f.pop_style() f.add_literal_data(_unicode_decode(" of ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(maxval_str)) f.pop_style() f.add_literal_data(_unicode_decode(" complete")) if self.running: f.add_literal_data(_unicode_decode(", ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(running_str)) f.pop_style() f.add_literal_data(_unicode_decode(" running")) if self.failed: f.add_literal_data(_unicode_decode(", ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(failed_str)) f.pop_style() f.add_literal_data(_unicode_decode(" failed")) padding = self._jobs_column_width - len(plain_output.getvalue()) if padding > 0: f.add_literal_data(padding * _unicode_decode(" ")) f.add_literal_data(_unicode_decode("Load avg: ")) f.add_literal_data(_unicode_decode(load_avg_str)) # Truncate to fit width, to avoid making the terminal scroll if the # line overflows (happens when the load average is large). plain_output = plain_output.getvalue() if self._isatty and len(plain_output) > self.width: # Use plain_output here since it's easier to truncate # properly than the color output which contains console # color codes. self._update(plain_output[:self.width]) else: self._update(color_output.getvalue()) if self.xterm_titles: xtermTitle(" ".join(plain_output.split()))
def _display_status(self): # Don't use len(self._completed_tasks) here since that also # can include uninstall tasks. curval_str = "%s" % (self.curval, ) maxval_str = "%s" % (self.maxval, ) running_str = "%s" % (self.running, ) failed_str = "%s" % (self.failed, ) load_avg_str = self._load_avg_str() color_output = io.StringIO() plain_output = io.StringIO() style_file = portage.output.ConsoleStyleFile(color_output) style_file.write_listener = plain_output style_writer = portage.output.StyleWriter(file=style_file, maxcol=9999) style_writer.style_listener = style_file.new_styles f = formatter.AbstractFormatter(style_writer) number_style = "INFORM" f.add_literal_data("Jobs: ") f.push_style(number_style) f.add_literal_data(curval_str) f.pop_style() f.add_literal_data(" of ") f.push_style(number_style) f.add_literal_data(maxval_str) f.pop_style() f.add_literal_data(" complete") if self.running: f.add_literal_data(", ") f.push_style(number_style) f.add_literal_data(running_str) f.pop_style() f.add_literal_data(" running") if self.failed: f.add_literal_data(", ") f.push_style(number_style) f.add_literal_data(failed_str) f.pop_style() f.add_literal_data(" failed") padding = self._jobs_column_width - len(plain_output.getvalue()) if padding > 0: f.add_literal_data(padding * " ") f.add_literal_data("Load avg: ") f.add_literal_data(load_avg_str) # Truncate to fit width, to avoid making the terminal scroll if the # line overflows (happens when the load average is large). plain_output = plain_output.getvalue() if self._isatty and len(plain_output) > self.width: # Use plain_output here since it's easier to truncate # properly than the color output which contains console # color codes. self._update(plain_output[:self.width]) else: self._update(color_output.getvalue()) if self.xterm_titles: # If the HOSTNAME variable is exported, include it # in the xterm title, just like emergelog() does. # See bug #390699. title_str = " ".join(plain_output.split()) hostname = os.environ.get("HOSTNAME") if hostname is not None: title_str = "%s: %s" % (hostname, title_str) xtermTitle(title_str)
def emsg(msg, config): if config['showtitles']: xtermTitle(msg) if config['verbose'] == -1: return print(green(" *"), msg)
def emerge_main(): global portage # NFC why this is necessary now - genone portage._disable_legacy_globals() # Disable color until we're sure that it should be enabled (after # EMERGE_DEFAULT_OPTS has been parsed). portage.output.havecolor = 0 # This first pass is just for options that need to be known as early as # possible, such as --config-root. They will be parsed again later, # together with EMERGE_DEFAULT_OPTS (which may vary depending on the # the value of --config-root). myaction, myopts, myfiles = parse_opts(sys.argv[1:], silent=True) if "--debug" in myopts: os.environ["PORTAGE_DEBUG"] = "1" if "--config-root" in myopts: os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"] if "--root" in myopts: os.environ["ROOT"] = myopts["--root"] if "--accept-properties" in myopts: os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"] # Portage needs to ensure a sane umask for the files it creates. os.umask(0o22) settings, trees, mtimedb = load_emerge_config() portdb = trees[settings["ROOT"]]["porttree"].dbapi rval = profile_check(trees, myaction) if rval != os.EX_OK: return rval if myaction not in ('help', 'info', 'version') and \ _global_updates(trees, mtimedb["updates"]): mtimedb.commit() # Reload the whole config from scratch. settings, trees, mtimedb = load_emerge_config(trees=trees) portdb = trees[settings["ROOT"]]["porttree"].dbapi xterm_titles = "notitles" not in settings.features if xterm_titles: xtermTitle("emerge") tmpcmdline = [] if "--ignore-default-opts" not in myopts: tmpcmdline.extend(settings["EMERGE_DEFAULT_OPTS"].split()) tmpcmdline.extend(sys.argv[1:]) myaction, myopts, myfiles = parse_opts(tmpcmdline) if "--digest" in myopts: os.environ["FEATURES"] = os.environ.get("FEATURES","") + " digest" # Reload the whole config from scratch so that the portdbapi internal # config is updated with new FEATURES. settings, trees, mtimedb = load_emerge_config(trees=trees) portdb = trees[settings["ROOT"]]["porttree"].dbapi adjust_configs(myopts, trees) apply_priorities(settings) if myaction == 'version': writemsg_stdout(getportageversion( settings["PORTDIR"], settings["ROOT"], settings.profile_path, settings["CHOST"], trees[settings["ROOT"]]["vartree"].dbapi) + '\n', noiselevel=-1) return 0 elif myaction == 'help': _emerge.help.help(myopts, portage.output.havecolor) return 0 spinner = stdout_spinner() if "candy" in settings.features: spinner.update = spinner.update_scroll if "--quiet" not in myopts: portage.deprecated_profile_check(settings=settings) repo_name_check(trees) repo_name_duplicate_check(trees) config_protect_check(trees) check_procfs() if "getbinpkg" in settings.features: myopts["--getbinpkg"] = True if "--getbinpkgonly" in myopts: myopts["--getbinpkg"] = True if "--getbinpkgonly" in myopts: myopts["--usepkgonly"] = True if "--getbinpkg" in myopts: myopts["--usepkg"] = True if "--usepkgonly" in myopts: myopts["--usepkg"] = True if "buildpkg" in settings.features or "--buildpkgonly" in myopts: myopts["--buildpkg"] = True if "--buildpkgonly" in myopts: # --buildpkgonly will not merge anything, so # it cancels all binary package options. for opt in ("--getbinpkg", "--getbinpkgonly", "--usepkg", "--usepkgonly"): myopts.pop(opt, None) for mytrees in trees.values(): mydb = mytrees["porttree"].dbapi # Freeze the portdbapi for performance (memoize all xmatch results). mydb.freeze() if "--usepkg" in myopts: # Populate the bintree with current --getbinpkg setting. # This needs to happen before expand_set_arguments(), in case # any sets use the bintree. mytrees["bintree"].populate( getbinpkgs="--getbinpkg" in myopts) del mytrees, mydb if "moo" in myfiles: print(""" Larry loves Gentoo (""" + platform.system() + """) _______________________ < Have you mooed today? > ----------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || """) for x in myfiles: ext = os.path.splitext(x)[1] if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)): print(colorize("BAD", "\n*** emerging by path is broken and may not always work!!!\n")) break root_config = trees[settings["ROOT"]]["root_config"] if myaction == "list-sets": writemsg_stdout("".join("%s\n" % s for s in sorted(root_config.sets))) return os.EX_OK ensure_required_sets(trees) # only expand sets for actions taking package arguments oldargs = myfiles[:] if myaction in ("clean", "config", "depclean", "info", "prune", "unmerge", None): myfiles, retval = expand_set_arguments(myfiles, myaction, root_config) if retval != os.EX_OK: return retval # Need to handle empty sets specially, otherwise emerge will react # with the help message for empty argument lists if oldargs and not myfiles: print("emerge: no targets left after set expansion") return 0 if ("--tree" in myopts) and ("--columns" in myopts): print("emerge: can't specify both of \"--tree\" and \"--columns\".") return 1 if '--emptytree' in myopts and '--noreplace' in myopts: writemsg_level("emerge: can't specify both of " + \ "\"--emptytree\" and \"--noreplace\".\n", level=logging.ERROR, noiselevel=-1) return 1 if ("--quiet" in myopts): spinner.update = spinner.update_quiet portage.util.noiselimit = -1 if "--fetch-all-uri" in myopts: myopts["--fetchonly"] = True if "--skipfirst" in myopts and "--resume" not in myopts: myopts["--resume"] = True # Allow -p to remove --ask if "--pretend" in myopts: myopts.pop("--ask", None) # forbid --ask when not in a terminal # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway. if ("--ask" in myopts) and (not sys.stdin.isatty()): portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n", noiselevel=-1) return 1 if settings.get("PORTAGE_DEBUG", "") == "1": spinner.update = spinner.update_quiet portage.debug=1 if "python-trace" in settings.features: import portage.debug portage.debug.set_trace(True) if not ("--quiet" in myopts): if '--nospinner' in myopts or \ settings.get('TERM') == 'dumb' or \ not sys.stdout.isatty(): spinner.update = spinner.update_basic if "--debug" in myopts: print("myaction", myaction) print("myopts", myopts) if not myaction and not myfiles and "--resume" not in myopts: _emerge.help.help(myopts, portage.output.havecolor) return 1 pretend = "--pretend" in myopts fetchonly = "--fetchonly" in myopts or "--fetch-all-uri" in myopts buildpkgonly = "--buildpkgonly" in myopts # check if root user is the current user for the actions where emerge needs this if portage.secpass < 2: # We've already allowed "--version" and "--help" above. if "--pretend" not in myopts and myaction not in ("search","info"): need_superuser = myaction in ('clean', 'depclean', 'deselect', 'prune', 'unmerge') or not \ (fetchonly or \ (buildpkgonly and secpass >= 1) or \ myaction in ("metadata", "regen") or \ (myaction == "sync" and os.access(settings["PORTDIR"], os.W_OK))) if portage.secpass < 1 or \ need_superuser: if need_superuser: access_desc = "superuser" else: access_desc = "portage group" # Always show portage_group_warning() when only portage group # access is required but the user is not in the portage group. from portage.data import portage_group_warning if "--ask" in myopts: myopts["--pretend"] = True del myopts["--ask"] print(("%s access is required... " + \ "adding --pretend to options\n") % access_desc) if portage.secpass < 1 and not need_superuser: portage_group_warning() else: sys.stderr.write(("emerge: %s access is required\n") \ % access_desc) if portage.secpass < 1 and not need_superuser: portage_group_warning() return 1 disable_emergelog = False for x in ("--pretend", "--fetchonly", "--fetch-all-uri"): if x in myopts: disable_emergelog = True break if myaction in ("search", "info"): disable_emergelog = True if disable_emergelog: """ Disable emergelog for everything except build or unmerge operations. This helps minimize parallel emerge.log entries that can confuse log parsers. We especially want it disabled during parallel-fetch, which uses --resume --fetchonly.""" _emerge.emergelog._disable = True else: if 'EMERGE_LOG_DIR' in settings: try: # At least the parent needs to exist for the lock file. portage.util.ensure_dirs(settings['EMERGE_LOG_DIR']) except portage.exception.PortageException as e: writemsg_level("!!! Error creating directory for " + \ "EMERGE_LOG_DIR='%s':\n!!! %s\n" % \ (settings['EMERGE_LOG_DIR'], e), noiselevel=-1, level=logging.ERROR) else: global _emerge_log_dir _emerge_log_dir = settings['EMERGE_LOG_DIR'] if not "--pretend" in myopts: emergelog(xterm_titles, "Started emerge on: "+\ _unicode_decode( time.strftime("%b %d, %Y %H:%M:%S", time.localtime()), encoding=_encodings['content'], errors='replace')) myelogstr="" if myopts: myelogstr=" ".join(myopts) if myaction: myelogstr+=" "+myaction if myfiles: myelogstr += " " + " ".join(oldargs) emergelog(xterm_titles, " *** emerge " + myelogstr) del oldargs def emergeexitsig(signum, frame): signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGTERM, signal.SIG_IGN) portage.util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum}) sys.exit(100+signum) signal.signal(signal.SIGINT, emergeexitsig) signal.signal(signal.SIGTERM, emergeexitsig) def emergeexit(): """This gets out final log message in before we quit.""" if "--pretend" not in myopts: emergelog(xterm_titles, " *** terminating.") if xterm_titles: xtermTitleReset() portage.atexit_register(emergeexit) if myaction in ("config", "metadata", "regen", "sync"): if "--pretend" in myopts: sys.stderr.write(("emerge: The '%s' action does " + \ "not support '--pretend'.\n") % myaction) return 1 if "sync" == myaction: return action_sync(settings, trees, mtimedb, myopts, myaction) elif "metadata" == myaction: action_metadata(settings, portdb, myopts) elif myaction=="regen": validate_ebuild_environment(trees) return action_regen(settings, portdb, myopts.get("--jobs"), myopts.get("--load-average")) # HELP action elif "config"==myaction: validate_ebuild_environment(trees) action_config(settings, trees, myopts, myfiles) # SEARCH action elif "search"==myaction: validate_ebuild_environment(trees) action_search(trees[settings["ROOT"]]["root_config"], myopts, myfiles, spinner) elif myaction in ('clean', 'depclean', 'deselect', 'prune', 'unmerge'): validate_ebuild_environment(trees) rval = action_uninstall(settings, trees, mtimedb["ldpath"], myopts, myaction, myfiles, spinner) if not (myaction == 'deselect' or buildpkgonly or fetchonly or pretend): post_emerge(root_config, myopts, mtimedb, rval) return rval elif myaction == 'info': # Ensure atoms are valid before calling unmerge(). vardb = trees[settings["ROOT"]]["vartree"].dbapi portdb = trees[settings["ROOT"]]["porttree"].dbapi bindb = trees[settings["ROOT"]]["bintree"].dbapi valid_atoms = [] for x in myfiles: if is_valid_package_atom(x): try: #look at the installed files first, if there is no match #look at the ebuilds, since EAPI 4 allows running pkg_info #on non-installed packages valid_atom = dep_expand(x, mydb=vardb, settings=settings) if valid_atom.cp.split("/")[0] == "null": valid_atom = dep_expand(x, mydb=portdb, settings=settings) if valid_atom.cp.split("/")[0] == "null" and "--usepkg" in myopts: valid_atom = dep_expand(x, mydb=bindb, settings=settings) valid_atoms.append(valid_atom) except portage.exception.AmbiguousPackageName as e: msg = "The short ebuild name \"" + x + \ "\" is ambiguous. Please specify " + \ "one of the following " + \ "fully-qualified ebuild names instead:" for line in textwrap.wrap(msg, 70): writemsg_level("!!! %s\n" % (line,), level=logging.ERROR, noiselevel=-1) for i in e[0]: writemsg_level(" %s\n" % colorize("INFORM", i), level=logging.ERROR, noiselevel=-1) writemsg_level("\n", level=logging.ERROR, noiselevel=-1) return 1 continue msg = [] msg.append("'%s' is not a valid package atom." % (x,)) msg.append("Please check ebuild(5) for full details.") writemsg_level("".join("!!! %s\n" % line for line in msg), level=logging.ERROR, noiselevel=-1) return 1 return action_info(settings, trees, myopts, valid_atoms) # "update", "system", or just process files: else: validate_ebuild_environment(trees) for x in myfiles: if x.startswith(SETPREFIX) or \ is_valid_package_atom(x): continue if x[:1] == os.sep: continue try: os.lstat(x) continue except OSError: pass msg = [] msg.append("'%s' is not a valid package atom." % (x,)) msg.append("Please check ebuild(5) for full details.") writemsg_level("".join("!!! %s\n" % line for line in msg), level=logging.ERROR, noiselevel=-1) return 1 if "--pretend" not in myopts: display_news_notification(root_config, myopts) retval = action_build(settings, trees, mtimedb, myopts, myaction, myfiles, spinner) root_config = trees[settings["ROOT"]]["root_config"] post_emerge(root_config, myopts, mtimedb, retval) return retval
def _display_status(self): # Don't use len(self._completed_tasks) here since that also # can include uninstall tasks. curval_str = str(self.curval) maxval_str = str(self.maxval) running_str = str(self.running) failed_str = str(self.failed) load_avg_str = self._load_avg_str() color_output = io.StringIO() plain_output = io.StringIO() style_file = portage.output.ConsoleStyleFile(color_output) style_file.write_listener = plain_output style_writer = portage.output.StyleWriter(file=style_file, maxcol=9999) style_writer.style_listener = style_file.new_styles f = formatter.AbstractFormatter(style_writer) number_style = "INFORM" f.add_literal_data(_unicode_decode("Jobs: ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(curval_str)) f.pop_style() f.add_literal_data(_unicode_decode(" of ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(maxval_str)) f.pop_style() f.add_literal_data(_unicode_decode(" complete")) if self.running: f.add_literal_data(_unicode_decode(", ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(running_str)) f.pop_style() f.add_literal_data(_unicode_decode(" running")) if self.failed: f.add_literal_data(_unicode_decode(", ")) f.push_style(number_style) f.add_literal_data(_unicode_decode(failed_str)) f.pop_style() f.add_literal_data(_unicode_decode(" failed")) padding = self._jobs_column_width - len(plain_output.getvalue()) if padding > 0: f.add_literal_data(padding * _unicode_decode(" ")) f.add_literal_data(_unicode_decode("Load avg: ")) f.add_literal_data(_unicode_decode(load_avg_str)) # Truncate to fit width, to avoid making the terminal scroll if the # line overflows (happens when the load average is large). plain_output = plain_output.getvalue() if self._isatty and len(plain_output) > self.width: # Use plain_output here since it's easier to truncate # properly than the color output which contains console # color codes. self._update(plain_output[:self.width]) else: self._update(color_output.getvalue()) if self.xterm_titles: xtermTitle(" ".join(plain_output.split()))
def _display_status(self): # Don't use len(self._completed_tasks) here since that also # can include uninstall tasks. curval_str = "%s" % (self.curval,) maxval_str = "%s" % (self.maxval,) running_str = "%s" % (self.running,) failed_str = "%s" % (self.failed,) load_avg_str = self._load_avg_str() color_output = io.StringIO() plain_output = io.StringIO() style_file = portage.output.ConsoleStyleFile(color_output) style_file.write_listener = plain_output style_writer = portage.output.StyleWriter(file=style_file, maxcol=9999) style_writer.style_listener = style_file.new_styles f = formatter.AbstractFormatter(style_writer) number_style = "INFORM" f.add_literal_data("Jobs: ") f.push_style(number_style) f.add_literal_data(curval_str) f.pop_style() f.add_literal_data(" of ") f.push_style(number_style) f.add_literal_data(maxval_str) f.pop_style() f.add_literal_data(" complete") if self.running: f.add_literal_data(", ") f.push_style(number_style) f.add_literal_data(running_str) f.pop_style() f.add_literal_data(" running") if self.failed: f.add_literal_data(", ") f.push_style(number_style) f.add_literal_data(failed_str) f.pop_style() f.add_literal_data(" failed") padding = self._jobs_column_width - len(plain_output.getvalue()) if padding > 0: f.add_literal_data(padding * " ") f.add_literal_data("Load avg: ") f.add_literal_data(load_avg_str) # Truncate to fit width, to avoid making the terminal scroll if the # line overflows (happens when the load average is large). plain_output = plain_output.getvalue() if self._isatty and len(plain_output) > self.width: # Use plain_output here since it's easier to truncate # properly than the color output which contains console # color codes. self._update(plain_output[:self.width]) else: self._update(color_output.getvalue()) if self.xterm_titles: # If the HOSTNAME variable is exported, include it # in the xterm title, just like emergelog() does. # See bug #390699. title_str = " ".join(plain_output.split()) hostname = os.environ.get("HOSTNAME") if hostname is not None: title_str = "%s: %s" % (hostname, title_str) xtermTitle(title_str)