From 084cd89a592f37d1713f6675756db65bd3c0869b Mon Sep 17 00:00:00 2001 From: karltk Date: Fri, 10 Sep 2004 09:20:47 +0000 Subject: [PATCH] New upstream release svn path=/; revision=127 --- trunk/src/epkgmove/ChangeLog | 4 + trunk/src/epkgmove/epkgmove | 1040 ++++++++++++++++++++++++++-------- 2 files changed, 794 insertions(+), 250 deletions(-) diff --git a/trunk/src/epkgmove/ChangeLog b/trunk/src/epkgmove/ChangeLog index f5920cd..b8ee64a 100644 --- a/trunk/src/epkgmove/ChangeLog +++ b/trunk/src/epkgmove/ChangeLog @@ -1,3 +1,7 @@ +2004-09-10 Karl Trygve Kalleberg + * Updated epkgmove to 1.0, as availble on + http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-1.0.py + 2004-07-21 Karl Trygve Kalleberg * Updated epkgmove to 0.5, as availble on http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-0.5.py diff --git a/trunk/src/epkgmove/epkgmove b/trunk/src/epkgmove/epkgmove index 585569c..5fa599a 100644 --- a/trunk/src/epkgmove/epkgmove +++ b/trunk/src/epkgmove/epkgmove @@ -1,307 +1,847 @@ -#!/usr/bin/env python2 -# Copyright 1999-2004 Gentoo Technologies, Inc. -# Distributed under the terms of the GNU General Public License v2 +#!/usr/bin/python -tO +# Copyright 2004 Ian Leitch +# Copyright 1999-2004 Gentoo Foundation # $Header$ # -# Author: +# Author: # Ian Leitch # -# ChangeLog: -# -# 4 Jun 2004 - epkgmove-0.5 -# - Fixed bug where epkgmove would fail if files/ contained subdirectories -# - Add the package to its new location before removing it from the original -# - Filter out non-update files in profiles/updates -# - Backup to /tmp/__productname__/package and make a little extra effort to keep clean -# - Small input validation fix -# -# 12 Feb 2004 - epkgmove-0.4, -# - Set PORTDIR to pwd if not in PORTDIR -# - Formatting fixes -# -# 02 Jan 2004 - epkgmove-0.3, -# - Check exit status of commands, die if non zero -# - Check if PORTDIR is a CVS repository -# - Name changed to epkgmove -# -# 02 Jan 2004 - pkgmove-0.2, -# - Code cleanups -# - Take only a catgegory name as destination argument -# - Wrote the AddUpdate() function - thanks to lanius -# - Catch SIGINT -# - err() now prints to stderr -# - strip trailing /'s from input -# - use -Qf flags on cvs commands -# - Recursively find all files to remove/add -# - Tested on local repository - command changes accordingly -# - Update categories before working in them -# -# 28 Dec 2003 - pkgmove-0.1, -# - 0.1 Beta Release -# -# TODO: -# -# - A complete rewrite. This was my first ever Python script and although I believe it to be safe to use, -# it is not well structured at all. -# import os -import re import sys import signal +import commands +from time import sleep +from random import randint +from optparse import OptionParser import portage from output import * -__author__ = "Ian Leitch" +__author__ = "Ian Leitch" __email__ = "port001@gentoo.org" -__productname__ = "epkgmove" -__version__ = "0.5" -__description__ = "A simple tool for moving packages in CVS" - -def main(): - - signal.signal(signal.SIGINT, sighandler) - - global portdir, ignore, cvsrmcmd, cvscommitcmd, cvsupcmd, cvsaddcmd, devnull - - portdir = portage.settings["PORTDIR"] - ignore = ("CVS") - cvsrmcmd = "cvs -Qf rm" - cvscommitcmd = "cvs -Qf commit -m" - cvsupcmd = "cvs -Qf up -dPC ." - cvsaddcmd = "cvs -Qf add" - devnull = "> /dev/null" - - if len(sys.argv) != 3: - print - err("Expected two arguments as input.") - help() - sys.exit(1) - - Checkcwd() - CheckArgs() - print "%s Moving %s to %s..." % (green(" *"), turquoise(location), yellow(destination)) - BackupPkg() - AddPackage() - RemovePackage() - AddUpdate() - CleanUp() - print "%s %s successfully moved to %s." % (green(" *"), turquoise(location), yellow(destination)) - sys.exit(0) +__productname__ = "epkgmove" +__version__ = "1.0 - \"The version ciaranm dreamed about.\"" +__description__ = "A tool for moving and renaming packages in CVS" -def help(): +def print_usage(): print - print "%s %s [ %s ] [ %s ]" % (white("Usage:"), turquoise(__productname__), green("location"), green("destination")) - print " %s: Expects a package name in the format 'category/pkg' e.g net-im/gaim" % (green("location")) - print " %s: Expects a category name" % (green("destination")) - -def about(): - + 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 - print "%s %s %s" % (white("About:"), turquoise(__productname__), green(__version__)) - print " \"%s\"" % (__description__) - print " By %s <%s>" % (__author__, __email__) -def docmd(cmd): +def check_cwd(portdir): - retval = os.system(cmd) - if retval != 0: - err("Command '%s' failed with exit status %d." % (cmd, retval)) + 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) -def err(msg): - - sys.stderr.write("%s ERROR: %s\n" % (red("!!!"), msg)) - -def sighandler(signal_number=None, stack_frame=None): + 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: + 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) - err("Caught SIGINT; exiting...\n") - sys.exit(1) - os.kill(0,signal.SIGKILL) + if not options.cvs_up: + update_categories(portdir, args, cvscmd["update"]) -def Checkcwd(): + 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 - global portdir + if booboo == True: + sys.exit(1) + + return (args[0].rstrip("/"), args[1].rstrip("/")) - if os.getcwd() != portdir: - print "%s Not in PORTDIR!" % yellow(" *") - print "%s Setting to: %s" % (yellow(" *"), os.getcwd()) - portdir = os.getcwd() +def check_repos(portdir): files = os.listdir(portdir) - + for file in files: if not os.path.isdir(file): - files.remove(file) - + files.remove(file) + if "CVS" not in files: - err("No CVS directory, this doesn't look like a repository!") + error("Current directory doesn't look like a CVS repository") sys.exit(1) -def UpdateCats(): - - print "%s Updating %s & %s..." % (green(" *"), locategory, decategory) +def check_commit_queue(): - os.chdir(os.path.join(portdir, locategory)) - docmd(cvsupcmd) - os.chdir(os.path.join(portdir, decategory)) - docmd(cvsupcmd) + empty = True -def CheckArgs(): + 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") - global fulllocation, location, fulldestination, destination, locategory, lopkg, decategory - - try: - (locategory, lopkg) = sys.argv[1].strip('/').split('/') - except: - err("'%s' Invalid 'category/pkg'." % (sys.argv[1])) + 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) - location = os.path.join(locategory, lopkg) - decategory = sys.argv[2].strip('/') - fulllocation = os.path.join(portdir, location) - fulldestination = os.path.join(portdir, decategory, lopkg) - destination = os.path.join(decategory, lopkg) - - if re.search('/', decategory): - err("Expected category name as destination argument.") - sys.exit(1) +def update_categories(portdir, catpkgs, cvsupcmd): - if destination == location: - err("Don't waste my time...") - sys.exit(1) + my_catpkgs = [] - if not os.path.exists(os.path.join(portdir, decategory)): - err("No such category '%s'" % (decategory)) - sys.exit(1) + print + print "%s Updating categories: " % green(" *") - UpdateCats() + 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]) + + 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) - if not os.path.exists(fulllocation): - err("'%s' Invalid 'category/pkg'." % (location)) - sys.exit(1) + os.chdir(portdir) + +def error(msg): - if os.path.exists(fulldestination): - err("Destination location '%s' already exists." % (destination)) - sys.exit(1) + sys.stderr.write("\n%s ERROR: %s\n" % (red("!!!"), msg)) - if not os.path.exists(os.path.join(portdir, "profiles/updates")): - err("There doesn't seem to be a 'profiles/updates' directory here, I need it for later.") - sys.exit(1) +def signal_handler(signal_number=None, stack_frame=None): -def BackupPkg(): + error("Caught SIGINT; exiting...") + sys.exit(1) + os.kill(0, signal.SIGKILL) - print "%s Backing-up %s to /tmp/%s..." % (green(" *"), turquoise(location), __productname__) - if not os.path.exists("/tmp/%s" % __productname__): - os.mkdir("/tmp/%s" % __productname__) - docmd("cp -R %s /tmp/%s/%s" % (fulllocation, __productname__, lopkg)) +def do_cmd(cmd): -def RemovePackage(): - - def RemoveFiles(arg, dir, files): - if os.path.basename(dir) not in 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)) - docmd("%s %s" % (cvsrmcmd, os.path.join(dir, file))) - - print "%s Removing %s from CVS:" % (green(" *"), turquoise(location)) - os.chdir(fulllocation) - os.path.walk('.', RemoveFiles , None) - os.chdir("..") - - print "%s Running '%s 'Moving to %s''..." % (green(" *"), cvscommitcmd, destination) - docmd("%s 'Moving to %s' %s" % (cvscommitcmd, destination, devnull)) - docmd("rm -rf " + fulllocation) - - print "%s Checking if package still remains in CVS..." % (green(" *")) - docmd(cvsupcmd) - - if not os.path.exists(fulllocation): - print "%s %s successfully removed from CVS." % (green(" *"), turquoise(location)) - else: - err("Remnants of %s still remain in CVS." % (turquoise(location))) - -def AddPackage(): - - def AddFiles(arg, dir, files): - global dirhi - dirhi = "" - dest = "" - if os.path.basename(dir) not in ignore: - if os.path.basename(dir) != lopkg: - (rubbish, dirhi) = dir.split("tmp/%s/%s/" % (__productname__, lopkg)) - print " >>> %s/" % (dirhi) - os.mkdir(os.path.join(fulldestination, dirhi)) - docmd("%s %s" % (cvsaddcmd, dirhi)) - for file in files: - if not os.path.isdir(os.path.join(dir, file)): - print " >>> %s" % (os.path.join(dirhi, os.path.basename(file))) - if dirhi: - dest = dirhi - else: - dest = "." - docmd("cp %s %s" % (os.path.join(dir, file), dest)) - docmd("%s %s" % (cvsaddcmd, os.path.join(dirhi, file))) - - print "%s Adding %s to CVS:" % (green(" *"), turquoise(destination)) - - os.chdir(os.path.join(portdir, decategory)) - print " >>> %s/" % (lopkg) - os.mkdir(lopkg) - docmd("%s %s" % (cvsaddcmd,lopkg)) - os.chdir(lopkg) - os.path.walk("/tmp/%s/%s" % (__productname__, lopkg), AddFiles , None) - os.chdir(fulldestination) - print "%s Running 'echangelog 'Moved from %s to %s.''..." % (green(" *"), location, destination) - docmd("echangelog 'Moved from %s to %s.' %s" % (location, destination, devnull)) - - print "%s Running '%s 'Moved from %s to %s.''..." % (green(" *"), cvscommitcmd, location, destination) - docmd("%s 'Moved from %s to %s.' %s" % (cvscommitcmd, location, destination, devnull)) - - print "%s %s successfully added to CVS." % (green(" *"), turquoise(destination)) - -def AddUpdate(): - - updatefiles = [] - fileregex = "^[\d]Q-[\d]{4}$" + (status, output) = commands.getstatusoutput(cmd) + if status != 0: + error("Command '%s' failed with exit status %d." % (cmd, status)) + for line in output.split("\n"): + print " %s %s" % (red("!"), line) + sys.exit(1) + +class Package: - p_fileregex = re.compile(fileregex) + def __init__(self, portdir, oldcatpkg, newcatpkg, cvscmd, options): - print "%s Logging move in 'profiles/updates'..." % (green(" *")) - os.chdir(os.path.join(portdir, "profiles/updates")) - docmd(cvsupcmd) - - for file in os.listdir("."): - o_fileregex = p_fileregex.match(file) - if file not in ignore and o_fileregex: - (q, y) = file.split("-") - updatefiles.append(y + "-" + q) + 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)) - updatefiles.sort() - (y, q) = updatefiles[-1].split("-") - upfile = q + "-" + y + do_cmd("cp -R %s /tmp/%s/%s" % (os.path.join(self._portdir, self._old_catpkg), __productname__, self._old_package)) - print " >>> %s" % (upfile) + def perform_action(self): - f = open(upfile, 'a') - f.write("move %s %s\n" % (location, destination)) - f.close() + count_down = 5 - docmd("%s 'Moved from %s to %s' %s" % (cvscommitcmd, location, destination, devnull)) + 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.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.__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_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): + + gpg_cmd = "" + + if "sign" in portage.features: + print "%s GPG Signing Manifest..." % green(" *") + os.chdir(os.path.join(self._portdir, self._new_catpkg)) + 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 'GPG Signed'" % 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: Skipp 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): + + new_contents = [] + + if len(dep_list) <= 0: + return + + print "%s Updating dependents:" % green(" *") + os.chdir(self._portdir) + + for dep in dep_list: + print " >>> %s" % dep + (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)) + + 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(" *") + 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(location))) + + 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__": - os.chdir(portdir) + 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="Skipp running cvs up in the origin and destination categories") + parser.add_option("-c", "--no-countdown", action="store_true", dest="countdown", default=False, help="Skipp 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"][:-1]) + check_repos(portdir) + (oldcatpkg, newcatpkg) = check_args(args, portdir, options, cvscmd) + + if options.commit_queue: + check_commit_queue() -def CleanUp(): + ThisPackage = Package(portdir, oldcatpkg, newcatpkg, cvscmd, options) - print "%s Removing back-up..." % (green(" *")) - docmd("rm -rf /tmp/%s/%s" % (__productname__, lopkg)) - if len(os.listdir("/tmp/%s" % __productname__)) == 0: - docmd("rmdir /tmp/%s" % __productname__) + ThisPackage.perform_action() + ThisPackage.log_move() + ThisPackage.clean_up() -if __name__ == "__main__": - main() + 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)) -- 2.26.2