コード例 #1
0
ファイル: rebuild.py プロジェクト: djgrasss/pybombs2
 def run(self):
     """ Go, go, go! """
     ### Sanity checks
     for pkg in self.args.packages:
         if not self.pm.installed(recipe.get_recipe(pkg)):
             self.log.error("Package {0} is not installed into current prefix. Aborting.".format(pkg))
             exit(1)
     ### Make install tree
     rb_tree = dep_manager.DepManager().make_dep_tree(
         self.args.packages,
         lambda x: bool(
             (x in self.args.packages) or \
             (self.args.deps and self.pm.installed(recipe.get_recipe(x)))
         )
     )
     self.log.debug("Install tree:")
     if self.log.getEffectiveLevel() <= 20 or self.args.print_tree:
         rb_tree.pretty_print()
     ### Recursively rebuild, starting at the leaf nodes
     while not rb_tree.empty():
         pkg = rb_tree.pop_leaf_node()
         rec = recipe.get_recipe(pkg)
         self.log.info("Rebuilding package: {0}".format(pkg))
         if not self.pm.rebuild(
             rec,
             make_clean=self.args.clean,
             nuke_builddir=not self.args.keep_build
         ):
             self.log.error("Error rebuilding package {0}. Aborting.".format(pkg))
             exit(1)
         self.log.info("Rebuild successful.")
コード例 #2
0
ファイル: dep_manager.py プロジェクト: djgrasss/pybombs2
 def _add_deps_recursive(self, install_tree, pkg, filter_callback):
     """
     Recursively add dependencies to the install tree.
     """
     # Load deps:
     deps = recipe.get_recipe(pkg).get_local_package_data()['depends'] or []
     # Filter for illegal stuff:
     for dep in deps:
         if not self.pm.exists(pkg):
             self.log.error("Package does not exist: {0} (declared as dependency for package {1})".format(dep, pkg))
             exit(1)
     # Filter all packages either already in the tree, or not wanted:
     deps_to_install = filter(
         lambda pkg: pkg is not None and filter_callback(pkg) and pkg not in install_tree.get_nodes(),
         deps
     )
     if len(deps_to_install) == 0:
         return
     # First, add all dependencies into the install tree:
     install_tree.insert_at(deps_to_install, pkg)
     # Then, extend the tree if the dependencies have dependencies themselves:
     for dep in deps_to_install:
         if isinstance(dep, list):
             # I honestly have no clue why this happens, yet sometimes
             # it does.
             continue
         self._add_deps_recursive(install_tree, dep, filter_callback)
コード例 #3
0
    def __init__(self, package_name):
        super(ModuleInfoDialog, self).__init__()
        self.moduleinfo_dialogui = Ui_ModuleInfoDialog()
        self.moduleinfo_dialogui.setupUi(self)
        self.moduleinfo_dialogui.plainTextEdit.setFrameStyle(QFrame.NoFrame)
        self.moduleinfo_dialogui.plainTextEdit.setContentsMargins(0, 0, 0, 0)
        self.moduleinfo_dialogui.plainTextEdit.readOnly = True
        self.moduleinfo_dialogui.plainTextEdit.clear()

        rec = recipe.get_recipe(package_name, target='package')

        pkg = 'Package Name: {}'.format(package_name)
        self.moduleinfo_dialogui.plainTextEdit.appendPlainText(pkg)
        self.moduleinfo_dialogui.plainTextEdit.appendPlainText('Dependencies:')
        for item in rec.depends:
            depends = '-{}'.format(item)
            self.moduleinfo_dialogui.plainTextEdit.appendPlainText(depends)
        self.moduleinfo_dialogui.plainTextEdit.appendPlainText('Source')
        source = '{}'.format(rec.get_dict()['source'])
        self.moduleinfo_dialogui.plainTextEdit.appendPlainText(source)
        self.moduleinfo_dialogui.plainTextEdit.appendPlainText('Category')
        self.moduleinfo_dialogui.plainTextEdit.appendPlainText(rec.category)
        if 'description' in rec.get_dict():
            self.moduleinfo_dialogui.plainTextEdit.appendPlainText(
                'Module Description')
            self.moduleinfo_dialogui.plainTextEdit.appendPlainText(
                rec.description)

        if 'forcebuild' in rec.get_dict():
            self.moduleinfo_dialogui.plainTextEdit.appendPlainText(
                'Forcebuild')
            self.moduleinfo_dialogui.plainTextEdit.appendPlainText('True')
コード例 #4
0
ファイル: package_manager.py プロジェクト: gnuradio/pybombs
 def exists(self, name, return_pkgr_name=False):
     """
     Check to see if this package is available on this platform.
     Returns True or a version string if yes, False if not.
     If return_pkgr_name is True, it'll return a list of packagers that
     can install this package.
     """
     if not return_pkgr_name and name in self.pmc.known_installable:
         self.log.trace("{0} has cached installable-status: {1}".format(
             name, self.pmc.known_installable.get(name)
         ))
         return True
     self.log.debug("Checking if package {0} is installable...".format(name))
     if self.check_package_flag(name, 'forceinstalled'):
         self.log.debug("Package {0} is forced to state 'installed'.".format(name))
         return ['force-installed'] if return_pkgr_name else True
     r = recipe.get_recipe(name)
     pkgrs = []
     for pkgr in self.get_packagers(name):
         pkg_version = pkgr.exists(r)
         if pkg_version is None or not pkg_version:
             continue
         else:
             self.pmc.known_installable[name] = True
             if return_pkgr_name:
                 pkgrs.append(pkgr.name)
             else:
                 return pkg_version
     if return_pkgr_name and len(pkgrs):
         self.pmc.known_installable[name] = True
         return pkgrs
     self.log.debug("Package {0} is not installable.".format(name))
     self.pmc.known_installable[name] = False
     return False
コード例 #5
0
 def get_dependees(self, pkgs):
     """
     From a list of pkgs, return a list that also includes packages
     which depend on them.
     """
     self.log.debug("Resolving dependency list for clean removal.")
     other_installed_pkgs = [
         x for x in self.inventory.get_packages() if not x in pkgs
     ]
     new_pkgs = []
     for other_installed_pkg in other_installed_pkgs:
         self.log.obnoxious(
             "Checking if {0} is a dependee...".format(other_installed_pkg))
         try:
             deps = recipe.get_recipe(other_installed_pkg).depends or []
         except PBException:
             continue
         for pkg in pkgs:
             if pkg in deps:
                 self.log.obnoxious("Yup, it is.")
                 new_pkgs.append(other_installed_pkg)
                 break
     if len(new_pkgs) > 0:
         pkgs = pkgs + new_pkgs
         return self.get_dependees(pkgs)
     return pkgs
