Ejemplo n.º 1
0
class Analyse(ModuleBase):
	"""Installed db analysis tool to query the installed databse
	and produce/output stats for USE flags or keywords/mask.
	The 'rebuild' action output is in the form suitable for file type output
	to create a new package.use, package.keywords, package.unmask
	type files in the event of needing to rebuild the
	/etc/portage/* user configs
	"""
	def __init__(self):
		ModuleBase.__init__(self)
		self.command_name = "enalyze"
		self.module_name = "analyze"
		self.options = {
			"flags": False,
			"keywords": False,
			"packages": False,
			"unset": False,
			"verbose": False,
			"quiet": False,
			'prefix': False,
			'portage': True,
			"width": 80,
			"prepend": "",
		}
		self.module_opts = {
			"-f": ("flags", "boolean", True),
			"--flags": ("flags", "boolean", True),
			"-k": ("keywords", "boolean", True),
			"--keywords": ("keywords", "boolean", True),
			"-u": ("unset", "boolean", True),
			"--unset": ("unset", "boolean", True),
			"-v": ("verbose", "boolean", True),
			"--verbose": ("verbose", "boolean", True),
			"-p": ("prefix", "boolean", True),
			"--prefix": ("prefix", "boolean", True),
			"-P": ("prepend", "char", None),
			"--prepend": ("prepend", "char", None),
			"-G": ("portage", "boolean", False),
			"--portage": ("portage", "boolean", False),
			"-W": ("width", "int", 80),
			"--width": ("width", "int", 80),
		}
		self.formatted_options = [
			("  -h, --help",  "Outputs this useage message"),
			("  -u, --unset",
			"Additionally include any unset USE flags and the packages"),
			("", "that could use them"),
			("  -v, --verbose",
			"Used in the analyze action to output more detailed information"),
			("  -p, --prefix",
			"Used for testing purposes only, runs report using " +
			"a prefix keyword and 'prefix' USE flag"),
			("  -P, --prepend",
			"Prepend the string to any list output.  " +
			"ie: prepend '* ' to the ""front of each package being listed."
			"This is useful for generating preformatted wiki text."),
			#(" -G, --portage",
			#"Use portage directly instead of gentoolkit's Package " +
			#"object for some operations. Usually a little faster."),
			("  -W, --width",
			"Format the output to wrap at 'WIDTH' ie: long line output"),
		]
		self.formatted_args = [
			("  use",
			"Causes the action to analyze the installed packages USE flags"),
			("  pkguse",
			"Causes the action to analyze the installed packages PKGUSE flags"),
			("  ",
			"These are flags that have been set in /etc/portage/package.use"),
			("  keywords",
			"Causes the action to analyze the installed packages keywords"),
			("  packages",
			"Causes the action to analyze the installed packages and the"),
			("  ",
			"USE flags they were installed with"),
			("  unmask",
			"Causes the action to analyze the installed packages"),
			("  ",
			"for those that need to be unmasked")
		]
		self.short_opts = "huvpGP:W:"
		self.long_opts = ("help", "unset", "verbose", "prefix", "prepend=",
						"width=") #, "portage")
		self.need_queries = True
		self.arg_spec = "Target"
		self.arg_options = ['use', 'pkguse','keywords', 'packages', 'unmask']
		self.arg_option = False
		self.warning = (
			"   CAUTION",
			"This is beta software and some features/options are incomplete,",
			"some features may change in future releases includig its name.",
			"Feedback will be appreciated, http://bugs.gentoo.org")


	def run(self, input_args, quiet=False):
		"""runs the module

		@param input_args: input arguments to be parsed
		"""
		query = self.main_setup(input_args)
		query = self.validate_query(query)
		self.set_quiet(quiet)
		if query in ["use", "pkguse"]:
			self.analyse_flags(query)
		elif query in ["keywords"]:
			self.analyse_keywords()
		elif query in ["packages"]:
			self.analyse_packages()
		elif query in ["unmask"]:
			self.analyse_unmask()

	def analyse_flags(self, target):
		"""This will scan the installed packages db and analyze the
		USE flags used for installation and produce a report on how
		they were used.

		@type target: string
		@param target: the target to be analyzed, one of ["use", "pkguse"]
		"""
		system_use = portage.settings["USE"].split()

		self.printer = AnalysisPrinter(
				"use",
				self.options["verbose"],
				system_use,
				width=self.options["width"],
				prepend=self.options["prepend"])
		if self.options["verbose"]:
			cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
			#cpvs = get_installed_cpvs()
			#print "Total number of installed ebuilds =", len(cpvs)
			flag_users = gather_flags_info(cpvs, system_use,
				self.options["unset"], target=target.upper(),
				use_portage=self.options['portage'])
		else:
			cpvs = get_installed_cpvs()
			flag_users = gather_flags_info(cpvs, system_flags=system_use,
				include_unset=self.options["unset"], target=target.upper(),
				use_portage=self.options['portage'])
		#print flag_users
		flag_keys = sorted(flag_users)
		if self.options["verbose"]:
			print(" Flag                                 System  #pkgs   cat/pkg-ver")
			#blankline = nl
		elif not self.options['quiet']:
			print(" Flag                                 System  #pkgs")
			#blankline = lambda: None
		for flag in flag_keys:
			flag_pos = flag_users[flag]["+"]
			if len(flag_pos):
				self.printer(flag, "+", flag_pos)
				#blankline()
			flag_neg = flag_users[flag]["-"]
			if len(flag_neg):
				self.printer(flag, "-", flag_neg)
				#blankline()
			if "unset" in flag_users[flag] and flag_users[flag]["unset"]:
				flag_unset = flag_users[flag]["unset"]
				self.printer(flag, "unset", flag_unset)
			#blankline()
		if not self.options['quiet']:
			print("===================================================")
			print("Total number of flags in report =",
				pp.output.red(str(len(flag_keys))))
			if self.options["verbose"]:
				print("Total number of installed ebuilds =",
					pp.output.red(str(len([x for x in cpvs]))))
			print()


	def analyse_keywords(self, keywords=None):
		"""This will scan the installed packages db and analyze the
		keywords used for installation and produce a report on them.
		"""
		print()
		system_keywords = portage.settings["ACCEPT_KEYWORDS"]
		arch = portage.settings["ARCH"]
		if self.options["prefix"]:
			# build a new keyword for testing
			system_keywords = "~" + arch + "-linux"
		if self.options["verbose"] or self.options["prefix"]:
			print("Current system ARCH =", arch)
			print("Current system ACCEPT_KEYWORDS =", system_keywords)
		system_keywords = system_keywords.split()
		self.printer = AnalysisPrinter(
				"keywords",
				self.options["verbose"],
				system_keywords,
				width=self.options["width"],
				prepend=self.options["prepend"])
		self.analyser = KeywordAnalyser( arch, system_keywords, portage.db[portage.root]["vartree"].dbapi)
		#self.analyser.set_order(portage.settings["USE"].split())
		# only for testing
		test_use = portage.settings["USE"].split()
		if self.options['prefix'] and 'prefix' not in test_use:
			print("ANALYSE_KEYWORDS() 'prefix' flag not found in system",
				"USE flags!!!  appending for testing")
			print()
			test_use.append('prefix')
		self.analyser.set_order(test_use)
		# /end testing

		if self.options["verbose"]:
			cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
			#print "Total number of installed ebuilds =", len(cpvs)
			keyword_users = gather_keywords_info(
				cpvs=cpvs,
				system_keywords=system_keywords,
				use_portage=self.options['portage'],
				keywords=keywords, analyser = self.analyser
				)
			blankline = nl
		else:
			keyword_users = gather_keywords_info(
				system_keywords=system_keywords,
				use_portage=self.options['portage'],
				keywords=keywords,
				analyser = self.analyser
				)
			blankline = lambda: None
		#print keyword_users
		keyword_keys = sorted(keyword_users)
		if self.options["verbose"]:
			print(" Keyword               System  #pkgs   cat/pkg-ver")
		elif not self.options['quiet']:
			print(" Keyword               System  #pkgs")
		for keyword in keyword_keys:
			kwd_stable = keyword_users[keyword]["stable"]
			if len(kwd_stable):
				self.printer(keyword, " ", kwd_stable)
				blankline()
			kwd_testing = keyword_users[keyword]["testing"]
			if len(kwd_testing):
				self.printer(keyword, "~", kwd_testing)
				blankline()
			kwd_missing = keyword_users[keyword]["missing"]
			if len(kwd_missing):
				self.printer(keyword, "-", kwd_missing)
				blankline
		if not self.options['quiet']:
			if self.analyser.mismatched:
				print("_________________________________________________")
				print(("The following packages were found to have a \n" +
					"different recorded ARCH than the current system ARCH"))
				for cpv in self.analyser.mismatched:
					print("\t", pp.cpv(cpv))
			print("===================================================")
			print("Total number of keywords in report =",
				pp.output.red(str(len(keyword_keys))))
			if self.options["verbose"]:
				print("Total number of installed ebuilds =",
					pp.output.red(str(len(cpvs))))
			print()


	def analyse_packages(self):
		"""This will scan the installed packages db and analyze the
		USE flags used for installation and produce a report.

		@type target: string
		@param target: the target to be analyzed, one of ["use", "pkguse"]
		"""
		system_use = portage.settings["USE"].split()
		if self.options["verbose"]:
			cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
			key_width = 45
		else:
			cpvs = get_installed_cpvs()
			key_width = 1

		self.printer = AnalysisPrinter(
				"packages",
				self.options["verbose"],
				key_width=key_width,
				width=self.options["width"],
				prepend=self.options["prepend"])

		cpvs = sorted(cpvs)
		flags = FlagAnalyzer(
					system=system_use,
					filter_defaults=False,
					target="USE"
					)

		if self.options["verbose"]:
			print("   cat/pkg-ver                             USE Flags")
				#   "app-emulation/emul-linux-x86-sdl-20100915 ...."
			#blankline = nl
		elif not self.options['quiet']:
			print("   cat/pkg-ver                             USE Flags")
			#blankline = lambda: None
		for cpv in cpvs:
			(flag_plus, flag_neg, unset) = flags.analyse_cpv(cpv)
			if self.options["unset"]:
				self.printer(cpv, "", (sorted(flag_plus), sorted(flag_neg),
					sorted(unset)))
			else:
				self.printer(cpv, "", (sorted(flag_plus), sorted(flag_neg), []))
		if not self.options['quiet']:
			print("===================================================")
			print("Total number of installed ebuilds =",
				pp.output.red(str(len([x for x in cpvs]))))
			print()


	def analyse_unmask(self):
		"""This will scan the installed packages db and analyze the
		unmasking used for installation and produce a report on them.
		"""
		self.not_implemented("unmask")
