2 # Copyright 2004 Ian Leitch
3 # Copyright 1999-2004 Gentoo Foundation
7 # Ian Leitch <port001@gentoo.org>
15 from time import sleep
16 from random import randint
17 from optparse import OptionParser
21 from portage.output import *
25 __author__ = "Ian Leitch"
26 __email__ = "port001@gentoo.org"
27 __productname__ = "epkgmove"
28 __version__ = "1.3.1 - \"Moving Fusion + Bandages + Plasters\""
29 __description__ = "A tool for moving and renaming packages in CVS"
34 print "%s %s [ %s ] [ %s ] [ %s ]" % (white("Usage:"), turquoise(__productname__), green("option"), green("origin"), green("destination"))
35 print " '%s' and '%s' are expected as a full package name, e.g. net-im/gaim" % (green("origin"), green("destination"))
36 print " See %s --help for a list of options" % __productname__
39 def check_cwd(portdir):
41 if os.getcwd() != portdir:
43 print "%s Not in PORTDIR!" % yellow(" *")
44 print "%s Setting to: %s" % (yellow(" *"), os.getcwd())
45 os.environ["PORTDIR"]=os.getcwd()
50 def check_args(args, portdir, options, cvscmd):
53 re_expr = "^[\da-zA-Z-]{,}/[\d\w0-9-]{,}$"
54 o_re_expr = re.compile(re_expr)
57 print "\n%s ERROR: errr, didn't you forget something" % red("!!!"),
66 print "\n\n%s %s hits you with a clue stick %s" % (green(" *"), __productname__, green("*"))
73 error("Please remove packages one at a time")
75 elif not o_re_expr.match(args[0].rstrip("/")):
76 error("Expected full package name as argument")
78 elif not os.path.exists(os.path.join(portdir, args[0].rstrip("/"))):
79 error("No such package '%s'" % args[0].rstrip("/"))
82 if not options.cvs_up:
83 update_categories(portdir, args, cvscmd["update"])
84 return (args[0].rstrip("/"), None)
87 if not o_re_expr.match(args[0].rstrip("/")):
88 error("Expected full package name as origin argument")
90 elif not o_re_expr.match(args[1].rstrip("/")):
91 error("Expected full package name as destination argument")
97 error("Expected two arguments as input.")
101 if not options.cvs_up:
102 update_categories(portdir, args, cvscmd["update"])
104 if not os.path.exists(os.path.join(portdir, args[0].rstrip("/"))):
105 error("No such package '%s'" % args[0].rstrip("/"))
107 elif os.path.exists(os.path.join(portdir, args[1].rstrip("/"))):
108 error("Package '%s' already exists" % args[1].rstrip("/"))
114 return (args[0].rstrip("/"), args[1].rstrip("/"))
116 def check_repos(portdir):
118 files = os.listdir(portdir)
121 if not os.path.isdir(file):
124 if "CVS" not in files:
125 error("Current directory doesn't look like a CVS repository")
128 def check_commit_queue():
133 print "%s Checking commit queue for outstanding changes..." % green(" *")
134 print "%s Note: This may take a VERY long time" % yellow(" *")
137 output = commands.getoutput("cvs diff")
139 for line in output.split("\n"):
140 if not line.startswith("?"):
145 error("Commit queue not empty! Please commit all outstanding changes before using %s." % __productname__)
148 def update_categories(portdir, catpkgs, cvsupcmd):
153 print "%s Updating categories: " % green(" *")
155 if len(catpkgs) >= 2:
156 if catpkgs[0].split("/", 1)[0] == catpkgs[1].split("/", 1)[0]:
157 my_catpkgs.append(catpkgs[0])
159 my_catpkgs.append(catpkgs[0])
160 my_catpkgs.append(catpkgs[1])
162 my_catpkgs.append(catpkgs[0])
164 for catpkg in my_catpkgs:
165 (category, package) = catpkg.split("/", 1)
166 if os.path.exists(os.path.join(portdir, category)):
167 os.chdir(os.path.join(portdir, category))
168 print " %s %s" % (green("*"), category)
171 print " %s %s" % (red("!"), category)
177 sys.stderr.write("\n%s ERROR: %s\n" % (red("!!!"), msg))
179 def signal_handler(signal_number=None, stack_frame=None):
181 error("Caught SIGINT; exiting...")
183 os.kill(0, signal.SIGKILL)
187 (status, output) = commands.getstatusoutput(cmd)
189 error("Command '%s' failed with exit status %d." % (cmd, status))
190 for line in output.split("\n"):
192 print " %s %s" % (red("!"), line)
195 class CVSAbstraction:
197 def __init__(self, portdir, oldcatpkg, newcatpkg, cvscmd, options):
199 self._portdir = portdir
200 self._cvscmd = cvscmd
201 self._options = options
202 self._ignore = ("CVS")
204 self._old_category = ""
205 self._old_package = ""
206 self._new_category = ""
207 self._new_package = ""
208 self._old_catpkg = oldcatpkg
209 self._new_catpkg = newcatpkg
213 self._distinguish_action(oldcatpkg, newcatpkg)
215 def _distinguish_action(self, oldcatpkg, newcatpkg):
217 (self._old_category, self._old_package) = oldcatpkg.split("/")
219 (self._new_category, self._new_package) = newcatpkg.split("/")
221 if self._old_category != self._new_category and self._new_category:
222 if self._old_package != self._new_package and self._new_package:
223 self._action = "MOVE & RENAME"
225 self._action = "MOVE"
226 elif self._old_package != self._new_package and self._new_package:
227 self._action = "RENAME"
228 elif not self._new_package:
229 self._action = "REMOVE"
231 error("Unable to distingush required action.")
236 print "%s Backing up %s..." % (green(" *"), turquoise(self._old_catpkg))
238 if not os.path.exists("/tmp/%s" % __productname__):
239 os.mkdir("/tmp/%s" % __productname__)
241 if os.path.exists("/tmp/%s/%s" % (__productname__, self._old_package)):
242 do_cmd("rm -rf /tmp/%s/%s" % (__productname__, self._old_package))
244 do_cmd("cp -R %s /tmp/%s/%s" % (os.path.join(self._portdir, self._old_catpkg), __productname__, self._old_package))
246 def perform_action(self):
251 if self._action == "REMOVE":
252 print "%s Performing a '%s' of %s..." % (green(" *"), green(self._action), turquoise(self._old_catpkg))
254 print "%s Performing a '%s' of %s to %s..." % (green(" *"), green(self._action), turquoise(self._old_catpkg), yellow(self._new_catpkg))
256 if not self._options.countdown:
257 print "%s Performing in: " % green(" *"),
258 count = range(count_down)
261 sys.stdout.write("%s " % red(str(second + 1)))
266 if not self._action == "REMOVE":
269 if self._action == "MOVE & RENAME":
270 self._perform_move_rename()
271 elif self._action == "MOVE":
273 elif self._action == "RENAME":
274 self._perform_rename()
275 elif self._action == "REMOVE":
276 self._perform_remove()
278 def _perform_remove(self):
280 deps = self.__get_reverse_deps()
283 print "%s The following ebuild(s) depend on this package:" % red(" *")
285 print "%s %s" % (red(" !"), dep)
286 if self._options.force:
287 print "%s Are you sure you wish to force removal of this package?" % yellow(" *"),
289 choice = raw_input("(Yes/No): ")
290 except KeyboardInterrupt:
291 error("Interrupted by user.")
293 if choice.strip().lower() != "yes":
294 error("Bailing on forced removal.")
297 error("Refusing to remove from CVS, package has dependents.")
300 self.__remove_old_package()
302 def _perform_move(self):
304 self.__add_new_package()
305 self.__regen_manifest()
306 self.__update_dependents(self.__get_reverse_deps())
307 self.__remove_old_package()
309 def _perform_move_rename(self):
311 self._perform_rename()
313 def _perform_rename(self):
315 self.__rename_files()
316 self.__add_new_package()
317 self.__regen_digests()
318 self.__update_dependents(self.__get_reverse_deps())
319 self.__remove_old_package()
321 def __rename_files(self):
323 def rename_files(arg, dir, files):
325 if os.path.basename(dir) not in self._ignore:
326 if os.path.basename(dir) != self._old_package:
329 if file.find(self._old_package) >= 0:
330 new_file = file.replace(self._old_package, self._new_package)
331 do_cmd("mv %s %s" % (os.path.join(dir, file), os.path.join(dir, new_file)))
332 if not os.path.isdir(os.path.join(dir, new_file)) and not file.startswith("digest-"):
333 self.__rename_file_contents(os.path.join(dir, new_file))
336 if file.endswith(".ebuild"):
337 new_file = file.replace(self._old_package, self._new_package)
338 do_cmd("mv %s %s" % (os.path.join(dir, file), os.path.join(dir, new_file)))
339 self.__rename_file_contents(os.path.join(dir, new_file))
340 elif file.endswith(".xml"):
341 self.__rename_file_contents(os.path.join(dir, file))
343 print "%s Renaming files..." % green(" *")
344 os.path.walk("/tmp/%s/%s" % (__productname__, self._old_package), rename_files , None)
345 do_cmd("mv /tmp/%s/%s /tmp/%s/%s" % (__productname__, self._old_package, __productname__, self._new_package))
347 def __regen_manifest(self, path=None, dep=False):
350 print "%s Regenerating Manifest..." % green(" *")
352 print "%s Regenerating Manifest..." % green(" *")
356 os.chdir(os.path.join(self._portdir, self._new_catpkg))
357 for ebuild in os.listdir("."):
358 if ebuild.endswith(".ebuild"):
359 do_cmd("/usr/lib/portage/bin/ebuild %s manifest" % ebuild)
364 def __regen_digests(self):
366 print "%s Regenerating digests:" % green(" *")
367 os.chdir(os.path.join(self._portdir, self._new_catpkg))
368 for digest in os.listdir("files/"):
369 if digest.startswith("digest-"):
370 os.unlink("files/%s" % digest)
371 for ebuild in os.listdir("."):
372 if ebuild.endswith(".ebuild"):
373 print " >>> %s" % ebuild
374 do_cmd("/usr/lib/portage/bin/ebuild %s digest" % ebuild)
378 def __gpg_sign(self, dep=False):
382 os.chdir(os.path.join(self._portdir, self._new_catpkg))
384 if "sign" in portage.features:
386 print "%s GPG Signing Manifest..." % green(" *")
388 print "%s GPG Signing Manifest..." % green(" *")
389 gpg_cmd = "gpg --quiet --sign --clearsign --yes --default-key %s" % portage.settings["PORTAGE_GPG_KEY"]
390 if portage.settings.has_key("PORTAGE_GPG_DIR"):
391 gpg_cmd = "%s --homedir %s" % (gpg_cmd, portage.settings["PORTAGE_GPG_DIR"])
392 do_cmd("%s Manifest" % gpg_cmd)
393 do_cmd("mv Manifest.asc Manifest")
394 do_cmd("%s 'Manifest recommit'" % self._cvscmd["commit"])
396 def __rename_file_contents(self, file):
398 def choice_loop(line, match_count, choice_list, type="name", replace=""):
406 if len(choice_list) > 0:
407 for choice in choice_list:
408 print "%s: Replace with '%s'," % (white(choice), green(choice_list[choice])),
410 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))),
412 print "%s: Pass, %s: Custom" % (white(str(len(choice_list)+1)), white(str(len(choice_list)+2))),
414 input = raw_input("%s " % white(":"))
415 except KeyboardInterrupt:
417 error("Interrupted by user.")
419 if choice_list.has_key(input):
421 new_line = new_line.replace(self._old_package, choice_list[input])
424 new_line = new_line.replace("${P}", choice_list[input])
427 new_line = new_line.replace("${PN}", choice_list[input])
430 new_line = new_line.replace("${PV}", choice_list[input])
433 new_line = new_line.replace("${PVR}", choice_list[input])
436 new_line = new_line.replace("${PR}", choice_list[input])
439 new_line = new_line.replace("${PF}", choice_list[input])
441 elif input == str(len(choice_list)+1):
443 elif input == str(len(choice_list)+2) and match_count == 0:
446 elif input == str(len(choice_list)+3) and match_count == 0 or input == str(len(choice_list)+2) and match_count != 0:
448 input_accepted = False
450 while(not input_accepted):
452 custom_input = raw_input(" %s Replacement string: " % green("*"))
453 except KeyboardInterrupt:
455 error("Interrupted by user.")
458 print " %s Replace '%s' with '%s'? (Y/N)" % (yellow("*"), white(replace), white(custom_input)),
460 yes_no = raw_input(": ")
461 except KeyboardInterrupt:
463 error("Interrupted by user.")
465 if yes_no.lower() == "y":
466 input_accepted = True
468 elif yes_no.lower() == "n":
471 new_line = new_line.replace(replace, custom_input)
479 return (new_line, skipp)
488 readfd = open(file, "r")
489 contents = readfd.readlines()
495 for line in contents:
496 if line.find(self._old_package) >= 0:
501 print "%s Editing %s:" % (green(" *"), white(file.split("/tmp/%s/%s/" % (__productname__, self._old_package))[1]))
503 writefd = open(file, "w")
507 for line in contents:
509 if not line.startswith("# $Header:"):
510 if line.find(self._old_package) >= 0:
511 print "%s %s" % (green(" !"), line.strip().replace(self._old_package, yellow(self._old_package)))
512 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": self._new_package,
513 "2": "${PN}"}, type="name", replace=self._old_package)
517 if line.find("${P}") >= 0:
518 print "%s %s" % (green(" !"), line.strip().replace("${P}", yellow("${P}")))
519 (pkg, version, revising) = portage.pkgsplit(os.path.split(file)[1][:-7])
520 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s" % (pkg, version),
521 "2": "%s-%s" % (self._old_package, version)}, type="P", replace="${P}")
525 if line.find("${PN}") >= 0:
526 print "%s %s" % (green(" !"), line.strip().replace("${PN}", yellow("${PN}")))
527 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": self._new_package,
528 "2": self._old_package}, type="PN", replace="${PN}")
532 if line.find("${PV}") >= 0:
533 print "%s %s" % (green(" !"), line.strip().replace("${PV}", yellow("${PV}")))
534 (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
535 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": version}, type="PV", replace="${PV}")
539 if line.find("${PVR}") >= 0:
540 print "%s %s" % (green(" !"), line.strip().replace("${PVR}", yellow("${PVR}")))
541 (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
542 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s" % (version, revision)}, type="PVR", replace="${PVR}")
546 if line.find("${PR}") >= 0:
547 print "%s %s" % (green(" !"), line.strip().replace("${PR}", yellow("${PR}")))
548 (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
549 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": revision}, type="PR", replace="${PR}")
553 if line.find("${PF}") >= 0:
554 print "%s %s" % (green(" !"), line.strip().replace("${PF}", yellow("${PF}")))
555 (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7])
556 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s-%s" % (pkg, version, revision),
557 "2": "%s-%s-%s" % (self._old_package, version, revision)}, type="PF", replace="${PF}")
561 if line.find("${P/") >= 0:
562 start = line.find("${P/")
565 while(line[start + (i - 1)] != "}"):
566 hi_str += line[start + i]
568 print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
569 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
573 if line.find("${PN/") >= 0:
574 start = line.find("${PN/")
577 while(line[start + (i - 1)] != "}"):
578 hi_str += line[start + i]
580 print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
581 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
585 if line.find("${PV/") >= 0:
586 start = line.find("${PV/")
589 while(line[start + (i - 1)] != "}"):
590 hi_str += line[start + i]
592 print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
593 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
597 if line.find("${PVR/") >= 0:
598 start = line.find("${PVR/")
601 while(line[start + (i - 1)] != "}"):
602 hi_str += line[start + i]
604 print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
605 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
609 if line.find("${PR/") >= 0:
610 start = line.find("${PR/")
613 while(line[start + (i - 1)] != "}"):
614 hi_str += line[start + i]
616 print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
617 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
621 if line.find("${PF/") >= 0:
622 start = line.find("${PF/")
625 while(line[start + (i - 1)] != "}"):
626 hi_str += line[start + i]
628 print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str)))
629 (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str)
634 new_contents.append(tmp_line)
637 for line in new_contents:
640 for line in contents:
645 def __update_dependents(self, dep_list):
647 if len(dep_list) <= 0:
650 print "%s Updating dependents:" % green(" *")
651 os.chdir(self._portdir)
654 print " >>> %s" % dep
656 (category, pkg) = dep.split("/")
657 pkg_split = portage.pkgsplit(pkg)
658 os.chdir(self._portdir)
659 do_cmd("%s %s" % (self._cvscmd["update"], os.path.join(category, pkg_split[0])))
662 readfd = open(os.path.join(self._portdir, category, pkg_split[0], "%s.ebuild" % pkg), "r")
663 contents = readfd.readlines()
669 for line in contents:
670 if self._old_catpkg in line:
671 new_contents.append(line.replace(self._old_catpkg, self._new_catpkg))
673 new_contents.append(line)
676 writefd = open(os.path.join(self._portdir, category, pkg_split[0], "%s.ebuild" % pkg), "w")
677 writefd.write("".join(new_contents))
683 os.chdir(os.path.join(self._portdir, category, pkg_split[0]))
684 do_cmd("echangelog 'Dependency update: %s -> %s.'" % (self._old_catpkg, self._new_catpkg))
685 do_cmd("%s 'Dependency update: %s -> %s.'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg))
686 self.__regen_manifest(path=os.path.join(self._portdir, category, pkg_split[0]), dep=True)
688 def __get_reverse_deps(self):
691 conf_portdir = "/usr/portage"
693 def scan_for_dep(arg, dir, files):
695 (null, category) = os.path.split(dir)
698 if self._old_catpkg not in os.path.join(category, file):
699 if not os.path.isdir(os.path.join(dir, file)):
701 fd = open(os.path.join(dir, file), "r")
702 contents = fd.readlines()
707 if self._old_catpkg in contents[0] or self._old_catpkg in contents[1] or self._old_catpkg in contents[12]:
708 dep_list.append(os.path.join(category, file))
710 print "%s Resolving reverse dependencies..." % green(" *")
713 fd = open("/etc/make.conf", "r")
714 contents = fd.readlines()
720 for line in contents:
721 if line.startswith("PORTDIR="):
722 (null, conf_portdir) = line.strip("\"\n").split("=")
725 os.path.walk(os.path.join(conf_portdir, "metadata/cache"), scan_for_dep, None)
729 def __remove_old_package(self):
731 def remove_files(arg, dir, files):
733 if os.path.basename(dir) not in self._ignore:
735 if not os.path.isdir(os.path.join(dir, file)):
736 print " <<< %s" % (os.path.join(dir.strip("./"), file))
737 os.unlink(os.path.join(dir, file))
738 do_cmd("%s %s" % (self._cvscmd["remove"], os.path.join(dir, file)))
740 print "%s Removing %s from CVS:" % (green(" *"), turquoise(self._old_catpkg))
741 os.chdir(os.path.join(self._portdir, self._old_catpkg))
742 os.path.walk('.', remove_files , None)
745 print "%s Commiting changes..." % green(" *")
746 if self._options.remove:
749 print "%s Please provide an explanation for this removal:" % yellow(" *"),
751 explanation = raw_input("")
752 explanation = explanation.replace("'", "\\'").replace('"', '\\"')
753 except KeyboardInterrupt:
755 error("Interrupted by user.")
757 if explanation != "":
759 do_cmd("""%s "Removed from %s: %s" """ % (self._cvscmd["commit"], self._old_category, explanation))
761 do_cmd("%s 'Moved to %s.'" % (self._cvscmd["commit"], self._new_catpkg))
762 do_cmd("rm -rf %s" % os.path.join(self._portdir, self._old_catpkg))
764 print "%s Checking for remnant files..." % (green(" *"))
765 do_cmd(self._cvscmd["update"])
767 if not os.path.exists(os.path.join(self._portdir, self._old_catpkg)):
768 if not self._action == "REMOVE":
769 print "%s %s successfully removed from CVS." % (green(" *"), turquoise(self._old_catpkg))
771 error("Remnants of %s still remain in CVS." % (turquoise(self._old_catpkg)))
773 def __add_new_package(self):
775 def add_files(arg, dir, files):
777 (null, null, null, dirs) = dir.split("/", 3)
779 if os.path.basename(dir) not in self._ignore:
780 os.chdir(os.path.join(self._portdir, self._new_category))
781 if os.path.basename(dir) != self._new_package:
782 print " >>> %s/" % dirs
784 do_cmd("%s %s" % (self._cvscmd["add"], dirs))
786 if not os.path.isdir(os.path.join(dir, file)):
787 print " >>> %s" % os.path.join(dirs, file)
788 do_cmd("cp %s %s" % (os.path.join(dir, file), dirs))
789 do_cmd("%s %s" % (self._cvscmd["add"], os.path.join(dirs, file)))
791 print "%s Adding %s to CVS:" % (green(" *"), turquoise(self._new_catpkg))
792 os.chdir(os.path.join(self._portdir, self._new_category))
793 print " >>> %s/" % self._new_package
794 os.mkdir(self._new_package)
795 do_cmd("%s %s" % (self._cvscmd["add"], self._new_package))
796 os.chdir(self._new_package)
797 os.path.walk("/tmp/%s/%s" % (__productname__, self._new_package), add_files , None)
798 os.chdir(os.path.join(self._portdir, self._new_catpkg))
800 print "%s Adding ChangeLog entry..." % green(" *")
801 do_cmd("echangelog 'Moved from %s to %s.'" % (self._old_catpkg, self._new_catpkg))
803 print "%s Commiting changes..." % green(" *")
804 do_cmd("%s 'Moved from %s to %s.'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg))
806 print "%s %s successfully added to CVS." % (green(" *"), turquoise(self._new_catpkg))
810 if not self._action == "REMOVE":
813 update_regex = "^[\d]Q-[\d]{4}$"
815 p_file_regex = re.compile(update_regex)
817 print "%s Logging move:" % (green(" *"))
818 os.chdir(os.path.join(self._portdir, "profiles/updates"))
819 do_cmd(self._cvscmd["update"])
821 for file in os.listdir("."):
822 o_file_regex = p_file_regex.match(file)
823 if file not in self._ignore and o_file_regex:
824 (q, y) = file.split("-")
825 update_files.append("%s-%s" % (y, q))
828 (y, q) = update_files[-1].split("-")
829 upfile = "%s-%s" % (q, y)
830 print " >>> %s" % upfile
833 fd = open(upfile, "a")
834 fd.write("move %s %s\n" % (self._old_catpkg, self._new_catpkg))
840 do_cmd("%s 'Moved %s to %s'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg))
841 os.chdir(self._portdir)
845 if not self._action == "REMOVE":
846 print "%s Removing back-up..." % (green(" *"))
847 do_cmd("rm -rf /tmp/%s/%s" % (__productname__, self._old_package))
848 if len(os.listdir("/tmp/%s" % __productname__)) == 0:
849 do_cmd("rmdir /tmp/%s" % __productname__)
851 os.chdir(self._portdir)
853 if __name__ == "__main__":
855 signal.signal(signal.SIGINT, signal_handler)
857 cvscmd = {"remove": "cvs -Qf rm",
858 "commit": "cvs -Qf commit -m",
859 "update": "cvs -Qf up -dPC",
860 "add": "cvs -Qf add"}
862 parser = OptionParser(usage="%prog [ option ] [ origin ] [ destination ]", version="%s-%s" % (__productname__, __version__))
863 parser.add_option("--usage", action="store_true", dest="usage", default=False, help="Pint usage information")
864 parser.add_option("-q", "--queue-check", action="store_true", dest="commit_queue", default=False, help="Check the cvs tree for files awaiting commit")
865 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")
866 parser.add_option("-c", "--no-countdown", action="store_true", dest="countdown", default=False, help="Skip countdown before performing")
867 parser.add_option("-R", "--remove", action="store_true", dest="remove", default=False, help="Remove package")
868 parser.add_option("-F", "--force", action="store_true", dest="force", default=False, help="Force removal of package, ignoring any reverse deps")
869 (options, args) = parser.parse_args()
875 if randint(1, 100) == 50:
876 print "%s I put on my robe and wizard hat..." % green(" *")
878 portdir = check_cwd(portage.settings["PORTDIR"].rstrip("/"))
880 (oldcatpkg, newcatpkg) = check_args(args, portdir, options, cvscmd)
882 if options.commit_queue:
885 ThisPackage = CVSAbstraction(portdir, oldcatpkg, newcatpkg, cvscmd, options)
887 ThisPackage.perform_action()
888 ThisPackage.log_move()
889 ThisPackage.clean_up()
892 print "%s %s successfully removed from CVS." % (green(" *"), turquoise(oldcatpkg))
894 print "%s %s successfully moved to %s." % (green(" *"), turquoise(oldcatpkg), yellow(newcatpkg))