コード例 #6
0
ファイル: package_manager.py プロジェクト: yueyz818/pybombs
 def exists(self, name, return_pkgr_name=False):
     """
     Check to see if this package is available on this platform.
     Returns True or a version string if yes, False if not.
     If return_pkgr_name is True, it'll return a list of packagers that
     can install this package.
     """
     if not return_pkgr_name and name in self.pmc.known_installable:
         self.log.trace("{0} has cached installable-status: {1}".format(
             name, self.pmc.known_installable.get(name)))
         return True
     self.log.debug(
         "Checking if package {0} is installable...".format(name))
     if self.check_package_flag(name, 'forceinstalled'):
         self.log.debug(
             "Package {0} is forced to state 'installed'.".format(name))
         return ['force-installed'] if return_pkgr_name else True
     r = recipe.get_recipe(name)
     pkgrs = []
     for pkgr in self.get_packagers(name):
         pkg_version = pkgr.exists(r)
         if pkg_version is None or not pkg_version:
             continue
         else:
             self.pmc.known_installable[name] = True
             if return_pkgr_name:
                 pkgrs.append(pkgr.name)
             else:
                 return pkg_version
     if return_pkgr_name and len(pkgrs):
         self.pmc.known_installable[name] = True
         return pkgrs
     self.log.debug("Package {0} is not installable.".format(name))
     self.pmc.known_installable[name] = False
     return False
コード例 #7
0
    def installed(self, name, return_pkgr_name=False):
        """
        Check to see if this recipe is installed (identified by its name).

        If not, return False. If yes, return value depends on return_pkgr_name
        and is either a list of packager name that installed it, or a version
        string (if the version string can't be determined, returns True instead).
        """
        if not return_pkgr_name and name in self.pmc.known_installed:
            self.log.obnoxious("{0} is cached and known to be installed.".format(name))
            return True
        self.log.debug("Checking if package {} is installed.".format(name))
        if self.check_package_flag(name, 'forceinstalled'):
            self.log.debug("Package {} is forced to state 'installed'.".format(name))
            # TODO maybe we can figure out a version string
            return ['force-installed'] if return_pkgr_name else True

        r = recipe.get_recipe(name)
        self.current_prefix = self.cfg.get_active_prefix()
        virtualenv = config_manager.extract_cfg_items(self.current_prefix.cfg_file,
                                                      'virtualenv')
        self.log.debug("Checking if the prefix has a virtualenv")
        if virtualenv and 'python' in r.depends:
            try:
                if 'pip' in r.satisfy:
                    #This pip list is specific to virtualenv
                    pip_output = subproc.check_output(["pip", "list"])
                    pip_list = [x.split(' ')[0] for x in str(pip_output).strip().
                                lower().split("\n")]
                    if not name in pip_list:
                        return False
            except AttributeError:
                self.log.debug("Package depends on python, but isn't pip installable")
                pkgrs = []
                for pkgr in self.get_packagers(name):
                    pkg_version = pkgr.installed(r)
                    if pkg_version is None or not pkg_version:
                        continue
                    else:
                        self.pmc.known_installed.add(name)
                        if return_pkgr_name:
                            pkgrs.append(pkgr.name)
                        else:
                            return pkg_version
        else:
            pkgrs = []
            for pkgr in self.get_packagers(name):
                pkg_version = pkgr.installed(r)
                if pkg_version is None or not pkg_version:
                    continue
                else:
                    self.pmc.known_installed.add(name)
                    if return_pkgr_name:
                        pkgrs.append(pkgr.name)
                    else:
                        return pkg_version

        if return_pkgr_name and len(pkgrs):
            return pkgrs
        return False
コード例 #8
0
ファイル: package_manager.py プロジェクト: yueyz818/pybombs
 def _std_package_operation(self,
                            name,
                            operation,
                            pkgrs,
                            verify=False,
                            **kwargs):
     """
     Standard package operation: Try an operation on all packagers.
     """
     rec = recipe.get_recipe(name)
     for pkgr in pkgrs:
         self.log.debug("Using packager {0}".format(pkgr.name))
         try:
             result = getattr(pkgr, operation)(rec, **kwargs)
             if result:
                 if verify and not pkgr.verify(rec):
                     self.log.warn(
                         "Package reported successful {0}, but verification failed."
                         .format(operation))
                     continue
                 return True
         except PBException as ex:
             self.log.error(
                 "Something went wrong while trying to {0} {1} using {2}: {3}"
                 .format(operation, name, pkgr.name,
                         str(ex).strip()))
     return False
コード例 #9
0
ファイル: dep_manager.py プロジェクト: mekhalleh/pybombs
 def _add_deps_recursive(self, install_tree, pkg, filter_callback):
     """
     Recursively add dependencies to the install tree.
     """
     # Load deps:
     deps = recipe.get_recipe(pkg).get_local_package_data()['depends'] or []
     # Filter for illegal stuff:
     for dep in deps:
         if not self.pm.exists(pkg) and dep is not None:
             self.log.error("Package does not exist: {0} (declared as dependency for package {1})".format(dep, pkg))
             exit(1)
     # Filter all packages either already in the tree, or not wanted:
     deps_to_install = filter(
         lambda pkg: filter_callback(pkg) and pkg not in install_tree.get_nodes(),
         deps
     )
     if len(deps_to_install) == 0:
         return
     # First, add all dependencies into the install tree:
     install_tree.insert_at(deps_to_install, pkg)
     # Then, extend the tree if the dependencies have dependencies themselves:
     for dep in deps_to_install:
         if isinstance(dep, list):
             # I honestly have no clue why this happens, yet sometimes
             # it does.
             continue
         self._add_deps_recursive(install_tree, dep, filter_callback)
コード例 #10
0
 def exists(self, name, return_pkgr_name=False):
     """
     Check to see if this package is available on this platform.
     Returns True or a version string if yes, False if not.
     """
     if not return_pkgr_name and name in self.pmc.known_installable:
         self.log.obnoxious("{0} is cached and known to be installable.".format(name))
         return True
     self.log.debug("Checking if package {} is installable.".format(name))
     if self.check_package_flag(name, 'forceinstalled'):
         self.log.debug("Package {} is forced to state 'installed'.".format(name))
         return ['force-installed'] if return_pkgr_name else True
     r = recipe.get_recipe(name)
     pkgrs = []
     for pkgr in self.get_packagers(name):
         pkg_version = pkgr.exists(r)
         if pkg_version is None or not pkg_version:
             continue
         else:
             self.pmc.known_installable.add(name)
             if return_pkgr_name:
                 pkgrs.append(pkgr.name)
             else:
                 return pkg_version
     if return_pkgr_name and len(pkgrs):
         return pkgrs
     return False