Ejemplo n.º 2
0
class Rebuild(ModuleBase):
	"""Installed db analysis tool to query the installed databse
	and produce/output stats for USE flags or keywords/mask.
	The 'rebuild' action output is in the form suitable for file type output
	to create a new package.use, package.keywords, package.unmask
	type files in the event of needing to rebuild the
	/etc/portage/* user configs
	"""
	def __init__(self):
		ModuleBase.__init__(self)
		self.command_name = "enalyze"
		self.module_name = "rebuild"
		self.options = {
			"use": False,
			"keywords": False,
			"unmask": False,
			"verbose": False,
			"quiet": False,
			"exact": False,
			"pretend": False,
			"prefix": False,
			"portage": True,
			"slot": False
			#"unset": False
		}
		self.module_opts = {
			"-p": ("pretend", "boolean", True),
			"--pretend": ("pretend", "boolean", True),
			"-e": ("exact", "boolean", True),
			"--exact": ("exact", "boolean", True),
			"-s": ("slot", "boolean", True),
			"--slot": ("slot", "boolean", True),
			"-v": ("verbose", "boolean", True),
			"--verbose": ("verbose", "boolean", True),
		}
		self.formatted_options = [
			("    -h, --help",  "Outputs this useage message"),
			("    -p, --pretend", "Does not actually create the files."),
			("    ", "It directs the outputs to the screen"),
			("    -e, --exact", "will atomize the package with a"),
			("  ", "leading '=' and include the version"),
			("    -s, --slot", "will atomize the package with a"),
			("  ", "leading '=' and include the slot")
		]
		self.formatted_args = [
			("    use",
			"causes the action to analyze the installed packages USE flags"),
			("    keywords",
			"causes the action to analyze the installed packages keywords"),
			("    unmask",
			"causes the action to analyze the installed packages " + \
			"current mask status")
		]
		self.short_opts = "hepsv"
		self.long_opts = ("help", "exact", "pretend", "slot", "verbose")
		self.need_queries = True
		self.arg_spec = "TargetSpec"
		self.arg_options = ['use', 'keywords', 'unmask']
		self.arg_option = False
		self.warning = (
			"     CAUTION",
			"This is beta software and some features/options are incomplete,",
			"some features may change in future releases includig its name.",
			"The file generated is saved in your home directory",
			"Feedback will be appreciated, http://bugs.gentoo.org")



	def run(self, input_args, quiet=False):
		"""runs the module

		@param input_args: input arguments to be parsed
		"""
		self.options['quiet'] = quiet
		query = self.main_setup(input_args)
		query = self.validate_query(query)
		if query in ["use"]:
			self.rebuild_use()
		elif query in ["keywords"]:
			self.rebuild_keywords()
		elif query in ["unmask"]:
			self.rebuild_unmask()


	def rebuild_use(self):
		if not self.options["quiet"]:
			print()
			print("  -- Scanning installed packages for USE flag settings that")
			print("     do not match the default settings")
		system_use = portage.settings["USE"].split()
		output = RebuildPrinter(
			"use", self.options["pretend"], self.options["exact"],
				self.options['slot'])
		pkgs, cp_counts = cpv_all_diff_use(system_flags=system_use)
		pkg_count = len(pkgs)
		if self.options["verbose"]:
			print()
			print((pp.emph("  -- Found ") +  pp.number(str(pkg_count)) +
				pp.emph(" packages that need entries")))
			#print pp.emph("     package.use to maintain their current setting")
		pkg_keys = []
		if pkgs:
			pkg_keys = sorted(pkgs)
			#print len(pkgs)
			if self.options["pretend"] and not self.options["quiet"]:
				print()
				print(pp.globaloption(
					"  -- These are the installed packages & use flags " +
					"that were detected"))
				print(pp.globaloption("     to need use flag settings other " +
					"than the defaults."))
				print()
			elif not self.options["quiet"]:
				print("  -- preparing pkgs for file entries")
			for pkg in pkg_keys:
				output(pkg, pkgs[pkg], cp_counts[pkg])
			if self.options['verbose']:
				message = (pp.emph("     ") +
					pp.number(str(pkg_count)) +
					pp.emph(" different packages"))
				print()
				print(pp.globaloption("  -- Totals"))
				print(message)
				#print
				#unique = list(unique_flags)
				#unique.sort()
				#print unique
			if not self.options["pretend"]:
				filepath = os.path.expanduser('~/package.use.test')
				self.save_file(filepath, output.lines)

	def rebuild_keywords(self):
		#print("Module action not yet available")
		#print()
		"""This will scan the installed packages db and analyze the
		keywords used for installation and produce a report on them.
		"""
		system_keywords = portage.settings["ACCEPT_KEYWORDS"].split()
		output = RebuildPrinter(
			"keywords", self.options["pretend"], self.options["exact"],
			self.options['slot'])
		arch = portage.settings["ARCH"]
		if self.options["prefix"]:
			# build a new keyword for testing
			system_keywords = "~" + arch + "-linux"
		if self.options["verbose"] or self.options["prefix"]:
			print("Current system ARCH =", arch)
			print("Current system ACCEPT_KEYWORDS =", system_keywords)
		self.analyser = KeywordAnalyser( arch, system_keywords, portage.db[portage.root]["vartree"].dbapi)
		#self.analyser.set_order(portage.settings["USE"].split())
		# only for testing
		test_use = portage.settings["USE"].split()
		if self.options['prefix'] and 'prefix' not in test_use:
			print("REBUILD_KEYWORDS() 'prefix' flag not found in system",
				"USE flags!!!  appending for testing")
			print()
			test_use.append('prefix')
		self.analyser.set_order(test_use)
		# /end testing

		cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
		#print "Total number of installed ebuilds =", len(cpvs)
		pkgs, cp_counts = cpv_all_diff_keywords(
			cpvs=cpvs,
			system_keywords=system_keywords,
			use_portage=self.options['portage'],
			analyser = self.analyser
			)
		#print([pkgs[p][0].cpv for p in pkgs])
		pkg_keys = []
		if pkgs:
			pkg_keys = sorted(pkgs)
			#print(len(pkgs))
			if self.options["pretend"] and not self.options["quiet"]:
				print()
				print(pp.globaloption(
					"  -- These are the installed packages & keywords " +
					"that were detected"))
				print(pp.globaloption("     to need keyword settings other " +
					"than the defaults."))
				print()
			elif not self.options["quiet"]:
				print("  -- preparing pkgs for file entries")
			for pkg in pkg_keys:
				output(pkg, pkgs[pkg], cp_counts[pkg])
		if not self.options['quiet']:
			if self.analyser.mismatched:
				print("_________________________________________________")
				print(("The following packages were found to have a \n" +
					"different recorded ARCH than the current system ARCH"))
				for cpv in self.analyser.mismatched:
					print("\t", pp.cpv(cpv))
			print("===================================================")
			print("Total number of entries in report =",
				pp.output.red(str(len(pkg_keys))))
			if self.options["verbose"]:
				print("Total number of installed ebuilds =",
					pp.output.red(str(len(cpvs))))
			print()
			if not self.options["pretend"]:
				filepath = os.path.expanduser('~/package.keywords.test')
				self.save_file(filepath, output.lines)


	def rebuild_unmask(self):
		self.not_implemented("unmask")


	def save_file(self, filepath, data):
		"""Writes the data to the file determined by filepath

		@param filepath: string. eg. '/path/to/filename'
		@param data: list of lines to write to filepath
		"""
		if  not self.options["quiet"]:
			print('   - Saving file: %s' %filepath)
		with open(_unicode_encode(filepath, encoding=_encodings['fs']), mode="w",
				encoding=_encodings['content']) as output:
			output.write('\n'.join(data))
		print("   - Done")
