aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/epkgmove/epkgmove')
-rw-r--r--src/epkgmove/epkgmove895
1 files changed, 895 insertions, 0 deletions
diff --git a/src/epkgmove/epkgmove b/src/epkgmove/epkgmove
new file mode 100644
index 0000000..42b6e7d
--- /dev/null
+++ b/src/epkgmove/epkgmove
@@ -0,0 +1,895 @@
+#!/usr/bin/python -O
+# Copyright 2004 Ian Leitch
+# Copyright 1999-2004 Gentoo Foundation
+# $Header$
+#
+# Author:
+# Ian Leitch <port001@gentoo.org>
+#
+
+import os
+import re
+import sys
+import signal
+import commands
+from time import sleep
+from random import randint
+from optparse import OptionParser
+
+import portage
+try:
+ from portage.output import *
+except ImportError:
+ from output import *
+
+__author__ = "Ian Leitch"
+__email__ = "port001@gentoo.org"
+__productname__ = "epkgmove"
+__version__ = "1.3.1 - \"Moving Fusion + Bandages + Plasters\""
+__description__ = "A tool for moving and renaming packages in CVS"
+
+def print_usage():
+
+ print
+ print "%s %s [ %s ] [ %s ] [ %s ]" % (white("Usage:"), turquoise(__productname__), green("option"), green("origin"), green("destination"))
+ print " '%s' and '%s' are expected as a full package name, e.g. net-im/gaim" % (green("origin"), green("destination"))
+ print " See %s --help for a list of options" % __productname__
+ print
+
+def check_cwd(portdir):
+
+ if os.getcwd() != portdir:
+ print
+ print "%s Not in PORTDIR!" % yellow(" *")
+ print "%s Setting to: %s" % (yellow(" *"), os.getcwd())
+ os.environ["PORTDIR"]=os.getcwd()
+ return os.getcwd()
+
+ return portdir
+
+def check_args(args, portdir, options, cvscmd):
+
+ booboo = False
+ re_expr = "^[\da-zA-Z-]{,}/[\d\w0-9-]{,}$"
+ o_re_expr = re.compile(re_expr)
+
+ if len(args) == 0:
+ print "\n%s ERROR: errr, didn't you forget something" % red("!!!"),
+ count = range(3)
+ for second in count:
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ sleep(1)
+ sys.stdout.write("?")
+ sys.stdout.flush()
+ sleep(1)
+ print "\n\n%s %s hits you with a clue stick %s" % (green(" *"), __productname__, green("*"))
+ sleep(1)
+ print_usage()
+ sys.exit(1)
+
+ if options.remove:
+ if len(args) > 1:
+ error("Please remove packages one at a time")
+ sys.exit(1)
+ elif not o_re_expr.match(args[0].rstrip("/")):
+ error("Expected full package name as argument")
+ sys.exit(1)
+ elif not os.path.exists(os.path.join(portdir, args[0].rstrip("/"))):
+ error("No such package '%s'" % args[0].rstrip("/"))
+ sys.exit(1)
+ else:
+ if not options.cvs_up:
+ update_categories(portdir, args, cvscmd["update"])
+ return (args[0].rstrip("/"), None)
+
+ if len(args) == 2:
+ if not o_re_expr.match(args[0].rstrip("/")):
+ error("Expected full package name as origin argument")
+ booboo = True
+ elif not o_re_expr.match(args[1].rstrip("/")):
+ error("Expected full package name as destination argument")
+ booboo = True
+
+ if booboo == True:
+ sys.exit(1)
+ else:
+ error("Expected two arguments as input.")
+ print_usage()
+ sys.exit(1)
+
+ if not options.cvs_up:
+ update_categories(portdir, args, cvscmd["update"])
+
+ if not os.path.exists(os.path.join(portdir, args[0].rstrip("/"))):
+ error("No such package '%s'" % args[0].rstrip("/"))
+ booboo = True
+ elif os.path.exists(os.path.join(portdir, args[1].rstrip("/"))):
+ error("Package '%s' already exists" % args[1].rstrip("/"))
+ booboo = True
+
+ if booboo == True:
+ sys.exit(1)
+
+ return (args[0].rstrip("/"), args[1].rstrip("/"))
+
+def check_repos(portdir):
+
+ files = os.listdir(portdir)
+
+ for file in files:
+ if not os.path.isdir(file):
+ files.remove(file)
+
+ if "CVS" not in files:
+ error("Current directory doesn't look like a CVS repository")
+ sys.exit(1)
+
+def check_commit_queue():
+
+ empty = True
+
+ print
+ print "%s Checking commit queue for outstanding changes..." % green(" *")
+ print "%s Note: This may take a VERY long time" % yellow(" *")
+ print
+
+ output = commands.getoutput("cvs diff")
+
+ for line in output.split("\n"):
+ if not line.startswith("?"):
+ empty = False
+ break
+
+ if empty == False:
+ error("Commit queue not empty! Please commit all outstanding changes before using %s." % __productname__)
+ sys.exit(1)
+
+def update_categories(portdir, catpkgs, cvsupcmd):
+
+ my_catpkgs = []
+
+ print
+ print "%s Updating categories: " % green(" *")
+
+ if len(catpkgs) >= 2:
+ if catpkgs[0].split("/", 1)[0] == catpkgs[1].split("/", 1)[0]:
+ my_catpkgs.append(catpkgs[0])
+ else:
+ my_catpkgs.append(catpkgs[0])
+ my_catpkgs.append(catpkgs[1])
+ else:
+ my_catpkgs.append(catpkgs[0])
+
+ for catpkg in my_catpkgs:
+ (category, package) = catpkg.split("/", 1)
+ if os.path.exists(os.path.join(portdir, category)):
+ os.chdir(os.path.join(portdir, category))
+ print " %s %s" % (green("*"), category)
+ do_cmd(cvsupcmd)
+ else:
+ print " %s %s" % (red("!"), category)
+
+ os.chdir(portdir)
+
+def error(msg):
+
+ sys.stderr.write("\n%s ERROR: %s\n" % (red("!!!"), msg))
+
+def signal_handler(signal_number=None, stack_frame=None):
+
+ error("Caught SIGINT; exiting...")
+ sys.exit(1)
+ os.kill(0, signal.SIGKILL)
+
+def do_cmd(cmd):
+
+ (status, output) = commands.getstatusoutput(cmd)
+ if status != 0:
+ error("Command '%s' failed with exit status %d." % (cmd, status))
+ for line in output.split("\n"):
+ if line != "":
+ print " %s %s" % (red("!"), line)
+ sys.exit(1)
+
+class CVSAbstraction:
+
+ def __init__(self, portdir, oldcatpkg, newcatpkg, cvscmd, options):
+
+ self._portdir = portdir
+ self._cvscmd = cvscmd
+ self._options = options
+ self._ignore = ("CVS")
+
+ self._old_category = ""
+ self._old_package = ""
+ self._new_category = ""
+ self._new_package = ""
+ self._old_catpkg = oldcatpkg
+ self._new_catpkg = newcatpkg
+
+ self._action = ""
+
+ self._distinguish_action(oldcatpkg, newcatpkg)
+
+ def _distinguish_action(self, oldcatpkg, newcatpkg):
+
+ (self._old_category, self._old_package) = oldcatpkg.split("/")
+ if newcatpkg:
+ (self._new_category, self._new_package) = newcatpkg.split("/")
+
+ if self._old_category != self._new_category and self._new_category:
+ if self._old_package != self._new_package and self._new_package:
+ self._action = "MOVE & RENAME"
+ else:
+ self._action = "MOVE"
+ elif self._old_package != self._new_package and self._new_package:
+ self._action = "RENAME"
+ elif not self._new_package:
+ self._action = "REMOVE"
+ else:
+ error("Unable to distingush required action.")
+ sys.exit(1)
+
+ def __backup(self):
+
+ print "%s Backing up %s..." % (green(" *"), turquoise(self._old_catpkg))
+
+ if not os.path.exists("/tmp/%s" % __productname__):
+ os.mkdir("/tmp/%s" % __productname__)
+
+ if os.path.exists("/tmp/%s/%s" % (__productname__, self._old_package)):
+ do_cmd("rm -rf /tmp/%s/%s" % (__productname__, self._old_package))
+
+ do_cmd("cp -R %s /tmp/%s/%s" % (os.path.join(self._portdir, self._old_catpkg), __productname__, self._old_package))
+
+ def perform_action(self):
+
+ count_down = 5
+
+ print
+ if self._action == "REMOVE":
+ print "%s Performing a '%s' of %s..." % (green(" *"), green(self._action), turquoise(self._old_catpkg))
+ else:
+ print "%s Performing a '%s' of %s to %s..." % (green(" *"), green(self._action), turquoise(self._old_catpkg), yellow(self._new_catpkg))
+
+ if not self._options.countdown:
+ print "%s Performing in: " % green(" *"),
+ count = range(count_down)
+ count.reverse()
+ for second in count:
+ sys.stdout.write("%s " % red(str(second + 1)))
+ sys.stdout.flush()
+ sleep(1)
+ print
+
+ if not self._action == "REMOVE":
+ self.__backup()
+
+ if self._action == "MOVE & RENAME":
+ self._perform_move_rename()
+ elif self._action == "MOVE":
+ self._perform_move()
+ elif self._action == "RENAME":
+ self._perform_rename()
+ elif self._action == "REMOVE":
+ self._perform_remove()
+
+ def _perform_remove(self):
+
+ deps = self.__get_reverse_deps()
+
+ if deps:
+ print "%s The following ebuild(s) depend on this package:" % red(" *")
+ for dep in deps:
+ print "%s %s" % (red(" !"), dep)
+ if self._options.force:
+ print "%s Are you sure you wish to force removal of this package?" % yellow(" *"),
+ try:
+ choice = raw_input("(Yes/No): ")
+ except KeyboardInterrupt:
+ error("Interrupted by user.")
+ sys.exit(1)
+ if choice.strip().lower() != "yes":
+ error("Bailing on forced removal.")
+ sys.exit(1)
+ else:
+ error("Refusing to remove from CVS, package has dependents.")
+ sys.exit(1)
+
+ self.__remove_old_package()
+
+ def _perform_move(self):
+
+ self.__add_new_package()
+ self.__regen_manifest()
+ self.__update_dependents(self.__get_reverse_deps())
+ self.__remove_old_package()
+
+ def _perform_move_rename(self):
+
+ self._perform_rename()
+
+ def _perform_rename(self):
+
+ self.__rename_files()
+ self.__add_new_package()
+ self.__regen_digests()
+ self.__update_dependents(self.__get_reverse_deps())
+ self.__remove_old_package()
+
+ def __rename_files(self):
+
+ def rename_files(arg, dir, files):
+
+ if os.path.basename(dir) not in self._ignore:
+ if os.path.basename(dir) != self._old_package:
+ for file in files:
+ new_file = ""
+ if file.find(self._old_package) >= 0:
+ new_file = file.replace(self._old_package, self._new_package)
+ do_cmd("mv %s %s" % (os.path.join(dir, file), os.path.join(dir, new_file)))
+ if not os.path.isdir(os.path.join(dir, new_file)) and not file.startswith("digest-"):
+ self.__rename_file_contents(os.path.join(dir, new_file))
+ else:
+ for file in files:
+ if file.endswith(".ebuild"):
+ new_file = file.replace(self._old_package, self._new_package)
+ do_cmd("mv %s %s" % (os.path.join(dir, file), os.path.join(dir, new_file)))
+ self.__rename_file_contents(os.path.join(dir, new_file))
+ elif file.endswith(".xml"):
+ self.__rename_file_contents(os.path.join(dir, file))
+
+ print "%s Renaming files..." % green(" *")
+ os.path.walk("/tmp/%s/%s" % (__productname__, self._old_package), rename_files , None)
+ do_cmd("mv /tmp/%s/%s /tmp/%s/%s" % (__productname__, self._old_package, __productname__, self._new_package))
+
+ def __regen_manifest(self, path=None, dep=False):
+
+ if dep:
+ print "%s Regenerating Manifest..." % green(" *")
+ else:
+ print "%s Regenerating Manifest..." % green(" *")
+ if path:
+ os.chdir(path)
+ else:
+ os.chdir(os.path.join(self._portdir, self._new_catpkg))
+ for ebuild in os.listdir("."):
+ if ebuild.endswith(".ebuild"):
+ do_cmd("/usr/lib/portage/bin/ebuild %s manifest" % ebuild)
+ break
+
+ self.__gpg_sign(dep)
+
+ def __regen_digests(self):
+
+ print "%s Regenerating digests:" % green(" *")
+ os.chdir(os.path.join(self._portdir, self._new_catpkg))
+ for digest in os.listdir("files/"):
+ if digest.startswith("digest-"):
+ os.unlink("files/%s" % digest)
+ for ebuild in os.listdir("."):
+ if ebuild.endswith(".ebuild"):
+ print " >>> %s" % ebuild
+ do_cmd("/usr/lib/portage/bin/ebuild %s digest" % ebuild)
+
+ self.__gpg_sign()
+
+ def __gpg_sign(self, dep=False):
+
+ gpg_cmd = ""
+
+ os.chdir(os.path.join(self._portdir, self._new_catpkg))
+
+ if "sign" in portage.features:
+ if dep:
+ print "%s GPG Signing Manifest..." % green(" *")
+ else:
+ print "%s GPG Signing Manifest..." % green(" *")
+ gpg_cmd = "gpg --quiet --sign --clearsign --yes --default-key %s" % portage.settings["PORTAGE_GPG_KEY"]
+ if portage.settings.has_key("PORTAGE_GPG_DIR"):
+ gpg_cmd = "%s --homedir %s" % (gpg_cmd, portage.settings["PORTAGE_GPG_DIR"])
+ do_cmd("%s Manifest" % gpg_cmd)
+ do_cmd("mv Manifest.asc Manifest")
+ do_cmd("%s 'Manifest recommit'" % self._cvscmd["commit"])
+
+ def __rename_file_contents(self, file):
+
+ def choice_loop(line, match_count, choice_list, type="name", replace=""):
+
+ new_line = line
+ accepted = False
+ skipp = False
+
+ while(not accepted):
+ print " ",
+ if len(choice_list) > 0:
+ for choice in choice_list:
+ print "%s: Replace with '%s'," % (white(choice), green(choice_list[choice])),
+ if match_count == 0:
+ print "%s: Pass, %s: Skip this file, %s: Custom" % (white(str(len(choice_list)+1)), white(str(len(choice_list)+2)), white(str(len(choice_list)+3))),
+ else:
+ print "%s: Pass, %s: Custom" % (white(str(len(choice_list)+1)), white(str(len(choice_list)+2))),
+ try:
+ input = raw_input("%s " % white(":"))
+ except KeyboardInterrupt:
+ print
+ error("Interrupted by user.")
+ sys.exit(1)
+ if choice_list.has_key(input):
+ if type == "name":
+ new_line = new_line.replace(self._old_package, choice_list[input])
+ accepted = True
+ elif type == "P":
+ new_line = new_line.replace("${P}", choice_list[input])
+ accepted = True
+ elif type == "PN":
+ new_line = new_line.replace("${PN}", choice_list[input])
+ accepted = True
+ elif type == "PV":
+ new_line = new_line.replace("${PV}", choice_list[input])
+ accepted = True
+ elif type == "PVR":
+ new_line = new_line.replace("${PVR}", choice_list[input])
+ accepted = True
+ elif type == "PR":
+ new_line = new_line.replace("${PR}", choice_list[input])
+ accepted = True
+ elif type == "PF":
+ new_line = new_line.replace("${PF}", choice_list[input])
+ accepted = True
+ elif input == str(len(choice_list)+1):
+ accepted = True
+ elif input == str(len(choice_list)+2) and match_count == 0:
+ accepted = True
+ skipp = True
+ elif input == str(len(choice_list)+3) and match_count == 0 or input == str(len(choice_list)+2) and match_count != 0:
+
+ input_accepted = False
+
+ while(not input_accepted):
+ try:
+ custom_input = raw_input(" %s Replacement string: " % green("*"))
+ except KeyboardInterrupt:
+ print
+ error("Interrupted by user.")
+ sys.exit(1)
+ while(1):
+ print " %s Replace '%s' with '%s'? (Y/N)" % (yellow("*"), white(replace), white(custom_input)),
+ try:
+ yes_no = raw_input(": ")
+ except KeyboardInterrupt:
+ print
+ error("Interrupted by user.")
+ sys.exit(1)
+ if yes_no.lower() == "y":
+ input_accepted = True
+ break
+ elif yes_no.lower() == "n":
+ break
+
+ new_line = new_line.replace(replace, custom_input)
+ accepted = True
+ else:
+ accepted = False
+
+ if skipp:
+ break
+
+ return (new_line, skipp)
+
+ found = False
+ contents = []
+ new_contents = []
+ match_count = 0
+ skipp = False
+
+ try:
+ readfd = open(file, "r")
+ contents = readfd.readlines()
+ readfd.close()
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+
+ for line in contents:
+ if line.find(self._old_package) >= 0:
+ found = True
+ break
+
+ if found == True:
+ print "%s Editing %s:" % (green(" *"), white(file.split("/tmp/%s/%s/" % (__productname__, self._old_package))[1]))
+ try:
+ writefd = open(file, "w")
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+ for line in contents:
+ tmp_line = line
+ if not line.startswith("# $Header:"):
+ if line.find(self._old_package) >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace(self._old_package, yellow(self._old_package)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": self._new_package,
+ "2": "${PN}"}, type="name", replace=self._old_package)
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${P}") >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace("${P}", yellow("${P}")))
+ (pkg, version, revising) = portage.pkgsplit(os.path.split(file)[1][:-7])
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s" % (pkg, version),
+ "2": "%s-%s" % (self._old_package, version)}, type="P", replace="${P}")
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PN}") >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace("${PN}", yellow("${PN}")))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": self._new_package,
+ "2": self._old_package}, type="PN", replace="${PN}")
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PV}") >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace("${PV}", yellow("${PV}")))
+ (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": version}, type="PV", replace="${PV}")
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PVR}") >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace("${PVR}", yellow("${PVR}")))
+ (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s" % (version, revision)}, type="PVR", replace="${PVR}")
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PR}") >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace("${PR}", yellow("${PR}")))
+ (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": revision}, type="PR", replace="${PR}")
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PF}") >= 0:
+ print "%s %s" % (green(" !"), line.strip().replace("${PF}", yellow("${PF}")))
+ (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s-%s" % (pkg, version, revision),
+ "2": "%s-%s-%s" % (self._old_package, version, revision)}, type="PF", replace="${PF}")
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${P/") >= 0:
+ start = line.find("${P/")
+ i = 0
+ hi_str = ""
+ while(line[start + (i - 1)] != "}"):
+ hi_str += line[start + i]
+ i += 1
+ print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PN/") >= 0:
+ start = line.find("${PN/")
+ i = 0
+ hi_str = ""
+ while(line[start + (i - 1)] != "}"):
+ hi_str += line[start + i]
+ i += 1
+ print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PV/") >= 0:
+ start = line.find("${PV/")
+ i = 0
+ hi_str = ""
+ while(line[start + (i - 1)] != "}"):
+ hi_str += line[start + i]
+ i += 1
+ print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PVR/") >= 0:
+ start = line.find("${PVR/")
+ i = 0
+ hi_str = ""
+ while(line[start + (i - 1)] != "}"):
+ hi_str += line[start + i]
+ i += 1
+ print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PR/") >= 0:
+ start = line.find("${PR/")
+ i = 0
+ hi_str = ""
+ while(line[start + (i - 1)] != "}"):
+ hi_str += line[start + i]
+ i += 1
+ print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
+ match_count += 1
+ if skipp:
+ break
+ if line.find("${PF/") >= 0:
+ start = line.find("${PF/")
+ i = 0
+ hi_str = ""
+ while(line[start + (i - 1)] != "}"):
+ hi_str += line[start + i]
+ i += 1
+ print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
+ (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
+ match_count += 1
+ if skipp:
+ break
+
+ new_contents.append(tmp_line)
+
+ if not skipp:
+ for line in new_contents:
+ writefd.write(line)
+ else:
+ for line in contents:
+ writefd.write(line)
+
+ writefd.close()
+
+ def __update_dependents(self, dep_list):
+
+ if len(dep_list) <= 0:
+ return
+
+ print "%s Updating dependents:" % green(" *")
+ os.chdir(self._portdir)
+
+ for dep in dep_list:
+ print " >>> %s" % dep
+ new_contents = []
+ (category, pkg) = dep.split("/")
+ pkg_split = portage.pkgsplit(pkg)
+ os.chdir(self._portdir)
+ do_cmd("%s %s" % (self._cvscmd["update"], os.path.join(category, pkg_split[0])))
+
+ try:
+ readfd = open(os.path.join(self._portdir, category, pkg_split[0], "%s.ebuild" % pkg), "r")
+ contents = readfd.readlines()
+ readfd.close()
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+
+ for line in contents:
+ if self._old_catpkg in line:
+ new_contents.append(line.replace(self._old_catpkg, self._new_catpkg))
+ else:
+ new_contents.append(line)
+
+ try:
+ writefd = open(os.path.join(self._portdir, category, pkg_split[0], "%s.ebuild" % pkg), "w")
+ writefd.write("".join(new_contents))
+ writefd.close()
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+
+ os.chdir(os.path.join(self._portdir, category, pkg_split[0]))
+ do_cmd("echangelog 'Dependency update: %s -> %s.'" % (self._old_catpkg, self._new_catpkg))
+ do_cmd("%s 'Dependency update: %s -> %s.'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg))
+ self.__regen_manifest(path=os.path.join(self._portdir, category, pkg_split[0]), dep=True)
+
+ def __get_reverse_deps(self):
+
+ dep_list = []
+ conf_portdir = "/usr/portage"
+
+ def scan_for_dep(arg, dir, files):
+
+ (null, category) = os.path.split(dir)
+
+ for file in files:
+ if self._old_catpkg not in os.path.join(category, file):
+ if not os.path.isdir(os.path.join(dir, file)):
+ try:
+ fd = open(os.path.join(dir, file), "r")
+ contents = fd.readlines()
+ fd.close()
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+ if self._old_catpkg in contents[0] or self._old_catpkg in contents[1] or self._old_catpkg in contents[12]:
+ dep_list.append(os.path.join(category, file))
+
+ print "%s Resolving reverse dependencies..." % green(" *")
+
+ try:
+ fd = open("/etc/make.conf", "r")
+ contents = fd.readlines()
+ fd.close()
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+
+ for line in contents:
+ if line.startswith("PORTDIR="):
+ (null, conf_portdir) = line.strip("\"\n").split("=")
+ break
+
+ os.path.walk(os.path.join(conf_portdir, "metadata/cache"), scan_for_dep, None)
+
+ return dep_list
+
+ def __remove_old_package(self):
+
+ def remove_files(arg, dir, files):
+
+ if os.path.basename(dir) not in self._ignore:
+ for file in files:
+ if not os.path.isdir(os.path.join(dir, file)):
+ print " <<< %s" % (os.path.join(dir.strip("./"), file))
+ os.unlink(os.path.join(dir, file))
+ do_cmd("%s %s" % (self._cvscmd["remove"], os.path.join(dir, file)))
+
+ print "%s Removing %s from CVS:" % (green(" *"), turquoise(self._old_catpkg))
+ os.chdir(os.path.join(self._portdir, self._old_catpkg))
+ os.path.walk('.', remove_files , None)
+ os.chdir("..")
+
+ print "%s Commiting changes..." % green(" *")
+ if self._options.remove:
+ explanation = ""
+ while(1):
+ print "%s Please provide an explanation for this removal:" % yellow(" *"),
+ try:
+ explanation = raw_input("")
+ explanation = explanation.replace("'", "\\'").replace('"', '\\"')
+ except KeyboardInterrupt:
+ print
+ error("Interrupted by user.")
+ sys.exit(1)
+ if explanation != "":
+ break
+ do_cmd("""%s "Removed from %s: %s" """ % (self._cvscmd["commit"], self._old_category, explanation))
+ else:
+ do_cmd("%s 'Moved to %s.'" % (self._cvscmd["commit"], self._new_catpkg))
+ do_cmd("rm -rf %s" % os.path.join(self._portdir, self._old_catpkg))
+
+ print "%s Checking for remnant files..." % (green(" *"))
+ do_cmd(self._cvscmd["update"])
+
+ if not os.path.exists(os.path.join(self._portdir, self._old_catpkg)):
+ if not self._action == "REMOVE":
+ print "%s %s successfully removed from CVS." % (green(" *"), turquoise(self._old_catpkg))
+ else:
+ error("Remnants of %s still remain in CVS." % (turquoise(self._old_catpkg)))
+
+ def __add_new_package(self):
+
+ def add_files(arg, dir, files):
+
+ (null, null, null, dirs) = dir.split("/", 3)
+
+ if os.path.basename(dir) not in self._ignore:
+ os.chdir(os.path.join(self._portdir, self._new_category))
+ if os.path.basename(dir) != self._new_package:
+ print " >>> %s/" % dirs
+ os.mkdir(dirs)
+ do_cmd("%s %s" % (self._cvscmd["add"], dirs))
+ for file in files:
+ if not os.path.isdir(os.path.join(dir, file)):
+ print " >>> %s" % os.path.join(dirs, file)
+ do_cmd("cp %s %s" % (os.path.join(dir, file), dirs))
+ do_cmd("%s %s" % (self._cvscmd["add"], os.path.join(dirs, file)))
+
+ print "%s Adding %s to CVS:" % (green(" *"), turquoise(self._new_catpkg))
+ os.chdir(os.path.join(self._portdir, self._new_category))
+ print " >>> %s/" % self._new_package
+ os.mkdir(self._new_package)
+ do_cmd("%s %s" % (self._cvscmd["add"], self._new_package))
+ os.chdir(self._new_package)
+ os.path.walk("/tmp/%s/%s" % (__productname__, self._new_package), add_files , None)
+ os.chdir(os.path.join(self._portdir, self._new_catpkg))
+
+ print "%s Adding ChangeLog entry..." % green(" *")
+ do_cmd("echangelog 'Moved from %s to %s.'" % (self._old_catpkg, self._new_catpkg))
+
+ print "%s Commiting changes..." % green(" *")
+ do_cmd("%s 'Moved from %s to %s.'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg))
+
+ print "%s %s successfully added to CVS." % (green(" *"), turquoise(self._new_catpkg))
+
+ def log_move(self):
+
+ if not self._action == "REMOVE":
+
+ update_files = []
+ update_regex = "^[\d]Q-[\d]{4}$"
+
+ p_file_regex = re.compile(update_regex)
+
+ print "%s Logging move:" % (green(" *"))
+ os.chdir(os.path.join(self._portdir, "profiles/updates"))
+ do_cmd(self._cvscmd["update"])
+
+ for file in os.listdir("."):
+ o_file_regex = p_file_regex.match(file)
+ if file not in self._ignore and o_file_regex:
+ (q, y) = file.split("-")
+ update_files.append("%s-%s" % (y, q))
+
+ update_files.sort()
+ (y, q) = update_files[-1].split("-")
+ upfile = "%s-%s" % (q, y)
+ print " >>> %s" % upfile
+
+ try:
+ fd = open(upfile, "a")
+ fd.write("move %s %s\n" % (self._old_catpkg, self._new_catpkg))
+ fd.close()
+ except IOError, e:
+ error(e)
+ sys.exit(1)
+
+ do_cmd("%s 'Moved %s to %s'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg))
+ os.chdir(self._portdir)
+
+ def clean_up(self):
+
+ if not self._action == "REMOVE":
+ print "%s Removing back-up..." % (green(" *"))
+ do_cmd("rm -rf /tmp/%s/%s" % (__productname__, self._old_package))
+ if len(os.listdir("/tmp/%s" % __productname__)) == 0:
+ do_cmd("rmdir /tmp/%s" % __productname__)
+
+ os.chdir(self._portdir)
+
+if __name__ == "__main__":
+
+ signal.signal(signal.SIGINT, signal_handler)
+
+ cvscmd = {"remove": "cvs -Qf rm",
+ "commit": "cvs -Qf commit -m",
+ "update": "cvs -Qf up -dPC",
+ "add": "cvs -Qf add"}
+
+ parser = OptionParser(usage="%prog [ option ] [ origin ] [ destination ]", version="%s-%s" % (__productname__, __version__))
+ parser.add_option("--usage", action="store_true", dest="usage", default=False, help="Pint usage information")
+ parser.add_option("-q", "--queue-check", action="store_true", dest="commit_queue", default=False, help="Check the cvs tree for files awaiting commit")
+ parser.add_option("-u", "--no-cvs-up", action="store_true", dest="cvs_up", default=False, help="Skip running cvs up in the origin and destination categories")
+ parser.add_option("-c", "--no-countdown", action="store_true", dest="countdown", default=False, help="Skip countdown before performing")
+ parser.add_option("-R", "--remove", action="store_true", dest="remove", default=False, help="Remove package")
+ parser.add_option("-F", "--force", action="store_true", dest="force", default=False, help="Force removal of package, ignoring any reverse deps")
+ (options, args) = parser.parse_args()
+
+ if options.usage:
+ print_usage()
+ sys.exit(0)
+
+ if randint(1, 100) == 50:
+ print "%s I put on my robe and wizard hat..." % green(" *")
+
+ portdir = check_cwd(portage.settings["PORTDIR"].rstrip("/"))
+ check_repos(portdir)
+ (oldcatpkg, newcatpkg) = check_args(args, portdir, options, cvscmd)
+
+ if options.commit_queue:
+ check_commit_queue()
+
+ ThisPackage = CVSAbstraction(portdir, oldcatpkg, newcatpkg, cvscmd, options)
+
+ ThisPackage.perform_action()
+ ThisPackage.log_move()
+ ThisPackage.clean_up()
+
+ if options.remove:
+ print "%s %s successfully removed from CVS." % (green(" *"), turquoise(oldcatpkg))
+ else:
+ print "%s %s successfully moved to %s." % (green(" *"), turquoise(oldcatpkg), yellow(newcatpkg))
+