コード例 #11
0
ファイル: package_manager.py プロジェクト: n-west/pybombs2
    def installed(self, name, return_pkgr_name=False):
        """
        Check to see if this recipe is installed (identified by its name).

        If not, return False. If yes, return value depends on return_pkgr_name
        and is either a list of packager name that installed it, or a version
        string (if the version string can't be determined, returns True instead).
        """
        self.log.debug("Checking if package {} is installed.".format(name))
        if self.check_package_flag(name, 'forceinstalled'):
            self.log.debug("Package {} is forced to state 'installed'.".format(name))
            # TODO maybe we can figure out a version string
            return ['force-installed'] if return_pkgr_name else True
        r = recipe.get_recipe(name)
        pkgrs = []
        for pkgr in self.get_packagers(name):
            pkg_version = pkgr.installed(r)
            if pkg_version is None or not pkg_version:
                continue
            else:
                if return_pkgr_name:
                    pkgrs.append(pkgr.name)
                else:
                    return True
        if return_pkgr_name and len(pkgrs):
            return pkgrs
        return False
コード例 #12
0
ファイル: digraph.py プロジェクト: ferhat1234/proje
 def graphviz(self, packages, dotfile, pngfile):
     """
     Create the graphviz file
     """
     self.log.info("Creating digraph file {0}".format(dotfile))
     f = open(dotfile, "w")
     f.write("digraph g {\n")
     for pkg in packages:
         pkg_safe = pkg.replace("-", "_")
         f.write('{pkg} [label="{pkg}"]\n'.format(pkg=pkg_safe))
         rec = recipe.get_recipe(pkg, fail_easy=True)
         if rec is None:
             continue
         for dep in rec.depends:
             if dep in packages:
                 f.write(" {pkg} -> {dep}\n".format(pkg=pkg_safe,
                                                    dep=dep.replace(
                                                        "-", "_")))
     f.write("}\n")
     f.close()
     self.log.debug("{0} written".format(dotfile))
     if pngfile is None:
         return
     self.log.info("Creating png file {0}".format(pngfile))
     subproc.monitor_process(
         ['dot', dotfile, '-Tpng', '-o{0}'.format(pngfile)],
         env=os.environ,
     )
コード例 #13
0
ファイル: package_manager.py プロジェクト: vosgus/pybombs
    def installed(self, name, return_pkgr_name=False):
        """
        Check to see if this recipe is installed (identified by its name).

        If not, return False. If yes, return value depends on return_pkgr_name
        and is either a list of packager name that installed it, or a version
        string (if the version string can't be determined, returns True instead).
        """
        self.log.debug("Checking if package {} is installed.".format(name))
        if self.check_package_flag(name, 'forceinstalled'):
            self.log.debug("Package {} is forced to state 'installed'.".format(name))
            # TODO maybe we can figure out a version string
            return ['force-installed'] if return_pkgr_name else True
        r = recipe.get_recipe(name)
        pkgrs = []
        for pkgr in self.get_packagers(name):
            pkg_version = pkgr.installed(r)
            if pkg_version is None or not pkg_version:
                continue
            else:
                if return_pkgr_name:
                    pkgrs.append(pkgr.name)
                else:
                    return True
        if return_pkgr_name and len(pkgrs):
            return pkgrs
        return False
コード例 #14
0
 def run(self):
     """ Go, go, go! """
     ### Sanity checks
     for pkg in self.args.packages:
         if not self.is_installed(pkg):
             self.log.error("Package {0} is not installed into current prefix. Aborting.".format(pkg))
             return -1
     ### Make install tree
     rb_tree = dep_manager.DepManager().make_dep_tree(
         self.args.packages,
         lambda x: bool(
             (x in self.args.packages) or \
             (self.args.deps and self.is_installed(x))
         )
     )
     if self.log.getEffectiveLevel() <= 10 or self.args.print_tree:
         print("Rebuild tree:")
         rb_tree.pretty_print()
     ### Recursively rebuild, starting at the leaf nodes
     node_cache = []
     while not rb_tree.empty():
         pkg = rb_tree.pop_leaf_node()
         if pkg in node_cache:
             continue
         rec = recipe.get_recipe(pkg)
         self.log.info("Rebuilding package: {0}".format(pkg))
         if not self.pm.rebuild(
                 rec,
                 make_clean=self.args.clean,
                 nuke_builddir=not (self.args.keep_build or bool(self.cfg.get('keep_builddir', False)))
         ):
             self.log.error("Error rebuilding package {0}. Aborting.".format(pkg))
             return 1
         self.log.info("Rebuild successful.")
コード例 #15
0
 def exists(self, name, return_pkgr_name=False):
     """
     Check to see if this package is available on this platform.
     Returns True or a version string if yes, False if not.
     """
     if not return_pkgr_name and name in self.pmc.known_installable:
         self.log.obnoxious(
             "{0} is cached and known to be installable.".format(name))
         return True
     self.log.debug(
         "Checking if package {0} is installable...".format(name))
     if self.check_package_flag(name, 'forceinstalled'):
         self.log.debug(
             "Package {0} is forced to state 'installed'.".format(name))
         return ['force-installed'] if return_pkgr_name else True
     r = recipe.get_recipe(name)
     pkgrs = []
     for pkgr in self.get_packagers(name):
         pkg_version = pkgr.exists(r)
         if pkg_version is None or not pkg_version:
             continue
         else:
             self.pmc.known_installable.add(name)
             if return_pkgr_name:
                 pkgrs.append(pkgr.name)
             else:
                 return pkg_version
     if return_pkgr_name and len(pkgrs):
         return pkgrs
     self.log.debug("Package {0} is not installable.".format(name))
     return False