Ejemplo n.º 3
0
class Rebuild(ModuleBase):
    """Installed db analysis tool to query the installed databse
    and produce/output stats for USE flags or keywords/mask.
    The 'rebuild' action output is in the form suitable for file type output
    to create a new package.use, package.keywords, package.unmask
    type files in the event of needing to rebuild the
    /etc/portage/* user configs
    """

    def __init__(self):
        ModuleBase.__init__(self)
        self.command_name = "enalyze"
        self.module_name = "rebuild"
        self.options = {
            "use": False,
            "keywords": False,
            "unmask": False,
            "verbose": False,
            "quiet": False,
            "exact": False,
            "pretend": False,
            "prefix": False,
            "portage": True,
            "slot": False
            # "unset": False
        }
        self.module_opts = {
            "-p": ("pretend", "boolean", True),
            "--pretend": ("pretend", "boolean", True),
            "-e": ("exact", "boolean", True),
            "--exact": ("exact", "boolean", True),
            "-s": ("slot", "boolean", True),
            "--slot": ("slot", "boolean", True),
            "-v": ("verbose", "boolean", True),
            "--verbose": ("verbose", "boolean", True),
        }
        self.formatted_options = [
            ("    -h, --help", "Outputs this useage message"),
            ("    -p, --pretend", "Does not actually create the files."),
            ("    ", "It directs the outputs to the screen"),
            ("    -e, --exact", "will atomize the package with a"),
            ("  ", "leading '=' and include the version"),
            ("    -s, --slot", "will atomize the package with a"),
            ("  ", "leading '=' and include the slot"),
        ]
        self.formatted_args = [
            (
                "    use",
                "causes the action to analyze the installed packages USE flags",
            ),
            (
                "    keywords",
                "causes the action to analyze the installed packages keywords",
            ),
            (
                "    unmask",
                "causes the action to analyze the installed packages "
                + "current mask status",
            ),
        ]
        self.short_opts = "hepsv"
        self.long_opts = ("help", "exact", "pretend", "slot", "verbose")
        self.need_queries = True
        self.arg_spec = "TargetSpec"
        self.arg_options = ["use", "keywords", "unmask"]
        self.arg_option = False
        self.warning = (
            "     CAUTION",
            "This is beta software and some features/options are incomplete,",
            "some features may change in future releases includig its name.",
            "The file generated is saved in your home directory",
            "Feedback will be appreciated, http://bugs.gentoo.org",
        )

    def run(self, input_args, quiet=False):
        """runs the module

        @param input_args: input arguments to be parsed
        """
        self.options["quiet"] = quiet
        query = self.main_setup(input_args)
        query = self.validate_query(query)
        if query in ["use"]:
            self.rebuild_use()
        elif query in ["keywords"]:
            self.rebuild_keywords()
        elif query in ["unmask"]:
            self.rebuild_unmask()

    def rebuild_use(self):
        if not self.options["quiet"]:
            print()
            print("  -- Scanning installed packages for USE flag settings that")
            print("     do not match the default settings")
        system_use = portage.settings["USE"].split()
        output = RebuildPrinter(
            "use", self.options["pretend"], self.options["exact"], self.options["slot"]
        )
        pkgs, cp_counts = cpv_all_diff_use(system_flags=system_use)
        pkg_count = len(pkgs)
        if self.options["verbose"]:
            print()
            print(
                (
                    pp.emph("  -- Found ")
                    + pp.number(str(pkg_count))
                    + pp.emph(" packages that need entries")
                )
            )
            # print pp.emph("     package.use to maintain their current setting")
        pkg_keys = []
        if pkgs:
            pkg_keys = sorted(pkgs)
            # print len(pkgs)
            if self.options["pretend"] and not self.options["quiet"]:
                print()
                print(
                    pp.globaloption(
                        "  -- These are the installed packages & use flags "
                        + "that were detected"
                    )
                )
                print(
                    pp.globaloption(
                        "     to need use flag settings other " + "than the defaults."
                    )
                )
                print()
            elif not self.options["quiet"]:
                print("  -- preparing pkgs for file entries")
            for pkg in pkg_keys:
                output(pkg, pkgs[pkg], cp_counts[pkg])
            if self.options["verbose"]:
                message = (
                    pp.emph("     ")
                    + pp.number(str(pkg_count))
                    + pp.emph(" different packages")
                )
                print()
                print(pp.globaloption("  -- Totals"))
                print(message)
                # print
                # unique = list(unique_flags)
                # unique.sort()
                # print unique
            if not self.options["pretend"]:
                filepath = os.path.expanduser("~/package.use.test")
                self.save_file(filepath, output.lines)

    def rebuild_keywords(self):
        # print("Module action not yet available")
        # print()
        """This will scan the installed packages db and analyze the
        keywords used for installation and produce a report on them.
        """
        system_keywords = portage.settings["ACCEPT_KEYWORDS"].split()
        output = RebuildPrinter(
            "keywords",
            self.options["pretend"],
            self.options["exact"],
            self.options["slot"],
        )
        arch = portage.settings["ARCH"]
        if self.options["prefix"]:
            # build a new keyword for testing
            system_keywords = "~" + arch + "-linux"
        if self.options["verbose"] or self.options["prefix"]:
            print("Current system ARCH =", arch)
            print("Current system ACCEPT_KEYWORDS =", system_keywords)
        self.analyser = KeywordAnalyser(
            arch, system_keywords, portage.db[portage.root]["vartree"].dbapi
        )
        # self.analyser.set_order(portage.settings["USE"].split())
        # only for testing
        test_use = portage.settings["USE"].split()
        if self.options["prefix"] and "prefix" not in test_use:
            print(
                "REBUILD_KEYWORDS() 'prefix' flag not found in system",
                "USE flags!!!  appending for testing",
            )
            print()
            test_use.append("prefix")
        self.analyser.set_order(test_use)
        # /end testing

        cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
        # print "Total number of installed ebuilds =", len(cpvs)
        pkgs, cp_counts = cpv_all_diff_keywords(
            cpvs=cpvs,
            system_keywords=system_keywords,
            use_portage=self.options["portage"],
            analyser=self.analyser,
        )
        # print([pkgs[p][0].cpv for p in pkgs])
        pkg_keys = []
        if pkgs:
            pkg_keys = sorted(pkgs)
            # print(len(pkgs))
            if self.options["pretend"] and not self.options["quiet"]:
                print()
                print(
                    pp.globaloption(
                        "  -- These are the installed packages & keywords "
                        + "that were detected"
                    )
                )
                print(
                    pp.globaloption(
                        "     to need keyword settings other " + "than the defaults."
                    )
                )
                print()
            elif not self.options["quiet"]:
                print("  -- preparing pkgs for file entries")
            for pkg in pkg_keys:
                output(pkg, pkgs[pkg], cp_counts[pkg])
        if not self.options["quiet"]:
            if self.analyser.mismatched:
                print("_________________________________________________")
                print(
                    (
                        "The following packages were found to have a \n"
                        + "different recorded ARCH than the current system ARCH"
                    )
                )
                for cpv in self.analyser.mismatched:
                    print("\t", pp.cpv(cpv))
            print("===================================================")
            print(
                "Total number of entries in report =", pp.output.red(str(len(pkg_keys)))
            )
            if self.options["verbose"]:
                print(
                    "Total number of installed ebuilds =", pp.output.red(str(len(cpvs)))
                )
            print()
            if not self.options["pretend"]:
                filepath = os.path.expanduser("~/package.keywords.test")
                self.save_file(filepath, output.lines)

    def rebuild_unmask(self):
        self.not_implemented("unmask")

    def save_file(self, filepath, data):
        """Writes the data to the file determined by filepath

        @param filepath: string. eg. '/path/to/filename'
        @param data: list of lines to write to filepath
        """
        if not self.options["quiet"]:
            print("   - Saving file: %s" % filepath)
        with open(
            _unicode_encode(filepath, encoding=_encodings["fs"]),
            mode="w",
            encoding=_encodings["content"],
        ) as output:
            output.write("\n".join(data))
        print("   - Done")
