| # Copyright 1999-2012 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| |
| import errno |
| import logging |
| import re |
| import stat |
| import subprocess |
| |
| import portage |
| from portage import os |
| |
| def chk_updated_info_files(root, infodirs, prev_mtimes): |
| |
| if os.path.exists("/usr/bin/install-info"): |
| out = portage.output.EOutput() |
| regen_infodirs = [] |
| for z in infodirs: |
| if z == '': |
| continue |
| inforoot = portage.util.normalize_path(root + z) |
| if os.path.isdir(inforoot) and \ |
| not [x for x in os.listdir(inforoot) \ |
| if x.startswith('.keepinfodir')]: |
| infomtime = os.stat(inforoot)[stat.ST_MTIME] |
| if inforoot not in prev_mtimes or \ |
| prev_mtimes[inforoot] != infomtime: |
| regen_infodirs.append(inforoot) |
| |
| if not regen_infodirs: |
| portage.util.writemsg_stdout("\n") |
| if portage.util.noiselimit >= 0: |
| out.einfo("GNU info directory index is up-to-date.") |
| else: |
| portage.util.writemsg_stdout("\n") |
| if portage.util.noiselimit >= 0: |
| out.einfo("Regenerating GNU info directory index...") |
| |
| dir_extensions = ("", ".gz", ".bz2") |
| icount = 0 |
| badcount = 0 |
| errmsg = "" |
| for inforoot in regen_infodirs: |
| if inforoot == '': |
| continue |
| |
| if not os.path.isdir(inforoot) or \ |
| not os.access(inforoot, os.W_OK): |
| continue |
| |
| file_list = os.listdir(inforoot) |
| file_list.sort() |
| dir_file = os.path.join(inforoot, "dir") |
| moved_old_dir = False |
| processed_count = 0 |
| for x in file_list: |
| if x.startswith(".") or \ |
| os.path.isdir(os.path.join(inforoot, x)): |
| continue |
| if x.startswith("dir"): |
| skip = False |
| for ext in dir_extensions: |
| if x == "dir" + ext or \ |
| x == "dir" + ext + ".old": |
| skip = True |
| break |
| if skip: |
| continue |
| if processed_count == 0: |
| for ext in dir_extensions: |
| try: |
| os.rename(dir_file + ext, dir_file + ext + ".old") |
| moved_old_dir = True |
| except EnvironmentError as e: |
| if e.errno != errno.ENOENT: |
| raise |
| del e |
| processed_count += 1 |
| try: |
| proc = subprocess.Popen( |
| ['/usr/bin/install-info', |
| '--dir-file=%s' % os.path.join(inforoot, "dir"), |
| os.path.join(inforoot, x)], |
| env=dict(os.environ, LANG="C", LANGUAGE="C"), |
| stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
| except OSError: |
| myso = None |
| else: |
| myso = portage._unicode_decode( |
| proc.communicate()[0]).rstrip("\n") |
| proc.wait() |
| existsstr = "already exists, for file `" |
| if myso: |
| if re.search(existsstr, myso): |
| # Already exists... Don't increment the count for this. |
| pass |
| elif myso[:44] == "install-info: warning: no info dir entry in ": |
| # This info file doesn't contain a DIR-header: install-info produces this |
| # (harmless) warning (the --quiet switch doesn't seem to work). |
| # Don't increment the count for this. |
| pass |
| else: |
| badcount += 1 |
| errmsg += myso + "\n" |
| icount += 1 |
| |
| if moved_old_dir and not os.path.exists(dir_file): |
| # We didn't generate a new dir file, so put the old file |
| # back where it was originally found. |
| for ext in dir_extensions: |
| try: |
| os.rename(dir_file + ext + ".old", dir_file + ext) |
| except EnvironmentError as e: |
| if e.errno != errno.ENOENT: |
| raise |
| del e |
| |
| # Clean dir.old cruft so that they don't prevent |
| # unmerge of otherwise empty directories. |
| for ext in dir_extensions: |
| try: |
| os.unlink(dir_file + ext + ".old") |
| except EnvironmentError as e: |
| if e.errno != errno.ENOENT: |
| raise |
| del e |
| |
| #update mtime so we can potentially avoid regenerating. |
| prev_mtimes[inforoot] = os.stat(inforoot)[stat.ST_MTIME] |
| |
| if badcount: |
| out.eerror("Processed %d info files; %d errors." % \ |
| (icount, badcount)) |
| portage.util.writemsg_level(errmsg, |
| level=logging.ERROR, noiselevel=-1) |
| else: |
| if icount > 0 and portage.util.noiselimit >= 0: |
| out.einfo("Processed %d info files." % (icount,)) |