コード例 #16
0
ファイル: digraph.py プロジェクト: n-west/pybombs2
 def graphviz(self, packages, dotfile, pngfile):
     """
     Create the graphviz file
     """
     self.log.info("Creating digraph file {0}".format(dotfile))
     f = open(dotfile, "w")
     f.write("digraph g {\n")
     for pkg in packages:
         pkg_safe = pkg.replace("-", "_")
         f.write('{pkg} [label="{pkg}"]\n'.format(pkg=pkg_safe))
         rec = recipe.get_recipe(pkg, fail_easy=True)
         if rec is None:
             continue
         for dep in rec.depends:
             if dep in packages:
                 f.write(" {pkg} -> {dep}\n".format(
                     pkg=pkg_safe,
                     dep=dep.replace("-", "_")
                 ))
     f.write("}\n")
     f.close()
     self.log.debug("{0} written".format(dotfile))
     if pngfile is None:
         return
     self.log.info("Creating png file {0}".format(pngfile))
     subproc.monitor_process(
         ['dot', dotfile, '-Tpng', '-o{0}'.format(pngfile)],
         env=os.environ,
     )
コード例 #17
0
ファイル: dep_manager.py プロジェクト: Mohamed07/pybombs
 def make_tree_recursive(self, pkg, filter_callback):
     """
     Make a dependency tree for one package
     """
     if not filter_callback(pkg):
         return None
     tree = TreeNode(pkg)
     deps = recipe.get_recipe(pkg).get_local_package_data()['depends'] or []
     for dep in deps:
         if dep is not None and not self.pm.exists(pkg):
             self.log.error(
                 "Package does not exist: {0} (declared as dependency for package {1})".format(
                     dep, pkg
                 )
             )
             exit(1)
     deps_to_install = set([
         dep for dep in deps \
         if dep is not None and filter_callback(dep) and not isinstance(dep, list) \
     ])
     for dep in deps_to_install:
         subtree = self.make_tree_recursive(dep, filter_callback)
         if subtree is not None:
             tree.add_child(subtree)
     return tree
コード例 #18
0
 def _install_sdk_to_prefix(self, sdkname):
     """
     Read recipe for sdkname, and install the SDK to the prefix.
     """
     from pybombs import recipe
     src_dir = self.prefix.src_dir
     cfg_file = self.prefix.cfg_file
     ### Get the recipe
     r = recipe.get_recipe(sdkname, target='sdk')
     try:
         self.log.trace("Switching CWD to {0}".format(src_dir))
         if not op.isdir(src_dir):
             os.mkdir(src_dir)
         os.chdir(src_dir)
     except:
         self.log.error("Source dir required to install SDK.")
         return False
     ### Install the actual SDK file
     self.log.debug("Fetching SDK `{sdk}'".format(sdk=sdkname))
     fetcher.Fetcher().fetch(r)
     self.log.info("Installing SDK `{sdk}'".format(sdk=sdkname))
     # Install command
     cmd = r.var_replace_all(r.get_command('install'))
     if subproc.monitor_process(cmd, shell=True, env=os.environ) == 0:
         self.log.debug("Installation successful")
     else:
         self.log.error("Error installing SDK. Aborting.")
         return False
     # Clean up
     files_to_delete = [op.normpath(op.join(src_dir, r.var_replace_all(x))) for x in r.clean]
     if len(files_to_delete):
         self.log.info("Cleaning up files...")
     for ftd in files_to_delete:
         if op.commonprefix((src_dir, ftd)) != src_dir:
             self.log.warn("Not removing {ftd} -- outside source dir!".format(ftd=ftd))
             continue
         self.log.debug("Removing {ftd}...".format(ftd=ftd))
         if op.isdir(ftd):
             shutil.rmtree(ftd)
         elif op.isfile(ftd):
             os.remove(ftd)
         else:
             self.log.error("Not sure what this is: {ftd}".format(ftd=ftd))
             return False
     ### Update the prefix-local config file
     self.log.debug("Updating config file with SDK recipe info.")
     try:
         old_cfg_data = PBConfigFile(cfg_file).get()
     except IOError:
         self.log.debug("There doesn't seem to be a config file yet for this prefix.")
         old_cfg_data = {}
     # Filter out keys we don't care about:
     sdk_recipe_keys_for_config = ('config', 'packages', 'categories', 'env')
     sdk_cfg_data = {k: v for k, v in iteritems(r.get_dict()) if k in sdk_recipe_keys_for_config}
     self.log.trace("New data: {new}".format(new=sdk_cfg_data))
     cfg_data = dict_merge(old_cfg_data, sdk_cfg_data)
     self.log.debug("Writing updated prefix config to `{0}'".format(cfg_file))
     PBConfigFile(cfg_file).save(cfg_data)
     return True
コード例 #19
0
ファイル: package_manager.py プロジェクト: yueyz818/pybombs
 def check_package_flag(self, pkgname, flag):
     """
     See if package 'pkgname' has 'flag' set (return the boolean value
     of that flag if yes, or None otherwise).
     """
     return bool(
         self.cfg.get_package_flags(
             pkgname,
             recipe.get_recipe(pkgname).category).get(flag))
コード例 #20
0
ファイル: recipes.py プロジェクト: ckuethe/pybombs
 def run_list(self):
     """
     Print a list of recipes.
     """
     pkgmgr = PackageManager()
     recmgr = RecipeListManager()
     self.log.debug("Loading all package names")
     all_recipes = recmgr.list_all()
     if self.args.list is not None:
         all_recipes = [x for x in all_recipes if re.search(self.args.list, x)]
     not_installed_string = '-'
     format_pkg_list = lambda x: [not_installed_string] if not x else x
     rows = []
     row_titles = {
         'id': "Package Name",
         'path': "Recipe Filename",
         'installed_by': "Installed By",
         'available_from': "Available From",
     }
     self.args.format = [x for x in self.args.format.split(",") if len(x)]
     if any(map(lambda x: x not in row_titles, self.args.format)):
         self.log.error("Invalid column formatting: {0}".format(self.args.format))
         return -1
     print("Loading package information...", end="")
     sys.stdout.flush()
     home_dir = os.path.expanduser("~")
     for pkg in all_recipes:
         rec = recipe.get_recipe(pkg, target=None, fail_easy=True)
         if rec is None:
             print()
             self.log.warn("Recipe for `{0}' is invalid.".format(pkg))
             continue
         if rec.target != 'package':
             continue
         print(".", end="")
         sys.stdout.flush()
         row = {
             'id': pkg,
             'path': recmgr.get_recipe_filename(pkg).replace(home_dir, "~"),
             'installed_by': format_pkg_list(pkgmgr.installed(pkg, return_pkgr_name=True)),
             'available_from': ",".join(format_pkg_list(pkgmgr.exists(pkg, return_pkgr_name=True))),
         }
         if self.args.in_prefix and 'source' not in row['installed_by']:
             continue
         if row['installed_by'] == [not_installed_string] and (self.args.installed or self.args.in_prefix):
             continue
         row['installed_by'] = ",".join(row['installed_by'])
         rows.append(row)
     print("")
     tables.print_table(
             row_titles,
             rows,
             self.args.format,
             sort_by=self.args.sort_by,
     )
