Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # Copyright (c) 2004 Conectiva, Inc.
- #
- # Written by Gustavo Niemeyer <niemeyer@conectiva.com>
- #
- # This file is part of Smart Package Manager.
- #
- # Smart Package Manager is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License as published
- # by the Free Software Foundation; either version 2 of the License, or (at
- # your option) any later version.
- #
- # Smart Package Manager is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with Smart Package Manager; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- #
- from smart.option import OptionParser
- from smart.const import *
- from smart import *
- from smart.commands import remove
- from smart.commands import install
- import re
- import os.path
- target_file = os.path.expanduser('~/.targets')
- USAGE=_('smart target [[--remove] package ...]')
- DESCRIPTION=_("""
- This command will list packages which will never be considered orphans.
- If pkgname is provided, the packages will be added to the targeted packages
- list. If --remove is specified, they will be removed from targets list, and all
- non-essential packages that are not required by any of the targets will be
- removed.
- The removal tries to be conservative: if a package depends on multiple
- alternatives, they are both kept.
- """)
- EXAMPLES=_("""
- smart target
- smart target pkgname
- smart target '*kgnam*'
- smart target pkgname-1.0
- smart target pkgname-1.0-1
- smart target pkgname1 pkgname2
- smart target --remove
- smart target --remove pkgname
- smart target --remove '*kgnam*'
- smart target --remove pkgname-1.0
- smart target --remove pkgname-1.0-1
- smart target --remove pkgname1 pkgname2
- """)
- def option_parser():
- parser = OptionParser(usage=USAGE,
- description=DESCRIPTION,
- examples=EXAMPLES)
- parser.allow_interspersed_args = False
- parser.add_option("--remove", action="store_true",
- help=_("optionally remove a package and all orphans"))
- return parser
- def parse_options(argv):
- parser = option_parser()
- opts, args = parser.parse_args(argv)
- opts.args = args
- return opts
- def get_installed(ctrl):
- packages = ctrl.getCache().getPackages()
- return (package for package in packages if package.installed)
- def get_immediate_deps(packages):
- """Returns all installed deps"""
- deps = set()
- for package in packages:
- for req in package.requires:
- for prv in req.providedby:
- for prvpkg in prv.packages:
- if prvpkg.installed:
- deps.add(prvpkg)
- return deps
- def get_dependencies(targets):
- """Dependency graph traversal. Finding all packages in required lists,
- breadth first.
- If there is more than one package providing the same dependency, all are
- selected.
- """
- required_packages = set()
- targets = set(targets)
- while targets:
- required_packages.update(targets)
- deps = get_immediate_deps(targets)
- targets = deps - required_packages
- return required_packages
- def find_targets(ctrl, targetnames):
- """Converts target names to packages"""
- targets = []
- for name in targetnames:
- ratio, packages, suggestions = ctrl.search(name)
- if not packages:
- raise ValueError(name + " not found")
- for package in packages:
- if package.installed:
- targets.append(package)
- return targets
- def find_orphans(ctrl, targetnames):
- """Finds all packags not in targets' dependencies"""
- installed = get_installed(ctrl)
- targets = find_targets(ctrl, targetnames)
- necessary = get_dependencies(targets)
- return [package for package in set(installed) - set(necessary) if not package.essential]
- def main(ctrl, opts, reloadchannels=True):
- try:
- targets_list = [name.strip() for name in open(target_file)]
- except Exception, e:
- import traceback
- traceback.print_exc()
- return
- if opts.remove is None and not opts.args:
- for pkgname in sorted(targets_list):
- print pkgname
- print len(targets_list)
- else:
- if sysconf.get("auto-update"):
- from smart.commands import update
- updateopts = update.parse_options([])
- update.main(ctrl, updateopts)
- else:
- if reloadchannels:
- ctrl.reloadChannels()
- cache = ctrl.getCache()
- if opts.remove:
- targets_set = set(targets_list)
- removal_list = set(opts.args)
- not_targets = removal_list - targets_set
- if not_targets:
- raise Error, _('The following packages are not targets, therefore cannot be removed:'
- '\n'.join(not_target for not_target in sorted(not_targets)))
- targets_list = list(targets_set - removal_list)
- full_removal_list = find_orphans(ctrl, targets_list)
- pkgnames = [pkg.name for pkg in full_removal_list]
- remove_opts = remove.parse_options(pkgnames)
- remove.main(ctrl, remove_opts)
- # FIXME: don't remove if command failed
- else:
- pkgnames = opts.args[:]
- install_opts = install.parse_options(pkgnames)
- install.main(ctrl, install_opts)
- # FIXME: don't add if command failed
- targets_list = list(set(targets_list).union(set(pkgnames)))
- f = open(target_file, 'w')
- f.write('\n'.join(targets_list))
- f.close()
- # vim:ts=4:sw=4:et
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement