diff options
Diffstat (limited to 'portage_with_autodep/bin/dispatch-conf')
-rwxr-xr-x | portage_with_autodep/bin/dispatch-conf | 94 |
1 files changed, 77 insertions, 17 deletions
diff --git a/portage_with_autodep/bin/dispatch-conf b/portage_with_autodep/bin/dispatch-conf index 1e21a52..139a001 100755 --- a/portage_with_autodep/bin/dispatch-conf +++ b/portage_with_autodep/bin/dispatch-conf @@ -1,5 +1,5 @@ #!/usr/bin/python -O -# Copyright 1999-2006 Gentoo Foundation +# Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # @@ -27,13 +27,11 @@ except ImportError: from portage import os from portage import dispatch_conf from portage import _unicode_decode -from portage.dispatch_conf import diffstatusoutput_len +from portage.dispatch_conf import diffstatusoutput from portage.process import find_binary FIND_EXTANT_CONFIGS = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print" DIFF_CONTENTS = "diff -Nu '%s' '%s'" -DIFF_CVS_INTERP = "diff -Nu '%s' '%s' | grep '^[+-][^+-]' | grep -v '# .Header:.*'" -DIFF_WSCOMMENTS = "diff -Nu '%s' '%s' | grep '^[+-][^+-]' | grep -v '^[-+]#' | grep -v '^[-+][:space:]*$'" # We need a secure scratch dir and python does silly verbose errors on the use of tempnam oldmask = os.umask(0o077) @@ -62,7 +60,21 @@ def cleanup(mydir=SCRATCH_DIR): shutil.rmtree(mydir) atexit.register(cleanup) -MANDATORY_OPTS = [ 'archive-dir', 'diff', 'replace-cvs', 'replace-wscomments', 'merge' ] +MANDATORY_OPTS = [ 'archive-dir', 'diff', 'replace-cvs', 'replace-wscomments', 'merge' ] + +def cmd_var_is_valid(cmd): + """ + Return true if the first whitespace-separated token contained + in cmd is an executable file, false otherwise. + """ + cmd = portage.util.shlex_split(cmd) + if not cmd: + return False + + if os.path.isabs(cmd[0]): + return os.access(cmd[0], os.EX_OK) + + return find_binary(cmd[0]) is not None class dispatch: options = {} @@ -71,7 +83,7 @@ class dispatch: confs = [] count = 0 - config_root = '/' + config_root = portage.const.EPREFIX or os.sep self.options = portage.dispatch_conf.read_config(MANDATORY_OPTS) if "log-file" in self.options: @@ -84,12 +96,30 @@ class dispatch: else: self.options["log-file"] = "/dev/null" + pager = self.options.get("pager") + if pager is None or not cmd_var_is_valid(pager): + pager = os.environ.get("PAGER") + if pager is None or not cmd_var_is_valid(pager): + pager = "cat" + + pager_basename = os.path.basename(portage.util.shlex_split(pager)[0]) + if pager_basename == "less": + less_opts = self.options.get("less-opts") + if less_opts is not None and less_opts.strip(): + pager += " " + less_opts + + if pager_basename == "cat": + pager = "" + else: + pager = " | " + pager + # # Build list of extant configs # for path in config_paths: - path = portage.normalize_path(path) + path = portage.normalize_path( + os.path.join(config_root, path.lstrip(os.sep))) try: mymode = os.stat(path).st_mode except OSError: @@ -100,7 +130,9 @@ class dispatch: path, basename = os.path.split(path) find_opts = "-maxdepth 1" - confs += self.massage(os.popen(FIND_EXTANT_CONFIGS % (path, find_opts, basename)).readlines()) + with os.popen(FIND_EXTANT_CONFIGS % + (path, find_opts, basename)) as proc: + confs += self.massage(proc.readlines()) if self.options['use-rcs'] == 'yes': for rcs_util in ("rcs", "ci", "co", "rcsmerge"): @@ -118,6 +150,9 @@ class dispatch: portage.util.shlex_split( portage.settings.get('CONFIG_PROTECT_MASK', ''))) + def diff(file1, file2): + return diffstatusoutput(DIFF_CONTENTS, file1, file2) + # # Remove new configs identical to current # and @@ -134,11 +169,11 @@ class dispatch: else: mrgfail = portage.dispatch_conf.file_archive(archive, conf['current'], conf['new'], mrgconf) if os.path.exists(archive + '.dist'): - unmodified = diffstatusoutput_len(DIFF_CONTENTS % (conf['current'], archive + '.dist'))[1] == 0 + unmodified = len(diff(conf['current'], archive + '.dist')[1]) == 0 else: unmodified = 0 if os.path.exists(mrgconf): - if mrgfail or diffstatusoutput_len(DIFF_CONTENTS % (conf['new'], mrgconf))[1] == 0: + if mrgfail or len(diff(conf['new'], mrgconf)[1]) == 0: os.unlink(mrgconf) newconf = conf['new'] else: @@ -149,24 +184,34 @@ class dispatch: if newconf == mrgconf and \ self.options.get('ignore-previously-merged') != 'yes' and \ os.path.exists(archive+'.dist') and \ - diffstatusoutput_len(DIFF_CONTENTS % (archive+'.dist', conf['new']))[1] == 0: + len(diff(archive+'.dist', conf['new'])[1]) == 0: # The current update is identical to the archived .dist # version that has previously been merged. os.unlink(mrgconf) newconf = conf['new'] - mystatus, myoutput_len = diffstatusoutput_len( - DIFF_CONTENTS % (conf ['current'], newconf)) + mystatus, myoutput = diff(conf['current'], newconf) + myoutput_len = len(myoutput) same_file = 0 == myoutput_len if mystatus >> 8 == 2: # Binary files differ same_cvs = False same_wsc = False else: - same_cvs = 0 == diffstatusoutput_len( - DIFF_CVS_INTERP % (conf ['current'], newconf))[1] - same_wsc = 0 == diffstatusoutput_len( - DIFF_WSCOMMENTS % (conf ['current'], newconf))[1] + # Extract all the normal diff lines (ignore the headers). + mylines = re.findall('^[+-][^\n+-].*$', myoutput, re.MULTILINE) + + # Filter out all the cvs headers + cvs_header = re.compile('# [$]Header:') + cvs_lines = list(filter(cvs_header.search, mylines)) + same_cvs = len(mylines) == len(cvs_lines) + + # Filter out comments and whitespace-only changes. + # Note: be nice to also ignore lines that only differ in whitespace... + wsc_lines = [] + for x in ['^[-+]\s*#', '^[-+]\s*$']: + wsc_lines += list(filter(re.compile(x).match, mylines)) + same_wsc = len(mylines) == len(wsc_lines) # Do options permit? same_cvs = same_cvs and self.options['replace-cvs'] == 'yes' @@ -224,10 +269,12 @@ class dispatch: clear_screen() if show_new_diff: cmd = self.options['diff'] % (conf['new'], mrgconf) + cmd += pager spawn_shell(cmd) show_new_diff = 0 else: cmd = self.options['diff'] % (conf['current'], newconf) + cmd += pager spawn_shell(cmd) print() @@ -423,6 +470,19 @@ def spawn_shell(cmd): else: os.system(cmd) +def usage(argv): + print('dispatch-conf: sane configuration file update\n') + print('Usage: dispatch-conf [config dirs]\n') + print('See the dispatch-conf(1) man page for more details') + sys.exit(os.EX_OK) + +for x in sys.argv: + if x in ('-h', '--help'): + usage(sys.argv) + elif x in ('--version'): + print("Portage", portage.VERSION) + sys.exit(os.EX_OK) + # run d = dispatch () |