コード例 #21
0
ファイル: recipes.py プロジェクト: ferhat1234/proje
 def run_list(self):
     """
     Print a list of recipes.
     """
     pkgmgr = PackageManager()
     recmgr = RecipeListManager()
     self.log.debug("Loading all package names")
     all_recipes = recmgr.list_all()
     if self.args.list is not None:
         all_recipes = [x for x in all_recipes if re.search(self.args.list, x)]
     not_installed_string = '-'
     format_pkg_list = lambda x: [not_installed_string] if not x else x
     rows = []
     row_titles = {
         'id': "Package Name",
         'path': "Recipe Filename",
         'installed_by': "Installed By",
         'available_from': "Available From",
     }
     self.args.format = [x for x in self.args.format.split(",") if len(x)]
     if any((x not in row_titles for x in self.args.format)):
         self.log.error("Invalid column formatting: {0}".format(self.args.format))
         return -1
     print("Loading package information...", end="")
     sys.stdout.flush()
     home_dir = os.path.expanduser("~")
     for pkg in all_recipes:
         rec = recipe.get_recipe(pkg, target=None, fail_easy=True)
         if rec is None:
             print()
             self.log.warn("Recipe for `{0}' is invalid.".format(pkg))
             continue
         if rec.target != 'package':
             continue
         print(".", end="")
         sys.stdout.flush()
         row = {
             'id': pkg,
             'path': recmgr.get_recipe_filename(pkg).replace(home_dir, "~"),
             'installed_by': format_pkg_list(pkgmgr.installed(pkg, return_pkgr_name=True)),
             'available_from': ",".join(format_pkg_list(pkgmgr.exists(pkg, return_pkgr_name=True))),
         }
         if self.args.in_prefix and 'source' not in row['installed_by']:
             continue
         if row['installed_by'] == [not_installed_string] and (self.args.installed or self.args.in_prefix):
             continue
         row['installed_by'] = ",".join(row['installed_by'])
         rows.append(row)
     print("")
     tables.print_table(
         row_titles,
         rows,
         self.args.format,
         sort_by=self.args.sort_by,
     )
コード例 #22
0
ファイル: package_manager.py プロジェクト: gnuradio/pybombs
 def check_package_flag(self, pkgname, flag):
     """
     See if package 'pkgname' has 'flag' set (return the boolean value
     of that flag if yes, or None otherwise).
     """
     return bool(
         self.cfg.get_package_flags(
             pkgname,
             recipe.get_recipe(pkgname).category
         ).get(flag)
     )
コード例 #23
0
ファイル: package_manager.py プロジェクト: n-west/pybombs2
 def exists(self, name):
     """
     Check to see if this package is available on this platform.
     Returns True or a version string if yes, False if not.
     """
     if self.check_package_flag(name, 'forceinstalled'):
         return True
     r = recipe.get_recipe(name)
     for pkgr in self.get_packagers(name):
         pkg_version = pkgr.exists(r)
         if pkg_version is None or not pkg_version:
             continue
         return pkg_version
     return False
コード例 #24
0
ファイル: dep_manager.py プロジェクト: ferhat1234/proje
    def make_tree_recursive(self, pkg, filter_callback):
        """
        Make a dependency tree for one package.

        Assumption is that pkg actually needs to go into the tree, it will
        not get checked by filter_callback again.
        """
        assert pkg is not None
        tree = TreeNode(pkg)
        all_deps = recipe.get_recipe(pkg).depends or []
        deps_to_install = set([dep for dep in all_deps if filter_callback(dep)])
        for dep in deps_to_install:
            tree.add_child(self.make_tree_recursive(dep, filter_callback))
        return tree
コード例 #25
0
ファイル: package_manager.py プロジェクト: vosgus/pybombs
 def exists(self, name):
     """
     Check to see if this package is available on this platform.
     Returns True or a version string if yes, False if not.
     """
     if self.check_package_flag(name, 'forceinstalled'):
         return True
     r = recipe.get_recipe(name)
     for pkgr in self.get_packagers(name):
         pkg_version = pkgr.exists(r)
         if pkg_version is None or not pkg_version:
             continue
         return pkg_version
     return False
コード例 #26
0
 def _write_env_file(self, path):
     prefix_recipe = recipe.get_recipe('default_prefix',
                                       target='prefix',
                                       fail_easy=True)
     #if prefix_recipe is None:
     #self.log.error("Could not find recipe for `{0}'".format(self.args.recipe))
     #return False
     if not sysutils.dir_is_writable(path):
         pass
     try:
         for fname, content in prefix_recipe.files.items():
             sysutils.write_file_in_subdir(
                 path, fname, prefix_recipe.var_replace_all(content))
     except:
         pass
     return True
コード例 #27
0
ファイル: git.py プロジェクト: ferhat1234/proje
 def _get_git_remotes(packages):
     """ Return a dict pkgname -> git remote for every package that has
     a git remote given. """
     the_fetcher = fetcher.Fetcher()
     recipes = {pkg: recipe.get_recipe(pkg, fail_easy=True) for pkg in packages}
     sources = {pkg: recipes[pkg].source for pkg in recipes if recipes[pkg] is not None}
     git_sources = {}
     for pkg in sources:
         try:
             for src in sources[pkg]:
                 url_type, url = the_fetcher.parse_uri(src)
                 if url_type == 'git':
                     git_sources[pkg] = url
                     break
         except PBException:
             pass
     return git_sources
