aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordol-sen <brian.dolbec@gmail.com>2011-04-24 23:15:05 -0700
committerdol-sen <brian.dolbec@gmail.com>2011-04-24 23:15:05 -0700
commitc637dc79998b38b04d27951cb5140b34fc4900e4 (patch)
tree028720ef6cf23704ee8d37da98da33c1f2c7799e
parentconvert to gentoolkit's standard tab indent. (diff)
downloadgentoolkit-c637dc79998b38b04d27951cb5140b34fc4900e4.tar.gz
gentoolkit-c637dc79998b38b04d27951cb5140b34fc4900e4.tar.bz2
gentoolkit-c637dc79998b38b04d27951cb5140b34fc4900e4.zip
new /bin/revdep-ng script. revamp rebuild.py for a better api.
-rwxr-xr-xbin/revdep-ng51
-rw-r--r--pym/gentoolkit/revdep_rebuild/rebuild.py332
2 files changed, 238 insertions, 145 deletions
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 <brian.dolbec@gmail.com>
+# 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