Skip to content

Instantly share code, notes, and snippets.

@bugabinga
Created March 14, 2016 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bugabinga/0010cfde17302f5ada53 to your computer and use it in GitHub Desktop.
Save bugabinga/0010cfde17302f5ada53 to your computer and use it in GitHub Desktop.
Obscure gentoo utility script to merge files of profiles into one each. Useful if trying to combine different gentoo profiles.
#!/usr/bin/env python
# Reduces gentoos portage configuration, found in profiles, files into single respective config files.
import sys
import argparse
import subprocess
import re
import os.path
base_path = "/usr/portage/profiles/"
get_profiles_cmd = "eselect profile list"
profile_files = ["packages.build","package.use","package.use.mask","packages","make.defaults","package.use.mask","use.mask","package.use.force","use.force","profile.bashrc", "package.provided", "package.unmask", "use.stable.mask"]
parent = "parent"
def collect_profile_file(path, file, content=""):
"""Merges the profile hierachy at 'path' for the specified file 'file'."""
realpath = os.path.realpath(path)+'/'
profile_file = realpath + file
# print "Collecting "+profile_file+':'
if os.path.isfile(profile_file):
# print "Found a profile file!"
content += open(profile_file,'r').read()
parent_file = path + parent
if os.path.isfile(parent_file):
parent_symlink = open(parent_file,'r')
for link in parent_symlink:
if "base" not in link:
# print "Found parent file, following it to " + link
content += collect_profile_file(realpath+link.strip()+'/', file, content)
return content
parser = argparse.ArgumentParser(description='Specify the profile IDs you wish to merge.')
parser.add_argument('integers', metavar='N', type=int, nargs='+', help='profile ID')
args = parser.parse_args()
get_profiles_process = subprocess.Popen(get_profiles_cmd, shell=True, stdout=subprocess.PIPE)
(selectable_profiles, error) = get_profiles_process.communicate()
profiles_marked_for_merge = args.integers
if error:
print "Unable to execute " + get_profiles_command + "."
sys.exit(1)
available_profiles = map(lambda x: int(x),re.findall('\[(\d+)\]',selectable_profiles))
# only proceed if the selected profiles actually exist
if not set( profiles_marked_for_merge).issubset( available_profiles):
print "You have selected profiles " + str(profiles_marked_for_merge) +". At least one of those could not be found using '"+ get_profiles_cmd +"'."
sys.exit(1)
lines = set()
for profile_id in profiles_marked_for_merge:
pattern = '\s*\['+str(profile_id)+'\]\s*(.*)'
matched_path = re.search('\s*\['+str(profile_id)+'\]\s*(.*)',selectable_profiles)
if matched_path:
profile_path = base_path + matched_path.group(1).strip()+'/'
for file in profile_files:
profile_file_collected = collect_profile_file(profile_path, file)
if profile_file_collected:
with open(file,'a') as output_file:
for line in profile_file_collected.splitlines():
if line not in lines:
lines.add(line)
output_file.write("\n" + line)
output_file.closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment