From: dol-sen Date: Mon, 25 Apr 2011 06:15:05 +0000 (-0700) Subject: new /bin/revdep-ng script. revamp rebuild.py for a better api. X-Git-Tag: gentoolkit-0.3.0.5~45 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d11d9f709e0116b083696d0c2d581bde597d467c;p=gentoolkit.git new /bin/revdep-ng script. revamp rebuild.py for a better api. --- diff --git a/bin/revdep-ng b/bin/revdep-ng new file mode 100755 index 0000000..a4c8e11 --- /dev/null +++ b/bin/revdep-ng @@ -0,0 +1,51 @@ +#!/usr/bin/python +# +# Copyright 2010 Brian Dolbec +# Copyright 2002-2010 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 or later +# +# $Header$ + +"""'analyse' is a flexible utility for Gentoo linux which can display various +information about installed packages, such as the USE flags used and the +packages that use them. It can also be used to help rebuild /etc/portage/package.* +files in the event of corruption, and possibly more. +""" + +from __future__ import print_function + +import sys +# This block ensures that ^C interrupts are handled quietly. +try: + import signal + + def exithandler(signum,frame): + signal.signal(signal.SIGINT, signal.SIG_IGN) + signal.signal(signal.SIGTERM, signal.SIG_IGN) + print() + sys.exit(1) + + signal.signal(signal.SIGINT, exithandler) + signal.signal(signal.SIGTERM, exithandler) + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + +except KeyboardInterrupt: + print() + sys.exit(1) + +from gentoolkit import errors +from gentoolkit.revdep_rebuild import rebuild + +try: + success = rebuild.main(rebuild.parse_options()) + sys.exit(success) +except errors.GentoolkitException as err: + if '--debug' in sys.argv: + raise + else: + from gentoolkit import pprinter as pp + sys.stderr.write(pp.error(str(err))) + print() + print("Add '--debug' to global options for traceback.") + sys.exit(1) diff --git a/pym/gentoolkit/revdep_rebuild/rebuild.py b/pym/gentoolkit/revdep_rebuild/rebuild.py index 4ad5e58..6185e0c 100644 --- a/pym/gentoolkit/revdep_rebuild/rebuild.py +++ b/pym/gentoolkit/revdep_rebuild/rebuild.py @@ -28,7 +28,7 @@ from analyse import analyse from stuff import exithandler, get_masking_status from cache import check_temp_files, read_cache from assign import get_slotted_cps -from settings import SETTINGS +from settings import DEFAULTS APP_NAME = sys.argv[0] @@ -37,156 +37,198 @@ VERSION = '0.1-r6' __productname__ = "revdep-ng" +# functions def print_usage(): - print APP_NAME + ': (' + VERSION +')' - print - print 'This is free software; see the source for copying conditions.' - print - print 'Usage: ' + APP_NAME + ' [OPTIONS] [--] [EMERGE_OPTIONS]' - print - print 'Broken reverse dependency rebuilder, python implementation.' - print - print 'Available options:' - print ''' - -C, --nocolor Turn off colored output - -d, --debug Print debug informations - -e, --exact Emerge based on exact package version - -h, --help Print this usage - -i, --ignore Ignore temporary files from previous runs (also won't create any) - -L, --library NAME Emerge existing packages that use the library with NAME - --library=NAME NAME can be a full or partial library name - -l, --no-ld-path Do not set LD_LIBRARY_PATH - -o, --no-order Do not check the build order - (Saves time, but may cause breakage.) - -p, --pretend Do a trial run without actually emerging anything - (also passed to emerge command) - -q, --quiet Be less verbose (also passed to emerge command) - -v, --verbose Be more verbose (also passed to emerge command) + print APP_NAME + ': (' + VERSION +')' + print + print 'This is free software; see the source for copying conditions.' + print + print 'Usage: ' + APP_NAME + ' [OPTIONS] [--] [EMERGE_OPTIONS]' + print + print 'Broken reverse dependency rebuilder, python implementation.' + print + print 'Available options:' + print ''' + -C, --nocolor Turn off colored output + -d, --debug Print debug informations + -e, --exact Emerge based on exact package version + -h, --help Print this usage + -i, --ignore Ignore temporary files from previous runs + (also won't create any) + -L, --library NAME Emerge existing packages that use + the library with NAME + --library=NAME NAME can be a full or partial library name + -l, --no-ld-path Do not set LD_LIBRARY_PATH + -o, --no-order Do not check the build order + (Saves time, but may cause breakage.) + -p, --pretend Do a trial run without actually emerging anything + (also passed to emerge command) + -q, --quiet Be less verbose (also passed to emerge command) + -v, --verbose Be more verbose (also passed to emerge command) ''' - print 'Calls emerge, options after -- are ignored by ' + APP_NAME - print 'and passed directly to emerge.' - - - -# functions + print 'Calls emerge, options after -- are ignored by ' + APP_NAME + print 'and passed directly to emerge.' def _match_str_in_list(lst, stri): - for l in lst: - if stri.endswith(l): - return l - return False + for l in lst: + if stri.endswith(l): + return l + return False + + +def init_logger(settings): + """Creates and iitializes our logger according to the settings""" + logger = logging.getLogger() + log_handler = logging.StreamHandler() + log_fmt = logging.Formatter('%(msg)s') + log_handler.setFormatter(log_fmt) + logger.addHandler(log_handler) + if settings['quiet']: + logger.setLevel(logging.ERROR) + elif settings['VERBOSITY'] == 2: + logger.setLevel(logging.INFO) + elif settings['debug']: + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.WARNING) + return logger + + +def parse_options(): + """Parses the command line options an sets settings accordingly""" + + settings = DEFAULTS.copy() + try: + opts, args = getopt.getopt(sys.argv[1:], + 'dehiklopqvCL:P', + ['nocolor', 'debug', 'exact', 'help', 'ignore', + 'keep-temp', 'library=', 'no-ld-path', 'no-order', + 'pretend', 'no-pretend', 'no-progress', 'quiet', 'verbose']) + + for key, val in opts: + if key in ('-h', '--help'): + print_usage() + sys.exit(0) + elif key in ('-q', '--quiet'): + settings['quiet'] = True + settings['VERBOSITY'] = 0 + elif key in ('-v', '--verbose'): + settings['VERBOSITY'] = 2 + elif key in ('-d', '--debug'): + settings['debug'] = True + settings['VERBOSITY'] = 3 + elif key in ('-p', '--pretend'): + settings['PRETEND'] = True + elif key == '--no-pretend': + settings['NO_PRETEND'] = True + elif key in ('-e', '--exact'): + settings['EXACT'] = True + elif key in ('-C', '--nocolor', '--no-color'): + settings['nocolor'] = True + elif key in ('-L', '--library', '--library='): + settings['library'] = settings['library'].union(val.split(',')) + elif key in ('-i', '--ignore'): + settings['USE_TMP_FILES'] = False + + settings['pass_through_options'] = " " + " ".join(args) + except getopt.GetoptError: + #logging.info(red('Unrecognized option\n')) + print(red('Unrecognized option\n')) + print_usage() + sys.exit(2) + return settings + + +def rebuild(logger, assigned, settings): + """rebuilds the assigned pkgs""" + + args = settings['pass_through_options'] + if settings['EXACT']: + emerge_command = '=' + ' ='.join(assigned) + else: + emerge_command = ' '.join(get_slotted_cps(assigned, logger)) + if settings['PRETEND']: + args += ' --pretend' + if settings['VERBOSITY'] >= 2: + args += ' --verbose' + elif settings['VERBOSITY'] < 1: + args += ' --quiet' + + if len(emerge_command) == 0: + logger.warn(bold('\nThere is nothing to emerge. Exiting.')) + return 0 + + emerge_command = args + ' --oneshot ' + emerge_command + + logger.warn(yellow('\nemerge') + bold(emerge_command)) + + success = os.system('emerge ' + emerge_command) + return success # Runs from here -if __name__ == "__main__": - logger = logging.getLogger() - log_handler = logging.StreamHandler() - log_fmt = logging.Formatter('%(msg)s') - log_handler.setFormatter(log_fmt) - logger.addHandler(log_handler) - logger.setLevel(logging.WARNING) - - _libs_to_check = set() - - try: - opts, args = getopt.getopt(sys.argv[1:], 'dehiklopqvCL:P', ['nocolor', 'debug', 'exact', 'help', 'ignore',\ - 'keep-temp', 'library=', 'no-ld-path', 'no-order', 'pretend', 'no-pretend', 'no-progress', 'quiet', 'verbose']) - - for key, val in opts: - if key in ('-h', '--help'): - print_usage() - sys.exit(0) - elif key in ('-q', '--quiet'): - logger.setLevel(logging.ERROR) - SETTINGS['VERBOSITY'] = 0 - elif key in ('-v', '--verbose'): - logger.setLevel(logging.INFO) - SETTINGS['VERBOSITY'] = 2 - elif key in ('-d', '--debug'): - logger.setLevel(logging.DEBUG) - SETTINGS['VERBOSITY'] = 3 - elif key in ('-p', '--pretend'): - SETTINGS['PRETEND'] = True - elif key == '--no-pretend': - SETTINGS['NO_PRETEND'] = True - elif key in ('-e', '--exact'): - SETTINGS['EXACT'] = True - elif key in ('-C', '--nocolor', '--no-color'): - nocolor() - elif key in ('-L', '--library', '--library='): - _libs_to_check = _libs_to_check.union(val.split(',')) - elif key in ('-i', '--ignore'): - SETTINGS['USE_TMP_FILES'] = False - - args = " " + " ".join(args) - except getopt.GetoptError: - logging.info(red('Unrecognized option\n')) - print_usage() - sys.exit(2) - - if not sys.stdout.isatty(): - nocolor() - - if os.getuid() != 0 and not SETTINGS['PRETEND']: - logger.warn(blue(' * ') + yellow('You are not root, adding --pretend to portage options')) - SETTINGS['PRETEND'] = True - elif not SETTINGS['PRETEND'] and SETTINGS['IS_DEV'] and not SETTINGS['NO_PRETEND']: - logger.warn(blue(' * ') + yellow('This is a development version, so it may not work correctly')) - logger.warn(blue(' * ') + yellow('Adding --pretend to portage options anyway')) - logger.info(blue(' * ') + 'If you\'re sure, you can add --no-pretend to revdep options') - SETTINGS['PRETEND'] = True - - - signal.signal(signal.SIGINT, exithandler) - signal.signal(signal.SIGTERM, exithandler) - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - - analyze_cache = {} - if SETTINGS['USE_TMP_FILES'] and check_temp_files(): - libraries, la_libraries, libraries_links, binaries = read_cache() - assigned = analyse(libraries=libraries, la_libraries=la_libraries, \ - libraries_links=libraries_links, binaries=binaries, _libs_to_check=_libs_to_check) - else: - assigned = analyse() - - if not assigned: - logger.warn('\n' + bold('Your system is consistent')) - sys.exit(0) - - - has_masked = False - tmp = [] - for a in assigned: - if get_masking_status(a): - has_masked = True - logger.warn('!!! ' + red('All ebuilds that could satisfy: ') + green(a) + red(' have been masked')) - else: - tmp.append(a) - assigned = tmp - - if has_masked: - logger.info(red(' * ') + 'Unmask all ebuild listed above and call revdep-rebuild again or manually emerge given packages.') - - - if SETTINGS['EXACT']: - emerge_command = '=' + ' ='.join(assigned) - else: - emerge_command = ' '.join(get_slotted_cps(assigned, logger)) - if SETTINGS['PRETEND']: - args += ' --pretend' - if SETTINGS['VERBOSITY'] >= 2: - args += ' --verbose' - elif SETTINGS['VERBOSITY'] < 1: - args += ' --quiet' - - if len(emerge_command) == 0: - logger.warn(bold('\nThere is nothing to emerge. Exiting.')) - sys.exit(0) - - emerge_command = args + ' --oneshot ' + emerge_command - - logger.warn(yellow('\nemerge') + bold(emerge_command)) - os.system('emerge ' + emerge_command) - +def main(settings=None): + + if settings is None: + print("NO Input settings, using defaults...") + settings = DEFAULTS.copy() + + logger = init_logger(settings) + + _libs_to_check = settings['library'] + + if not settings['stdout'].isatty() or settings['nocolor']: + nocolor() + + if os.getuid() != 0 and not settings['PRETEND']: + logger.warn(blue(' * ') + + yellow('You are not root, adding --pretend to portage options')) + settings['PRETEND'] = True + elif not settings['PRETEND'] \ + and settings['IS_DEV'] \ + and not settings['NO_PRETEND']: + logger.warn(blue(' * ') + + yellow('This is a development version, ' + 'so it may not work correctly')) + logger.warn(blue(' * ') + + yellow('Adding --pretend to portage options anyway')) + logger.info(blue(' * ') + + 'If you\'re sure, you can add --no-pretend to revdep options') + settings['PRETEND'] = True + + analyze_cache = {} + if settings['USE_TMP_FILES'] and check_temp_files(): + libraries, la_libraries, libraries_links, binaries = read_cache() + assigned = analyse(libraries=libraries, la_libraries=la_libraries, + libraries_links=libraries_links, + binaries=binaries, + _libs_to_check=_libs_to_check) + else: + assigned = analyse(settings, logger) + + if not assigned: + logger.warn('\n' + bold('Your system is consistent')) + # return the correct exit code + return 0 + + has_masked = False + tmp = [] + for a in assigned: + if get_masking_status(a): + has_masked = True + logger.warn('!!! ' + red('All ebuilds that could satisfy: ') + + green(a) + red(' have been masked')) + else: + tmp.append(a) + assigned = tmp + + if has_masked: + logger.info(red(' * ') + + 'Unmask all ebuild(s) listed above and call revdep-rebuild ' + 'again or manually emerge given packages.') + + success = rebuild(logger, assigned, settings) + logger.debug("rebuild return code =", success) + return success