[solo.commands.rescue] use world file to replicate by-user status

Uses the newly introduced function in spm: get_user_selected_packages.
This commit is contained in:
Sławomir Nizio
2018-07-30 08:49:17 +02:00
parent 77a5071cf5
commit e5db0d6b6e
3 changed files with 80 additions and 2 deletions

View File

@@ -730,6 +730,25 @@ Tools to rescue the running system.
prefix="equo.rescue.spmsync")
os.close(tmp_fd)
try:
spm_wanted_packages = spm.get_user_selected_packages()
except Exception as err:
entropy.tools.print_traceback()
entropy_client.output(
"%s: %s" % (
darkred(_("Cannot read list of user selected packages")),
err,
),
level="warning"
)
spm_wanted_packages = frozenset()
spm_wanted_map = {}
for _spm_wanted_pkg in spm_wanted_packages:
_stripped = entropy.dep.dep_getkey(_spm_wanted_pkg)
obj = spm_wanted_map.setdefault(_stripped, set())
obj.add(_spm_wanted_pkg)
for _spm_package, _spm_package_id in to_be_added:
counter += 1
entropy_client.output(
@@ -792,8 +811,28 @@ Tools to rescue the running system.
new_package_id = inst_repo.handlePackage(
data, revision = data['revision'])
inst_repo.storeInstalledPackage(new_package_id,
etpConst['spmdbid'])
def _spm_match_installed(x):
try:
return spm.match_installed_package(x)
except KeyError:
pass
spm_package_key = entropy.dep.dep_getkey(_spm_package)
spm_wanted_candidates = spm_wanted_map.get(spm_package_key, set())
# Avoid calling spm.match_installed_package() which can be
# a little slow. Now the list is reduced.
spm_wanted_matches = (_spm_match_installed(x)
for x in spm_wanted_candidates
if x is not None)
if _spm_package in spm_wanted_matches:
source = etpConst['install_sources']['user']
else:
source = etpConst['install_sources']['automatic_dependency']
inst_repo.storeInstalledPackage(
new_package_id, etpConst['spmdbid'], source)
inst_repo.commit()
try:

View File

@@ -1937,6 +1937,29 @@ class PortagePlugin(SpmPlugin):
return list(filter(catfilter, packages))
def get_user_selected_packages(self, root = None):
"""
Reimplemented from SpmPlugin class.
"""
world_atoms = set()
with self._PortageWorldSetLocker(self, root = root):
world_file = self.get_user_installed_packages_file(root = root)
enc = etpConst['conf_encoding']
try:
with codecs.open(world_file, "r", encoding=enc) \
as world_f:
world_atoms |= set((x.strip() for x in \
world_f.readlines() if x.strip()))
except (OSError, IOError) as err:
if err.errno != errno.ENOENT:
raise self.Error(err)
except UnicodeDecodeError as err:
raise self.Error("Portage world file is malformed")
return frozenset(world_atoms)
def get_package_sets(self, builtin_sets):
"""
Reimplemented from SpmPlugin class.

View File

@@ -589,6 +589,22 @@ class SpmPlugin(Singleton):
"""
raise NotImplementedError()
def get_user_selected_packages(self, root = None):
"""
Return installed list of packages that were selected by user as
selected (wanted).
Packages returned by this function can have a different representation
from what e.g. I{get_installed_packages()} returns, that is, no
package matching is done for performance.
@keyword root: specify an alternative root directory "/"
@type root: string
@return: list of installed packages found
@rtype: frozenset
@raise entropy.exceptions.SPMError: when something went bad
"""
raise NotImplementedError()
def get_package_sets(self, builtin_sets):
"""
Package sets are groups of packages meant to ease user installation and