253 lines
8.1 KiB
Python
253 lines
8.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
|
|
@author: Fabio Erculiani <lxnay@sabayon.org>
|
|
@contact: lxnay@sabayon.org
|
|
@copyright: Fabio Erculiani
|
|
@license: GPL-2
|
|
|
|
B{Entropy Infrastructure Toolkit}.
|
|
|
|
"""
|
|
import sys
|
|
import argparse
|
|
|
|
from entropy.i18n import _
|
|
from entropy.const import etpConst
|
|
from entropy.output import purple, darkgreen, brown, teal, blue
|
|
|
|
from eit.commands.descriptor import EitCommandDescriptor
|
|
from eit.commands.command import EitCommand
|
|
|
|
|
|
class EitDeps(EitCommand):
|
|
"""
|
|
Main Eit deps command.
|
|
"""
|
|
|
|
NAME = "deps"
|
|
ALIASES = []
|
|
|
|
def __init__(self, args):
|
|
EitCommand.__init__(self, args)
|
|
self._packages = []
|
|
|
|
def _get_parser(self):
|
|
descriptor = EitCommandDescriptor.obtain_descriptor(
|
|
EitDeps.NAME)
|
|
parser = argparse.ArgumentParser(
|
|
description=descriptor.get_description(),
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
prog="%s %s" % (sys.argv[0], EitDeps.NAME))
|
|
|
|
parser.add_argument("packages", nargs='+', metavar="<package>",
|
|
help=_("package name"))
|
|
parser.add_argument("--in", metavar="<repository>",
|
|
help=_("inject into given repository"),
|
|
dest="inrepo", default=None)
|
|
|
|
return parser
|
|
|
|
INTRODUCTION = """\
|
|
Through this tool it's possible to add, remove and edit dependencies of
|
|
any package.
|
|
This might be helpful for small tweaks or trivial changes in order to
|
|
avoid a complete repackage.
|
|
Please do not abuse it, package file metadata are not updated accordingly,
|
|
and the same is for Source Package Manager metadata.
|
|
Consider this a last resort for updating package dependencies in a
|
|
non-permanent way.
|
|
"""
|
|
|
|
def man(self):
|
|
"""
|
|
Overridden from EitCommand.
|
|
"""
|
|
return self._man()
|
|
|
|
def parse(self):
|
|
parser = self._get_parser()
|
|
try:
|
|
nsargs = parser.parse_args(self._args)
|
|
except IOError:
|
|
return parser.print_help, []
|
|
|
|
self._packages += nsargs.packages
|
|
return self._call_locked, [self._deps, nsargs.inrepo]
|
|
|
|
def _show_dependencies_legend(self, entropy_server, indent = None):
|
|
"""
|
|
Print dependency types legend.
|
|
"""
|
|
if indent is None:
|
|
indent = ""
|
|
dep_types = etpConst['dependency_type_ids']
|
|
dep_descs = etpConst['dependency_type_ids_desc']
|
|
|
|
for dep_id, dep_val in sorted(dep_types.items(),
|
|
key = lambda x: x[0], reverse = True):
|
|
dep_desc = dep_descs.get(dep_id, _("N/A"))
|
|
txt = '%s%s%s%s %s' % (
|
|
indent, teal("{"), dep_val+1, teal("}"), dep_desc,)
|
|
entropy_server.output(txt)
|
|
|
|
def _show_package_dependencies(self, entropy_server, atom,
|
|
orig_deps, partial = False):
|
|
"""
|
|
Print package dependencies for atom.
|
|
"""
|
|
if not partial:
|
|
entropy_server.output(
|
|
"%s, %s" % (
|
|
blue(atom), darkgreen(_("package dependencies"))),
|
|
header=brown(" @@ "))
|
|
else:
|
|
entropy_server.output("")
|
|
|
|
for dep_str, dep_id in orig_deps:
|
|
entropy_server.output(
|
|
"[%s: %s] %s" % (
|
|
brown(_("type")),
|
|
darkgreen(str(dep_id+1)),
|
|
purple(dep_str)),
|
|
header=brown(" #"))
|
|
|
|
if not orig_deps:
|
|
entropy_server.output(
|
|
_("No dependencies"),
|
|
header=brown(" # "))
|
|
else:
|
|
self._show_dependencies_legend(entropy_server, " ")
|
|
|
|
if partial:
|
|
entropy_server.output("")
|
|
|
|
def _deps(self, entropy_server):
|
|
"""
|
|
Actual Eit deps code.
|
|
"""
|
|
repository_id = entropy_server.repository()
|
|
|
|
# match
|
|
package_ids = []
|
|
for package in self._packages:
|
|
match = entropy_server.atom_match(
|
|
package, match_repo = [repository_id])
|
|
if match[1] == repository_id:
|
|
package_ids.append(match[0])
|
|
else:
|
|
entropy_server.output(
|
|
"[%s] %s %s" % (
|
|
purple(repository_id),
|
|
darkgreen(package),
|
|
teal(_("not found"))),
|
|
importance=1, level="warning")
|
|
if not package_ids:
|
|
entropy_server.output(
|
|
purple(_("No packages found")),
|
|
importance=1, level="error")
|
|
return 1
|
|
|
|
avail_dep_type_desc = []
|
|
d_type_ids = etpConst['dependency_type_ids']
|
|
d_type_desc = etpConst['dependency_type_ids_desc']
|
|
for dep_val, dep_id in sorted(d_type_ids.items(),
|
|
key = lambda x: x[1]):
|
|
avail_dep_type_desc.append(d_type_desc[dep_val])
|
|
|
|
def pkg_dep_types_cb(s):
|
|
try:
|
|
avail_dep_type_desc.index(s[1])
|
|
except IndexError:
|
|
return False
|
|
return True
|
|
|
|
repo = entropy_server.open_repository(repository_id)
|
|
for package_id in package_ids:
|
|
atom = repo.retrieveAtom(package_id)
|
|
orig_deps = repo.retrieveDependencies(
|
|
package_id, extended = True,
|
|
resolve_conditional_deps = False)
|
|
dep_type_map = dict(orig_deps)
|
|
|
|
def dep_check_cb(s):
|
|
input_params = [
|
|
('dep_type', ('combo', (_("Dependency type"),
|
|
avail_dep_type_desc),),
|
|
pkg_dep_types_cb, False)
|
|
]
|
|
|
|
data = entropy_server.input_box(
|
|
("%s: %s" % (_('Select a dependency type for'), s,)),
|
|
input_params
|
|
)
|
|
if data is None:
|
|
return False
|
|
|
|
rc_dep_type = avail_dep_type_desc.index(
|
|
data['dep_type'][1])
|
|
dep_type_map[s] = rc_dep_type
|
|
changes_made_type_map = {s: rc_dep_type}
|
|
|
|
self._show_package_dependencies(entropy_server,
|
|
atom, changes_made_type_map.items(), partial = True)
|
|
return True
|
|
|
|
self._show_package_dependencies(
|
|
entropy_server, atom, orig_deps)
|
|
|
|
entropy_server.output("")
|
|
current_deps = [x[0] for x in orig_deps]
|
|
input_params = [
|
|
('new_deps', ('list', (_('Dependencies'), current_deps),),
|
|
dep_check_cb, True)
|
|
]
|
|
data = entropy_server.input_box(
|
|
_("Dependencies editor"), input_params)
|
|
if data is None:
|
|
continue
|
|
|
|
new_deps = data.get('new_deps', [])
|
|
orig_deps = [(x, dep_type_map[x],) for x in new_deps]
|
|
insert_deps = dict(orig_deps)
|
|
|
|
self._show_package_dependencies(
|
|
entropy_server, atom, orig_deps)
|
|
rc_ask = entropy_server.ask_question(_("Confirm ?"))
|
|
if rc_ask == _("No"):
|
|
continue
|
|
|
|
w_repo = entropy_server.open_server_repository(
|
|
repository_id, read_only = False)
|
|
|
|
# save new dependencies
|
|
while True:
|
|
try:
|
|
w_repo.removeDependencies(package_id)
|
|
w_repo.insertDependencies(package_id, insert_deps)
|
|
w_repo.commit()
|
|
except (KeyboardInterrupt, SystemExit,):
|
|
continue
|
|
break
|
|
|
|
# now bump, this makes EAPI=3 differential db sync happy
|
|
old_pkg_data = w_repo.getPackageData(package_id)
|
|
w_repo.handlePackage(old_pkg_data)
|
|
|
|
entropy_server.output(
|
|
"%s: %s" % (
|
|
blue(atom),
|
|
darkgreen(_("dependencies updated successfully"))),
|
|
header=brown(" @@ "))
|
|
|
|
entropy_server.commit_repositories()
|
|
return 0
|
|
|
|
|
|
EitCommandDescriptor.register(
|
|
EitCommandDescriptor(
|
|
EitDeps,
|
|
EitDeps.NAME,
|
|
_('edit dependencies for packages in repository'))
|
|
)
|