コード例 #28
0
ファイル: package_manager.py プロジェクト: yueyz818/pybombs
    def installed(self,
                  name,
                  return_pkgr_name=False,
                  install_type=None,
                  ignore_pkg_flag=False):
        """
        Check to see if this recipe is installed (identified by its name).

        If not, return False. If yes, return value depends on return_pkgr_name
        and is either a list of packager name that installed it, or a version
        string (if the version string can't be determined, returns True instead).

        ignore_pkg_flag is passed to get_packagers().
        """
        install_type = _get_valid_install_type(install_type)
        if not return_pkgr_name and name in self.pmc.known_installed.get(
                install_type, {}):
            self.log.trace("{0} has cached installed-status: {1}".format(
                name,
                self.pmc.known_installed.get(install_type, {}).get(name)))
            return self.pmc.known_installed.get(install_type, {}).get(name)
        self.log.debug("Checking if package {0} is installed...".format(name))
        if self.check_package_flag(name, 'forceinstalled'):
            self.log.debug(
                "Package {0} is forced to state 'installed'.".format(name))
            # TODO maybe we can figure out a version string
            return ['force-installed'] if return_pkgr_name else True
        r = recipe.get_recipe(name)
        pkgrs = []
        for pkgr in self.get_packagers(name, install_type, ignore_pkg_flag):
            pkg_version = pkgr.installed(r)
            if pkg_version is None or not pkg_version:
                continue
            else:
                self.pmc.known_installed[install_type][name] = True
                if return_pkgr_name:
                    pkgrs.append(pkgr.name)
                else:
                    return pkg_version
        if return_pkgr_name and len(pkgrs):
            return pkgrs
        self.pmc.known_installed[install_type][name] = False
        self.log.debug("Package {0} is not installed.".format(name))
        return False
コード例 #29
0
 def make_tree_recursive(self, pkg, filter_callback):
     """
     Make a dependency tree for one package
     """
     if not filter_callback(pkg):
         return None
     tree = TreeNode(pkg)
     deps = recipe.get_recipe(pkg).depends or []
     for dep in deps:
         if not self.pm.exists(pkg):
             raise PBException(
                 "Package does not exist: {0} (declared as dependency for package {1})"
                 .format(dep, pkg))
     deps_to_install = set([dep for dep in deps if filter_callback(dep)])
     for dep in deps_to_install:
         subtree = self.make_tree_recursive(dep, filter_callback)
         if subtree is not None:
             tree.add_child(subtree)
     return tree
コード例 #30
0
ファイル: remove.py プロジェクト: n-west/pybombs2
 def get_dependees(self, pkgs):
     """
     From a list of pkgs, return a list that also includes packages
     which depend on them.
     """
     self.log.debug("Resolving dependency list for clean removal.")
     other_installed_pkgs = [x for x in self.inventory.get_packages() if not x in pkgs]
     new_pkgs = []
     for other_installed_pkg in other_installed_pkgs:
         self.log.obnoxious("Checking if {0} is a dependee...".format(other_installed_pkg))
         deps = recipe.get_recipe(other_installed_pkg).get_local_package_data()['depends'] or []
         for pkg in pkgs:
             if pkg in deps:
                 self.log.obnoxious("Yup, it is.")
                 new_pkgs.append(other_installed_pkg)
                 break
     if len(new_pkgs) > 0:
         pkgs = pkgs + new_pkgs
         return self.get_dependees(pkgs)
     return pkgs
コード例 #31
0
ファイル: dep_manager.py プロジェクト: NinjaComics/pybombs
 def make_tree_recursive(self, pkg, filter_callback):
     """
     Make a dependency tree for one package
     """
     if not filter_callback(pkg):
         return None
     tree = TreeNode(pkg)
     deps = recipe.get_recipe(pkg).depends or []
     for dep in deps:
         if not self.pm.exists(pkg):
             raise PBException(
                 "Package does not exist: {0} (declared as dependency for package {1})".format(
                     dep, pkg
                 )
             )
     deps_to_install = set([dep for dep in deps if filter_callback(dep)])
     for dep in deps_to_install:
         subtree = self.make_tree_recursive(dep, filter_callback)
         if subtree is not None:
             tree.add_child(subtree)
     return tree
コード例 #32
0
ファイル: package_manager.py プロジェクト: gnuradio/pybombs
 def _std_package_operation(self, name, operation, pkgrs, verify=False, **kwargs):
     """
     Standard package operation: Try an operation on all packagers.
     """
     rec = recipe.get_recipe(name)
     for pkgr in pkgrs:
         self.log.debug("Using packager {0}".format(pkgr.name))
         try:
             result = getattr(pkgr, operation)(rec, **kwargs)
             if result:
                 if verify and not pkgr.verify(rec):
                     self.log.warn("Package reported successful {0}, but verification failed.".format(operation))
                     continue
                 return True
         except PBException as ex:
             self.log.error(
                 "Something went wrong while trying to {0} {1} using {2}: {3}".format(
                     operation, name, pkgr.name, str(ex).strip()
                 )
             )
     return False
コード例 #33
0
ファイル: package_manager.py プロジェクト: gnuradio/pybombs
    def installed(self, name, return_pkgr_name=False, install_type=None, ignore_pkg_flag=False):
        """
        Check to see if this recipe is installed (identified by its name).

        If not, return False. If yes, return value depends on return_pkgr_name
        and is either a list of packager name that installed it, or a version
        string (if the version string can't be determined, returns True instead).

        ignore_pkg_flag is passed to get_packagers().
        """
        install_type = _get_valid_install_type(install_type)
        if not return_pkgr_name and name in self.pmc.known_installed.get(install_type, {}):
            self.log.trace("{0} has cached installed-status: {1}".format(
                name, self.pmc.known_installed.get(install_type, {}).get(name)
            ))
            return self.pmc.known_installed.get(install_type, {}).get(name)
        self.log.debug("Checking if package {0} is installed...".format(name))
        if self.check_package_flag(name, 'forceinstalled'):
            self.log.debug("Package {0} is forced to state 'installed'.".format(name))
            # TODO maybe we can figure out a version string
            return ['force-installed'] if return_pkgr_name else True
        r = recipe.get_recipe(name)
        pkgrs = []
        for pkgr in self.get_packagers(name, install_type, ignore_pkg_flag):
            pkg_version = pkgr.installed(r)
            if pkg_version is None or not pkg_version:
                continue
            else:
                self.pmc.known_installed[install_type][name] = True
                if return_pkgr_name:
                    pkgrs.append(pkgr.name)
                else:
                    return pkg_version
        if return_pkgr_name and len(pkgrs):
            return pkgrs
        self.pmc.known_installed[install_type][name] = False
        self.log.debug("Package {0} is not installed.".format(name))
        return False
コード例 #34
0
def get_prefix_recipe(recipe_name):
    " Return the prefix recipe or None "
    from pybombs import recipe
    return recipe.get_recipe(recipe_name, target='prefix', fail_easy=True)