Ejemplo n.º 4
0
class Analyse(ModuleBase):
    """Installed db analysis tool to query the installed databse
	and produce/output stats for USE flags or keywords/mask.
	The 'rebuild' action output is in the form suitable for file type output
	to create a new package.use, package.keywords, package.unmask
	type files in the event of needing to rebuild the
	/etc/portage/* user configs
	"""

    def __init__(self):
        ModuleBase.__init__(self)
        self.command_name = "enalyze"
        self.module_name = "analyze"
        self.options = {
            "flags": False,
            "keywords": False,
            "packages": False,
            "unset": False,
            "verbose": False,
            "quiet": False,
            "prefix": False,
            "portage": True,
        }
        self.module_opts = {
            "-f": ("flags", "boolean", True),
            "--flags": ("flags", "boolean", True),
            "-k": ("keywords", "boolean", True),
            "--keywords": ("keywords", "boolean", True),
            "-u": ("unset", "boolean", True),
            "--unset": ("unset", "boolean", True),
            "-v": ("verbose", "boolean", True),
            "--verbose": ("verbose", "boolean", True),
            "-p": ("prefix", "boolean", True),
            "--prefix": ("prefix", "boolean", True),
            "-G": ("portage", "boolean", False),
            "--portage": ("portage", "boolean", False),
        }
        self.formatted_options = [
            ("  -h, --help", "Outputs this useage message"),
            ("  -a, --analyze", "Action, sets the module to gather data and output the"),
            ("", "formatted stats/information to the screen"),
            ("  -u, --unset", "Additionally include any unset USE flags and the packages"),
            ("", "that could use them"),
            ("  -v, --verbose", "Used in the analyze action to output more detailed information"),
            (
                "  -p, --prefix",
                "Used for testing purposes only, runs report using " + "a prefix keyword and 'prefix' USE flag",
            ),
            # (" -G, --portage",
            # "Use portage directly instead of gentoolkit's Package " +
            # "object for some operations. Usually a little faster."),
        ]
        self.formatted_args = [
            ("  use", "Causes the action to analyze the installed packages USE flags"),
            ("  pkguse", "Causes the action to analyze the installed packages PKGUSE flags"),
            ("  ", "These are flags that have been set in /etc/portage/package.use"),
            ("  keywords", "Causes the action to analyze the installed packages keywords"),
            ("  packages", "Causes the action to analyze the installed packages and the"),
            ("  ", "USE flags they were installed with"),
            ("  unmask", "Causes the action to analyze the installed packages"),
            ("  ", "for those that need to be unmasked"),
        ]
        self.short_opts = "huvpG"
        self.long_opts = ("help", "unset", "verbose", "prefix")  # , "portage")
        self.need_queries = True
        self.arg_spec = "Target"
        self.arg_options = ["use", "pkguse", "keywords", "packages", "unmask"]
        self.arg_option = False
        self.warning = (
            "   CAUTION",
            "This is beta software and some features/options are incomplete,",
            "some features may change in future releases includig its name.",
            "Feedback will be appreciated, http://bugs.gentoo.org",
        )

    def run(self, input_args, quiet=False):
        """runs the module

		@param input_args: input arguments to be parsed
		"""
        query = self.main_setup(input_args)
        query = self.validate_query(query)
        self.set_quiet(quiet)
        if query in ["use", "pkguse"]:
            self.analyse_flags(query)
        elif query in ["keywords"]:
            self.analyse_keywords()
        elif query in ["packages"]:
            self.analyse_packages()
        elif query in ["unmask"]:
            self.analyse_unmask()

    def analyse_flags(self, target):
        """This will scan the installed packages db and analyze the
		USE flags used for installation and produce a report on how
		they were used.

		@type target: string
		@param target: the target to be analyzed, one of ["use", "pkguse"]
		"""
        system_use = portage.settings["USE"].split()
        self.printer = AnalysisPrinter("use", self.options["verbose"], system_use)
        if self.options["verbose"]:
            cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
            # cpvs = get_installed_cpvs()
            # print "Total number of installed ebuilds =", len(cpvs)
            flag_users = gather_flags_info(
                cpvs, system_use, self.options["unset"], target=target.upper(), use_portage=self.options["portage"]
            )
        else:
            cpvs = get_installed_cpvs()
            flag_users = gather_flags_info(
                cpvs,
                system_flags=system_use,
                include_unset=self.options["unset"],
                target=target.upper(),
                use_portage=self.options["portage"],
            )
            # print flag_users
        flag_keys = sorted(flag_users)
        if self.options["verbose"]:
            print(" Flag                                 System  #pkgs   cat/pkg-ver")
            blankline = nl
        elif not self.options["quiet"]:
            print(" Flag                                 System  #pkgs")
            blankline = lambda: None
        for flag in flag_keys:
            flag_pos = flag_users[flag]["+"]
            if len(flag_pos):
                self.printer(flag, "+", flag_pos)
                # blankline()
            flag_neg = flag_users[flag]["-"]
            if len(flag_neg):
                self.printer(flag, "-", flag_neg)
                # blankline()
            if "unset" in flag_users[flag] and flag_users[flag]["unset"]:
                flag_unset = flag_users[flag]["unset"]
                self.printer(flag, "unset", flag_unset)
                # blankline()
        if not self.options["quiet"]:
            print("===================================================")
            print("Total number of flags in report =", pp.output.red(str(len(flag_keys))))
            if self.options["verbose"]:
                print("Total number of installed ebuilds =", pp.output.red(str(len([x for x in cpvs]))))
            print()

    def analyse_keywords(self, keywords=None):
        """This will scan the installed packages db and analyze the
		keywords used for installation and produce a report on them.
		"""
        print()
        system_keywords = portage.settings["ACCEPT_KEYWORDS"]
        arch = portage.settings["ARCH"]
        if self.options["prefix"]:
            # build a new keyword for testing
            system_keywords = "~" + arch + "-linux"
        if self.options["verbose"] or self.options["prefix"]:
            print("Current system ARCH =", arch)
            print("Current system ACCEPT_KEYWORDS =", system_keywords)
        system_keywords = system_keywords.split()
        self.printer = AnalysisPrinter("keywords", self.options["verbose"], system_keywords)
        self.analyser = KeywordAnalyser(arch, system_keywords, portage.db[portage.root]["vartree"].dbapi)
        # self.analyser.set_order(portage.settings["USE"].split())
        # only for testing
        test_use = portage.settings["USE"].split()
        if self.options["prefix"] and "prefix" not in test_use:
            print("ANALYSE_KEYWORDS() 'prefix' flag not found in system", "USE flags!!!  appending for testing")
            print()
            test_use.append("prefix")
        self.analyser.set_order(test_use)
        # /end testing

        if self.options["verbose"]:
            cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
            # print "Total number of installed ebuilds =", len(cpvs)
            keyword_users = gather_keywords_info(
                cpvs=cpvs,
                system_keywords=system_keywords,
                use_portage=self.options["portage"],
                keywords=keywords,
                analyser=self.analyser,
            )
            blankline = nl
        else:
            keyword_users = gather_keywords_info(
                system_keywords=system_keywords,
                use_portage=self.options["portage"],
                keywords=keywords,
                analyser=self.analyser,
            )
            blankline = lambda: None
            # print keyword_users
        keyword_keys = sorted(keyword_users)
        if self.options["verbose"]:
            print(" Keyword               System  #pkgs   cat/pkg-ver")
        elif not self.options["quiet"]:
            print(" Keyword               System  #pkgs")
        for keyword in keyword_keys:
            kwd_stable = keyword_users[keyword]["stable"]
            if len(kwd_stable):
                self.printer(keyword, " ", kwd_stable)
                blankline()
            kwd_testing = keyword_users[keyword]["testing"]
            if len(kwd_testing):
                self.printer(keyword, "~", kwd_testing)
                blankline()
            kwd_missing = keyword_users[keyword]["missing"]
            if len(kwd_missing):
                self.printer(keyword, "-", kwd_missing)
                blankline
        if not self.options["quiet"]:
            if self.analyser.mismatched:
                print("_________________________________________________")
                print(
                    (
                        "The following packages were found to have a \n"
                        + "different recorded ARCH than the current system ARCH"
                    )
                )
                for cpv in self.analyser.mismatched:
                    print("\t", pp.cpv(cpv))
            print("===================================================")
            print("Total number of keywords in report =", pp.output.red(str(len(keyword_keys))))
            if self.options["verbose"]:
                print("Total number of installed ebuilds =", pp.output.red(str(len(cpvs))))
            print()

    def analyse_packages(self):
        """This will scan the installed packages db and analyze the
		USE flags used for installation and produce a report.

		@type target: string
		@param target: the target to be analyzed, one of ["use", "pkguse"]
		"""
        system_use = portage.settings["USE"].split()
        if self.options["verbose"]:
            cpvs = portage.db[portage.root]["vartree"].dbapi.cpv_all()
            key_width = 45
        else:
            cpvs = get_installed_cpvs()
            key_width = 1

        self.printer = AnalysisPrinter("packages", self.options["verbose"], key_width=key_width)

        cpvs = sorted(cpvs)
        flags = FlagAnalyzer(system=system_use, filter_defaults=False, target="USE")

        if self.options["verbose"]:
            print("   cat/pkg-ver                             USE Flags")
            #   "app-emulation/emul-linux-x86-sdl-20100915 ...."
            blankline = nl
        elif not self.options["quiet"]:
            print("   cat/pkg-ver                             USE Flags")
            blankline = lambda: None
        for cpv in cpvs:
            (flag_plus, flag_neg, unset) = flags.analyse_cpv(cpv)
            if self.options["unset"]:
                self.printer(cpv, "", (flag_plus, flag_neg, unset))
            else:
                self.printer(cpv, "", (flag_plus, flag_neg, []))
        if not self.options["quiet"]:
            print("===================================================")
            print("Total number of installed ebuilds =", pp.output.red(str(len([x for x in cpvs]))))
            print()

    def analyse_unmask(self):
        """This will scan the installed packages db and analyze the
		unmasking used for installation and produce a report on them.
		"""
        self.not_implemented("unmask")