summaryrefslogtreecommitdiff
path: root/geneticone
diff options
context:
space:
mode:
Diffstat (limited to 'geneticone')
-rw-r--r--geneticone/flags.py171
1 files changed, 171 insertions, 0 deletions
diff --git a/geneticone/flags.py b/geneticone/flags.py
new file mode 100644
index 0000000..df22185
--- /dev/null
+++ b/geneticone/flags.py
@@ -0,0 +1,171 @@
+#!/usr/bin/python
+
+#
+# File: geneticone/flags.py
+# This file is part of the Genetic/One-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006 Necoro d.M.
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by Necoro d.M. <necoro@necoro.net>
+
+import os
+import os.path
+from subprocess import Popen, PIPE
+
+from geneticone import *
+
+### GENERAL PART ###
+
+def grep (p, path):
+ """Grep runs "egrep" on a given path and looks for occurences of a given package."""
+ if not isinstance(p, Package):
+ p = Package(p) # assume it is a cpv or a gentoolkit.Package
+
+ command = "egrep -x -n -r -H '^[<>!=~]{0,2}%s(-[0-9].*)?[[:space:]].*$' %s"
+ return Popen((command % (p.get_cp(), path)), shell = True, stdout = PIPE).communicate()[0].splitlines()
+
+def get_data(pkg):
+ """This splits up the data of grep() and builds tuples in the format (file,line,criterion,list_of_flags)."""
+ flags = []
+
+ # do grep
+ list = grep(pkg, USE_PATH)
+
+ for i in range(len(list)):
+ file, line, fl = tuple(list[i].split(":")) # get file, line and flag-list
+ fl = fl.split()
+ crit = fl[0]
+ fl = fl[1:]
+ # stop after first comment
+ for i in range(len(fl)):
+ if fl[i][0] == "#": #comment - stop here
+ fl = fl[:i]
+ break
+ flags.append((file,line,crit,fl))
+
+ return flags
+
+### USE FLAG PART ###
+USE_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.use.go")
+USE_PATH_IS_DIR = os.path.isdir(USE_PATH)
+useFlags = {} # useFlags in the file
+newUseFlags = [] # useFlags as we want them to be: format: (cpv, file, line, useflag, (true if removed from list / false if added))
+
+def set_use_flag (pkg, flag):
+ """Sets the useflag for a given package."""
+ if not isinstance(pkg, Package):
+ pkg = Package(pkg) # assume cpv or gentoolkit.Package
+
+ cpv = pkg.get_cpv()
+
+ # if not saved in useFlags, get it by calling get_data() which calls grep()
+ data = None
+ if not cpv in useFlags:
+ data = get_data(pkg)
+ useFlags[cpv] = data
+ else:
+ data = useFlags[cpv]
+
+ # add a useflag / delete one
+ added = False
+ for file, line, crit, flags in data:
+ if pkg.matches(crit):
+ # we have "-flag" and "flag" is in the uselist -> delete "flag"
+ if flag[0] == "-" and flag[1:] in flags:
+ if added: del newUseFlags[-1] # we currently added it as an extra option - delete it
+ added = True
+ newUseFlags.append((pkg.get_cpv(), file, line, flag[1:], True))
+ break
+ # we have "flag" and "-flag" is in the uselist -> delete "-flag"
+ elif flag[0] != "-" and "-"+flag in flags:
+ if added: del newUseFlags[-1] # we currently added it as an extra option - delete it
+ added = True
+ newUseFlags.append((pkg.get_cpv(), file, line, "-"+flag, True))
+ break
+ # add as an extra flag
+ else:
+ if not added: newUseFlags.append((pkg.get_cpv(), file, line, flag, False))
+ added = True
+ # create a new line
+ if not added:
+ if USE_PATH_IS_DIR:
+ newUseFlags.append((pkg.get_cpv(), os.path.join(USE_PATH,"geneticone"), -1, flag, False))
+ else:
+ newUseFlags.append((pkg.get_cpv(), USE_PATH, -1, flag, False))
+
+def write_use_flags ():
+ """This writes our changed useflags into the file."""
+ global newUseFlags, useFlags
+
+ def insert (flag, list):
+ """Shortcut for inserting a new flag right after the package-name."""
+ list.insert(1,flag)
+
+ def remove (flag, list):
+ """Removes a flag."""
+ try:
+ list.remove(flag)
+ except ValueError: # flag is given as flag\n
+ list.remove(flag+"\n")
+ list.append("\n") #re-insert the newline
+
+ # no more flags there - comment it out
+ if len(list) == 1 or list[1][0] in ("#","\n"):
+ list[0] = "#"+list[0]
+ insert("#removed by geneticone#",list)
+
+ file_cache = {} # cache for having to read the file only once: name->[lines]
+ for cpv, file, line, flag, delete in newUseFlags:
+ line = int(line) # it is saved as a string so far!
+
+ # add new line
+ if line == -1:
+ msg = "\n#geneticone update#\n=%s %s" % (cpv, flag)
+ if not file in file_cache:
+ f = open(file, "a")
+ f.write(msg)
+ f.close()
+ else:
+ file_cache[file].append(msg)
+ # change a line
+ else:
+ if not file in file_cache:
+ # read file
+ f = open(file, "r")
+ lines = []
+ i = 1
+ while i < line: # stop at the given line
+ lines.append(f.readline())
+ i = i+1
+ l = f.readline().split(" ")
+ # delete or insert
+ if delete:
+ remove(flag,l)
+ else:
+ insert(flag,l)
+ lines.append(" ".join(l))
+
+ # read the rest
+ lines.extend(f.readlines())
+
+ file_cache[file] = lines
+ f.close()
+ else: # in cache
+ l = file_cache[file][line-1].split(" ")
+ if delete:
+ remove(flag,l)
+ else:
+ insert(flag,l)
+ file_cache[file][line-1] = " ".join(l)
+
+ # write to disk
+ for file in file_cache.keys():
+ f = open(file, "w")
+ f.writelines(file_cache[file])
+ f.close()
+ # reset
+ useFlags = {}
+ newUseFlags = []