コード例 #35
0
    def run(self):
        """This is where we generate our data and provide a signal it to the GUI
        """
        self.indicator.emit("Collecting packages for PyBOMBS")
        #Init lists required to hold our data
        app_package_list = []
        sdk_package_list = []
        app_package_data = []
        sdk_package_data = []
        base_package_data = []

        pm = package_manager.PackageManager()
        #cfg = config_manager.config_manager
        #TODO Correctly list out recipes based on the prefix selected

        list_recipes = sorted(list(recipe_manager.recipe_manager.list_all()))

        for pkg_name in list_recipes:
            module = Recipe(recipe_manager.recipe_manager.
                            get_recipe_filename(pkg_name))
            if module.target == 'prefix':
                sdk_package_list.append(pkg_name)
            elif module.target == 'sdk':
                sdk_package_list.append(pkg_name)
            elif module.target == 'package':
                app_package_list.append(pkg_name)

        self.indicator.emit("Preparing SDK packages")
        self.log.info("Preparing SDK packages")
        for pkg in sdk_package_list:
            rec = Recipe(recipe_manager.recipe_manager.get_recipe_filename(pkg))
            if rec.target == 'prefix':
                sdk_package_data.append([pkg, 'Prefix Specific Packages'])
            elif rec.target == 'sdk':
                sdk_package_data.append([pkg, 'SDK Packages'])
        self.log.info("Loading SDK packages - successful !")

        self.indicator.emit("Preparing application and baseline packages")
        self.log.info("Preparing application and baseline packages")
        for oot_module in app_package_list:
            rec = recipe.get_recipe(oot_module, target='package', fail_easy=True)
            if rec.category == 'baseline':
                if pm.installed(oot_module):
                    base_package_data.append([oot_module, 'Installed'])
                else:
                    base_package_data.append([oot_module, 'Not Installed'])
            else:
                if 'description' in rec.get_dict():
                    if pm.installed(oot_module):
                        app_package_data.append([oot_module,
                                                 rec.get_dict()['category'],
                                                 'Installed',
                                                 rec.get_dict()['description']])
                    else:
                        app_package_data.append([oot_module,
                                                 rec.get_dict()['category'],
                                                 'Not Installed',
                                                 rec.get_dict()['description']])
                else:
                    if pm.installed(oot_module):
                        app_package_data.append([oot_module,
                                                 rec.get_dict()['category'],
                                                 'Installed',
                                                 'No description available'])
                    else:
                        app_package_data.append([oot_module,
                                                 rec.get_dict()['category'],
                                                 'Not Installed',
                                                 'No description available'])

        self.data_generator.emit(app_package_data, base_package_data,
                                 sdk_package_data)
        self.log.info("Loading application and baseline packages - Successful !")
        self.data_done.emit("Data successfully loaded")
        return
コード例 #36
0
ファイル: recipes.py プロジェクト: vosgus/pybombs
 def _list_recipes(self):
     """
     Print a list of recipes.
     """
     pkgmgr = PackageManager()
     recmgr = RecipeListManager()
     self.log.debug("Loading all package names")
     all_recipes = recmgr.list_all()
     if self.args.list is not None:
         all_recipes = [
             x for x in all_recipes if re.search(self.args.list, x)
         ]
     not_installed_string = '-'
     format_installed_by = lambda x: [not_installed_string] if not x else x
     rows = []
     row_titles = {
         'id': "Package Name",
         'path': "Recipe Filename",
         'installed_by': "Installed By",
     }
     self.args.format = [x for x in self.args.format.split(",") if len(x)]
     if any(map(lambda x: x not in row_titles, self.args.format)):
         self.log.error("Invalid column formatting: {0}".format(
             self.args.format))
         return -1
     widths = {k: len(row_titles[k]) for k in row_titles.keys()}
     print("Loading package information...", end="")
     sys.stdout.flush()
     home_dir = os.path.expanduser("~")
     for pkg in all_recipes:
         if recipe.get_recipe(pkg, target=None).target != 'package':
             continue
         print(".", end="")
         sys.stdout.flush()
         row = {
             'id':
             pkg,
             'path':
             recmgr.get_recipe_filename(pkg).replace(home_dir, "~"),
             'installed_by':
             format_installed_by(
                 pkgmgr.installed(pkg, return_pkgr_name=True)),
         }
         if self.args.in_prefix and 'source' not in row['installed_by']:
             continue
         if row['installed_by'] == [
                 not_installed_string
         ] and (self.args.installed or self.args.in_prefix):
             continue
         row['installed_by'] = ",".join(row['installed_by'])
         widths = {k: max(widths[k], len(row[k])) for k in row.iterkeys()}
         rows.append(row)
     print("\n")
     # Sort rows
     if self.args.sort_by is not None and self.args.sort_by in row_titles.keys(
     ):
         rows = sorted(rows, key=lambda k: k[self.args.sort_by])
     # Print Header
     hdr_len = 0
     for col_id in self.args.format:
         format_string = "{0:" + str(widths[col_id]) + "}  "
         hdr_title = format_string.format(row_titles[col_id])
         print(hdr_title, end="")
         hdr_len += len(hdr_title)
     print("")
     print("-" * hdr_len)
     # Print Table
     for row in rows:
         for col_id in self.args.format:
             format_string = "{{0:{width}}}  ".format(width=widths[col_id])
             print(format_string.format(row[col_id]), end="")
         print("")
     print("")
