#!/usr/bin/env python # # make-worldconf: this file is part of the GRS suite # Copyright (C) 2015 Anthony G. Basile # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import configparser import copy import os import re import sys from grs import CONST from _emerge.main import parse_opts from _emerge.actions import load_emerge_config, create_depgraph_params from _emerge.depgraph import backtrack_depgraph def useflags(config, p): # Get all IUSE, enabled USE and EXPAND_HIDDEN flags. try: iuse = list(p.iuse.all) use = list(p.use.enabled) # expand = list(p.use.expand) expand_hidden = list(p.use.expand_hidden) except AttributeError: return except TypeError: return # We only include select USE_EXPAND flags. Note becaue of how we match 'abi_', # for example, will match abi_ppc, abi_mips etc. Hopefully this will not lead # to any false hits. expand = [ 'kernel_', 'elibc_', 'userland_', 'abi_', 'linguas_', 'python_', 'ruby_' ] # Remove any selected USE_EXPAND and any EXPAND_HIDDEN flags from IUSE flags my_iuse = copy.deepcopy(iuse) for u in iuse: for e in expand + expand_hidden: while re.match(e, u): try: my_iuse.remove(u) except ValueError: break # Remove the same flags from the enabled USE flags my_use = copy.deepcopy(use) for u in use: for e in expand + expand_hidden: while re.match(e, u): try: my_use.remove(u) except ValueError: break # Remove the arch flag. # TODO: this needs to be generalized. my_use.remove('amd64') # Go through all the IUSE flags and put a - in front # of all the disabled USE flags. flags = [] for i in my_iuse: if i in my_use: flags.append(i) else: flags.append('-%s' % i) # Insert nicely sorted flags. if len(flags) > 0: flags.sort() config[p.slot_atom]['package.use'] = p.slot_atom + ' ' + ' '.join(flags) def keywords(config, p): # Stable means there is no keyword is needed. keyword = None try: if not p.stable: keyword = "??" # Something went wrong! if p.get_keyword_mask() == 'missing': keyword = '**' if p.get_keyword_mask() == 'unstable': # This needs to be generalized keyword = '~amd64' except AttributeError: pass if keyword: config[p.slot_atom]['package.accept_keywords'] = '=%s %s' % (p.cpv, keyword) def from_etc_portage(config, p, subdir): # We could add better matching intelligence here so as to match # these subdirs+files for /etc/portage not maintained by GRS. fpath = os.path.join(CONST.PORTAGE_CONFIGDIR, '%s/%s' % \ (subdir, re.sub('[/:]', '_', p.slot_atom))) if os.path.isfile(fpath): with open(fpath, 'r') as g: config[p.slot_atom][subdir] = g.read().strip() def main(): args = sys.argv[1:] if len(args) == 0: args = [ '-e', '@world' ] myaction, myopts, myfiles = parse_opts(args, silent=True) emerge_config = load_emerge_config(action=myaction, args=myfiles, opts=myopts) mysettings, mytrees = emerge_config.target_config.settings, emerge_config.trees myparams = create_depgraph_params(myopts, myaction) success, mydepgraph, favorites = backtrack_depgraph(mysettings, mytrees, myopts, \ myparams, myaction, myfiles, spinner=None) config = configparser.RawConfigParser(delimiters=':', allow_no_value=True, comment_prefixes=None) for p in mydepgraph.altlist(): # Prepare an empty section for this atom try: config[p.slot_atom] = {} except AttributeError: continue # Populate package.use - these are read out of p useflags(config, p) # Populate package.accept_keywords - these are read out of p keywords(config, p) # Others - these are read out of /etc/portage from_etc_portage(config, p, 'package.mask') from_etc_portage(config, p, 'package.unmask') from_etc_portage(config, p, 'package.env') from_etc_portage(config, p, 'env') # Remove any empty sections if config[p.slot_atom] == {}: config.remove_section(p.slot_atom) # Recontruct a RawConfigParser from the above which has sorted sections. all_slot_atoms = config.sections() all_slot_atoms.sort() sorted_config = configparser.RawConfigParser(delimiters=':', allow_no_value=True, comment_prefixes=None) for s in all_slot_atoms: sorted_config[s] = config[s] with open('world.conf', 'w') as configfile: sorted_config.write(configfile) if __name__ == "__main__": main()