Files
entropy/server/eit/commands/deps.py
Fabio Erculiani e406a4edaa [entropy.*] create new dependencies metadata "pkg_dependencies"
The old "dependencies" metadata is deprecated. It was found that
the generated metadata might get corrupted by colliding atom strings.
The new implementation avoids collisions completely and is more
efficient.
2013-11-29 19:15:44 +01:00

252 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]
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, orig_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'))
)