コード例 #37
0
    def prefix_init(self):
        """
        pybombs prefix init
        """
        prefix_path = str(self.prefixconfig_dialogui.lineEdit_2.text())
        alias = str(self.prefixconfig_dialogui.lineEdit.text())

        if not self.check_alias(alias):
            return False
        else:
            prefix_alias = alias

        print(prefix_alias, prefix_path)
        self.prefixconfig_dialogui.lineEdit.clear()
        self.prefixconfig_dialogui.lineEdit_2.clear()

        # Check alias and prefix dir validity
        prefix_recipe = recipe.get_recipe('default_prefix', target='prefix',
                                          fail_easy=True)

        # Make sure the directory is writable
        path = os.path.abspath(os.path.normpath(prefix_path))

        if not sysutils.mkdir_writable(path):
            dir_msg = "Choose a prefix directory with write access"
            self.color_strips(dir_msg, 'red')
            return False

        # Make sure that a pybombs directory doesn't already exist
        if os.path.exists(os.path.join(path, config_manager.PrefixInfo.prefix_conf_dir)):
            dir_exists = "Prefix directory already exists. Choose a new one"
            self.color_strips(dir_exists, 'red')
            return False

        # Add subdirs
        sysutils.require_subdirs(path,
                                 [k for k, v in prefix_recipe.dirs.items() if v])
        self.cfg.load(select_prefix=path)
        self.prefix = self.cfg.get_active_prefix()

        # Create files
        for fname, content in prefix_recipe.files.items():
            sysutils.write_file_in_subdir(path, fname,
                                          prefix_recipe.var_replace_all(content))

        # If there is no default prefix, make this the default
        if len(self.cfg.get('default_prefix')) == 0:
            if prefix_alias is not None:
                new_default_prefix = prefix_alias
            else:
                new_default_prefix = prefix_path
            self.cfg.update_cfg_file({'config':
                                      {'default_prefix': new_default_prefix}})

        # Create virtualenv if so desired
        if self.prefixconfig_dialogui.checkBox.isChecked():
            #self.log.info("Creating Python virtualenv in prefix...")
            venv_args = ['virtualenv']
            venv_args.append(path)
            subproc.monitor_process(args=venv_args)

        # Update config section
        if len(prefix_recipe.config):
            if self.prefixconfig_dialogui.checkBox.isChecked():
                prefix_recipe.config = dict_merge(
                    {'virtualenv': True}, prefix_recipe.config)
                self.cfg.update_cfg_file(prefix_recipe.config, self.prefix.cfg_file)
            else:
                prefix_recipe.config = dict_merge(
                    {'virtualenv': False}, prefix_recipe.config)
                self.cfg.update_cfg_file(prefix_recipe.config, self.prefix.cfg_file)

            self.cfg.load(select_prefix=prefix_path)
            self.prefix = self.cfg.get_active_prefix()
            self.cfg.update_cfg_file({'prefix_aliases':{prefix_alias: prefix_path}},
                                 self.cfg.local_cfg)
        success_msg = 'Successfully created prefix in {}'.format(prefix_path)
        self.color_strips(success_msg, 'blue')
        self.close()
        return True
コード例 #38
0
    def _std_package_operation(self, name, operation, pkgrs, verify=False, **kwargs):
        """
        Standard package operation: Try an operation on all packagers.
        """
        rec = recipe.get_recipe(name)

        virtualenv = config_manager.extract_cfg_items(self.current_prefix.cfg_file,
                                                      'virtualenv')

        #If the following condition is satisfied, pybombs uses pip explicity
        #to install those packages specific to the virtualenv
        if virtualenv and 'python' in rec.depends:
            try:
                if 'pip' in rec.satisfy:
                    pkgr = pkgrs[0]
                    self.log.debug("Using packager {}".format(pkgr.name))
                    try:
                        result = getattr(pkgr, operation)(rec, **kwargs)
                        if result:
                            if verify and not pkgr.verify(rec):
                                self.log.warn("Package reported successful {0},' \
                                              'but verification failed.".format(operation))
                                return True
                    except PBException as ex:
                        self.log.error(
                            "Something went wrong while trying to {} {} using {}: {}".format(
                                operation, name, pkgr.name, str(ex).strip()))
            except:
                for pkgr in pkgrs:
                    self.log.debug("Using packager {}".format(pkgr.name))
                    try:
                        result = getattr(pkgr, operation)(rec, **kwargs)
                        if result:
                            if verify and not pkgr.verify(rec):
                                self.log.warn("Package reported successful {0},' \
                                              'but verification failed.".format(operation))
                                continue
                            return True
                    except PBException as ex:
                        self.log.error(
                            "Something went wrong while trying to {} {} using {}: {}".format(
                                operation, name, pkgr.name, str(ex).strip()))

        #This works exactly like the above piece of code, but with all the
        #available packagers
        else:
            for pkgr in pkgrs:
                self.log.debug("Using packager {}".format(pkgr.name))
                try:
                    result = getattr(pkgr, operation)(rec, **kwargs)
                    if result:
                        if verify and not pkgr.verify(rec):
                            self.log.warn("Package reported successful {0},' \
                                          'but verification failed.".format(operation))
                            continue
                        return True
                except PBException as ex:
                    self.log.error(
                        "Something went wrong while trying to {} {} using {}: {}".format(
                            operation, name, pkgr.name, str(ex).strip()))

        return False
コード例 #39
0
ファイル: recipes.py プロジェクト: n-west/pybombs2
 def _list_recipes(self):
     """
     Print a list of recipes.
     """
     pkgmgr = PackageManager()
     recmgr = RecipeListManager()
     self.log.debug("Loading all package names")
     all_recipes = recmgr.list_all()
     if self.args.list is not None:
         all_recipes = [x for x in all_recipes if re.search(self.args.list, x)]
     not_installed_string = '-'
     format_installed_by = lambda x: [not_installed_string] if not x else x
     rows = []
     row_titles = {
         'id': "Package Name",
         'path': "Recipe Filename",
         'installed_by': "Installed By",
     }
     self.args.format = [x for x in self.args.format.split(",") if len(x)]
     if any(map(lambda x: x not in row_titles, self.args.format)):
         self.log.error("Invalid column formatting: {0}".format(self.args.format))
         return -1
     widths = {k: len(row_titles[k]) for k in row_titles.keys()}
     print("Loading package information...", end="")
     sys.stdout.flush()
     home_dir = os.path.expanduser("~")
     for pkg in all_recipes:
         if recipe.get_recipe(pkg, target=None).target != 'package':
             continue
         print(".", end="")
         sys.stdout.flush()
         row = {
             'id': pkg,
             'path': recmgr.get_recipe_filename(pkg).replace(home_dir, "~"),
             'installed_by': format_installed_by(pkgmgr.installed(pkg, return_pkgr_name=True)),
         }
         if self.args.in_prefix and 'source' not in row['installed_by']:
             continue
         if row['installed_by'] == [not_installed_string] and (self.args.installed or self.args.in_prefix):
             continue
         row['installed_by'] = ",".join(row['installed_by'])
         widths = {k: max(widths[k], len(row[k])) for k in row.iterkeys()}
         rows.append(row)
     print("\n")
     # Sort rows
     if self.args.sort_by is not None and self.args.sort_by in row_titles.keys():
         rows = sorted(rows, key=lambda k: k[self.args.sort_by])
     # Print Header
     hdr_len = 0
     for col_id in self.args.format:
         format_string = "{0:" + str(widths[col_id]) + "}  "
         hdr_title = format_string.format(row_titles[col_id])
         print(hdr_title, end="")
         hdr_len += len(hdr_title)
     print("")
     print("-" * hdr_len)
     # Print Table
     for row in rows:
         for col_id in self.args.format:
             format_string = "{{0:{width}}}  ".format(width=widths[col_id])
             print(format_string.format(row[col_id]), end="")
         print("")
     print("")