/missing
/contrib/pakfire.nm
/src/pakfire/__version__.py
+/src/scripts/pakfire
/src/scripts/pakfire-builder
/src/scripts/pakfire-client
/src/scripts/pakfire-daemon
README
# ------------------------------------------------------------------------------
-
-dist_bin_SCRIPTS = \
- src/scripts/pakfire
bin_SCRIPTS = \
+ src/scripts/pakfire \
src/scripts/pakfire-builder \
src/scripts/pakfire-client \
src/scripts/pakfire-daemon
EXTRA_DIST += \
+ src/scripts/pakfire.in \
src/scripts/pakfire-builder.in \
src/scripts/pakfire-client.in \
src/scripts/pakfire-daemon.in
CLEANFILES += \
+ src/scripts/pakfire \
src/scripts/pakfire-builder \
src/scripts/pakfire-client \
src/scripts/pakfire-daemon
-install-exec-local:
- $(MKDIR_P) $(DESTDIR)/$(bindir)
- cd $(DESTDIR)/$(bindir) && \
- $(LN_S) -vf pakfire pakfire-key
-
# ------------------------------------------------------------------------------
pakfire_PYTHON = \
from ._pakfire import Pakfire
+from .__version__ import PAKFIRE_VERSION as __version__
+
# Import Exceptions
from ._pakfire import CommandExecutionError
class Cli(object):
default_path = "/"
- def parse_cli(self):
- parser = argparse.ArgumentParser(
- description = _("Pakfire command line interface"),
- )
- subparsers = parser.add_subparsers()
-
- # Add common arguments
- self._add_common_arguments(parser)
-
- parser.add_argument("--arch", "-a", nargs="?",
- help=_("Run pakfire for the given architecture"))
- parser.add_argument("--root", metavar="PATH", default="/",
- help=_("The path where pakfire should operate in"))
-
- # check
- check = subparsers.add_parser("check", help=_("Check the system for any errors"))
- check.set_defaults(func=self.handle_check)
-
- # clean
- clean = subparsers.add_parser("clean", help=_("Cleanup all temporary files"))
- clean.set_defaults(func=self.handle_clean)
-
- # execute
- execute = subparsers.add_parser("execute",
- help=_("Executes a command in the pakfire environment (useful for development)"))
- execute.add_argument("--bind", action="append", default=[], dest="binds",
- help=_("Bind-mounts the given directory"))
- execute.add_argument("command", nargs=argparse.REMAINDER)
- execute.set_defaults(func=self.handle_execute)
-
- # info
- info = subparsers.add_parser("info",
- help=_("Print some information about the given package(s)"))
- info.add_argument("--long", action="store_true",
- help=_("Show more information"))
- info.add_argument("package", help=_("Give at least the name of one package"))
- info.set_defaults(func=self.handle_info)
-
- # install
- install = subparsers.add_parser("install",
- help=_("Install one or more packages to the system"))
- install.add_argument("package", nargs="+",
- help=_("Give name of at least one package to install"))
- install.add_argument("--without-recommended", action="store_true",
- help=_("Don't install recommended packages"))
- install.add_argument("--allow-uninstall", action="store_true",
- help=_("Allow uninstalling packages"))
- install.add_argument("--allow-downgrade", action="store_true",
- help=_("Allow downgrading packages"))
- install.set_defaults(func=self.handle_install)
-
- # provides
- provides = subparsers.add_parser("provides",
- help=_("Get a list of packages that provide a given file or feature"))
- provides.add_argument("pattern", help=_("File or feature to search for"))
- provides.set_defaults(func=self.handle_provides)
-
- # requires
- requires = subparsers.add_parser("requires",
- help=_("Get a list of packages that require this dependency"))
- requires.add_argument("pattern", help=_("File or feature to search for"))
- requires.set_defaults(func=self.handle_requires)
-
- # reinstall
- reinstall = subparsers.add_parser("reinstall",
- help=_("Reinstall one or more packages"))
- reinstall.add_argument("package", nargs="+",
- help=_("Give name of at least one package to reinstall"))
- reinstall.set_defaults(func=self.handle_reinstall)
-
- # remove
- remove = subparsers.add_parser("remove",
- help=_("Remove one or more packages from the system"))
- remove.add_argument("package", nargs="+",
- help=_("Give name of at least one package to remove"))
- remove.add_argument("--keep-dependencies", action="store_true",
- help=_("Keep dependencies installed"))
- remove.set_defaults(func=self.handle_remove)
-
- # repolist
- repolist = subparsers.add_parser("repolist",
- help=_("List all currently enabled repositories"))
- repolist.set_defaults(func=self.handle_repolist)
-
- # search
- search = subparsers.add_parser("search", help=_("Search for a given pattern"))
- search.add_argument("pattern", help=_("A pattern to search for"))
- search.set_defaults(func=self.handle_search)
-
- # sync
- sync = subparsers.add_parser("sync",
- help=_("Sync all installed with the latest one in the distribution"))
- sync.add_argument("--keep-orphaned", action="store_true",
- help=_("Keep orphaned packages"))
- sync.set_defaults(func=self.handle_sync)
-
- # update
- update = subparsers.add_parser("update",
- help=_("Update the whole system or one specific package"))
- update.add_argument("package", nargs="*",
- help=_("Give a name of a package to update or leave emtpy for all"))
- update.add_argument("--exclude", "-x", nargs="+", default=[],
- help=_("Exclude package from update"))
- update.add_argument("--allow-uninstall", action="store_true",
- help=_("Allow uninstalling packages"))
- update.add_argument("--allow-downgrade", action="store_true",
- help=_("Allow downgrading packages"))
- update.set_defaults(func=self.handle_update)
-
- return parser.parse_args()
-
- def _add_common_arguments(self, parser, offline_switch=True):
- parser.add_argument("--version", action="version",
- version="%(prog)s " + PAKFIRE_VERSION)
-
- parser.add_argument("-v", "--verbose", action="store_true",
- help=_("Enable verbose output."))
-
- parser.add_argument("-c", "--config", nargs="?",
- help=_("Path to a configuration file to load."))
-
- parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
- help=_("Disable a repository temporarily."), default=[])
-
- parser.add_argument("--enable-repo", nargs="*", metavar="REPO",
- help=_("Enable a repository temporarily."), default=[])
-
- if offline_switch:
- parser.add_argument("--offline", action="store_true",
- help=_("Run pakfire in offline mode."))
-
- def pakfire(self, ns):
- p = _pakfire.Pakfire(
- arch=ns.arch,
- conf=ns.config,
- path=ns.root if "root" in ns else self.default_path,
- offline=ns.offline,
- )
-
- # Disable repositories.
- for repo_name in ns.disable_repo:
- repo = p.get_repo(repo_name)
- repo.enabled = False
-
- # Enable repositories.
- for repo_name in ns.enable_repo:
- repo = p.get_repo(repo_name)
- repo.enabled = True
-
- return p
-
- def handle_execute(self, ns):
- pakfire = self.pakfire(ns)
-
- # Bind-mount everything
- for bind in ns.binds:
- pakfire.bind(bind)
-
- # Log everything to the console
- def logging_callback(level, line):
- if level >= logging.ERROR:
- sys.stderr.write("%s\n" % line)
- else:
- sys.stdout.write("%s\n" % line)
-
- return pakfire.execute(ns.command, logging_callback=logging_callback)
-
- def run(self):
- args = self.parse_cli()
- assert args.func, "Argument function not defined"
-
- try:
- return args.func(args)
-
- except KeyboardInterrupt:
- return 128 + signal.SIGINT
-
- except DependencyError as e:
- print(_("One or more dependencies could not been resolved"))
- print("") # empty line
-
- # This exception provides a list of all problems
- problems, = e.args
-
- # List all problems
- for problem in problems:
- print(" * %s" % problem)
-
- print(" %s" % _("Possible solutions are:"))
- for solution in problem.solutions:
- print(" * %s" % solution)
-
- # Add another empty line
- print("")
-
- return 4
-
- # Catch all errors and show a user-friendly error message.
- except Error as e:
- print(_("An error has occured when running Pakfire"))
- print(_("%s: %s") % (e.__class__.__name__, e.message))
-
- return e.exit_code
-
- def handle_info(self, ns):
- p = self.pakfire(ns)
-
- for pkg in p.search(ns.package, name_only=True):
- s = pkg.dump(long=ns.long)
- print(s)
-
- def handle_search(self, ns):
- p = self.pakfire(ns)
-
- for pkg in p.search(ns.pattern):
- # Skip any -debuginfo packages
- if pkg.name.endswith("-debuginfo"):
- continue
-
- print("%-24s: %s" % (pkg.name, pkg.summary))
-
- def handle_update(self, ns):
- p = self.pakfire(ns)
- p.update(
- ns.package,
- excludes=ns.exclude,
- allow_uninstall=ns.allow_uninstall,
- allow_downgrade=ns.allow_downgrade,
- )
-
- def handle_sync(self, ns):
- self.pakfire(ns).sync(keep_orphaned=ns.keep_orphaned)
-
- def handle_install(self, ns):
- p = self.pakfire(ns)
- p.install(
- ns.package,
- without_recommended=ns.without_recommended,
- allow_uninstall=ns.allow_uninstall,
- allow_downgrade=ns.allow_downgrade,
- )
-
- def handle_reinstall(self, ns):
- with self.pakfire(ns) as p:
- transaction = p.reinstall(ns.package)
-
- # Execute the transaction
- self._execute_transaction(transaction)
-
- def handle_remove(self, ns):
- p = self.pakfire(ns)
- p.erase(ns.package, keep_dependencies=ns.keep_dependencies)
-
- def handle_provides(self, ns, long=False):
- for pkg in self.pakfire(ns).whatprovides(ns.pattern):
- s = pkg.dump(long=long)
- print(s)
-
- def handle_requires(self, ns):
- for pkg in self.pakfire(ns).whatrequires(ns.pattern):
- s = pkg.dump(long=True)
- print(s)
-
- def handle_repolist(self, ns):
- p = self.pakfire(ns)
-
- FORMAT = " %-20s %8s %12s %12s "
- title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
- print(title)
- print("=" * len(title)) # spacing line
-
- for repo in p.repos:
- print(FORMAT % (repo.name, repo.enabled, repo.priority, len(repo)))
-
- def handle_clean(self, ns):
- print(_("Cleaning up everything..."))
-
- p = self.pakfire(ns)
- p.clean()
-
- def handle_check(self, ns):
- self.pakfire(ns).check()
-
class CliKey(Cli):
def parse_cli(self):
+++ /dev/null
-#!/usr/bin/python3
-###############################################################################
-# #
-# Pakfire - The IPFire package management system #
-# Copyright (C) 2017 Pakfire development team #
-# #
-# This program 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 3 of the License, or #
-# (at your option) any later version. #
-# #
-# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-
-import os
-import sys
-
-# Catch ImportError and show a more user-friendly message about what went wrong
-try:
- import pakfire.cli
-
-except ImportError as e:
- # Try to load at least the i18n support, but when this fails as well we can
- # go with an English error message.
- try:
- from pakfire.i18n import _
- except ImportError:
- _ = lambda x: x
-
- print(_("There has been an error when trying to import one or more of the"
- " modules, that are required to run Pakfire."))
- print(_("Please check your installation of Pakfire."))
- print()
- print(_("The error that lead to this:"))
- print(" ", e)
- print()
-
- # Exit immediately.
- sys.exit(1)
-
-basename2cls = {
- "pakfire" : pakfire.cli.Cli,
- "pakfire-client" : pakfire.cli.CliClient,
- "pakfire-key" : pakfire.cli.CliKey,
-}
-
-# Get the basename of the program
-basename = os.path.basename(sys.argv[0])
-
-# Check if the program was called with a weird basename.
-# If so, we exit immediately.
-if basename not in basename2cls:
- sys.exit(127)
-
-cli = basename2cls[basename]()
-ret = cli.run()
-
-sys.exit(ret)
--- /dev/null
+#!/usr/bin/python3
+##############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program 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 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+import argparse
+import sys
+
+import pakfire
+from pakfire.i18n import _
+
+class Cli(object):
+ def parse_cli(self):
+ parser = argparse.ArgumentParser(
+ description = _("Pakfire command line interface"),
+ )
+
+ # Version
+ parser.add_argument("--version", action="version",
+ version="%%(prog)s %s" % pakfire.__version__)
+
+ # Which configuration file to load?
+ parser.add_argument("--config", "-c", nargs="?",
+ help=_("Configuration file"))
+
+ # Enable/disable repositories
+ parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
+ help=_("Disable a repository"), default=[])
+ parser.add_argument("--enable-repo", nargs="*", metavar="REPO",
+ help=_("Enable a repository"), default=[])
+
+ # Offline mode
+ parser.add_argument("--offline", action="store_true",
+ help=_("Run pakfire in offline mode"))
+
+ # Architecture
+ parser.add_argument("--arch", "-a", nargs="?",
+ help=_("Run pakfire for the given architecture"))
+
+ # Root
+ parser.add_argument("--root", metavar="PATH", default="/",
+ help=_("The path where pakfire should operate in"))
+
+ subparsers = parser.add_subparsers()
+
+ # check
+ check = subparsers.add_parser("check",
+ help=_("Check the system for any errors"))
+ check.set_defaults(func=self._check)
+
+ # clean
+ clean = subparsers.add_parser("clean",
+ help=_("Cleanup all temporary files"))
+ clean.set_defaults(func=self._clean)
+
+ # execute
+ execute = subparsers.add_parser("execute",
+ help=_("Executes a command in the pakfire environment (useful for development)"))
+ execute.add_argument("--bind", action="append", default=[], dest="binds",
+ help=_("Bind-mounts the given directory"))
+ execute.add_argument("command", nargs=argparse.REMAINDER)
+ execute.set_defaults(func=self._execute)
+
+ # info
+ info = subparsers.add_parser("info",
+ help=_("Print some information about the given package(s)"))
+ info.add_argument("--long", action="store_true",
+ help=_("Show more information"))
+ info.add_argument("package", help=_("Give at least the name of one package"))
+ info.set_defaults(func=self._info)
+
+ # install
+ install = subparsers.add_parser("install",
+ help=_("Install one or more packages to the system"))
+ install.add_argument("package", nargs="+",
+ help=_("Give name of at least one package to install"))
+ install.add_argument("--without-recommended", action="store_true",
+ help=_("Don't install recommended packages"))
+ install.add_argument("--allow-uninstall", action="store_true",
+ help=_("Allow uninstalling packages"))
+ install.add_argument("--allow-downgrade", action="store_true",
+ help=_("Allow downgrading packages"))
+ install.set_defaults(func=self._install)
+
+ # provides
+ provides = subparsers.add_parser("provides",
+ help=_("Get a list of packages that provide a given file or feature"))
+ provides.add_argument("pattern", help=_("File or feature to search for"))
+ provides.set_defaults(func=self._provides)
+
+ # requires
+ requires = subparsers.add_parser("requires",
+ help=_("Get a list of packages that require this dependency"))
+ requires.add_argument("pattern", help=_("File or feature to search for"))
+ requires.set_defaults(func=self._requires)
+
+ # remove
+ remove = subparsers.add_parser("remove",
+ help=_("Remove one or more packages from the system"))
+ remove.add_argument("package", nargs="+",
+ help=_("Give name of at least one package to remove"))
+ remove.add_argument("--keep-dependencies", action="store_true",
+ help=_("Keep dependencies installed"))
+ remove.set_defaults(func=self._remove)
+
+ # repolist
+ repolist = subparsers.add_parser("repolist",
+ help=_("List all currently enabled repositories"))
+ repolist.set_defaults(func=self._repolist)
+
+ # search
+ search = subparsers.add_parser("search",
+ help=_("Search for a given pattern"))
+ search.add_argument("pattern",
+ help=_("A pattern to search for"))
+ search.set_defaults(func=self._search)
+
+ # sync
+ sync = subparsers.add_parser("sync",
+ help=_("Sync all installed with the latest one in the distribution"))
+ sync.add_argument("--keep-orphaned", action="store_true",
+ help=_("Keep orphaned packages"))
+ sync.set_defaults(func=self._sync)
+
+ # update
+ update = subparsers.add_parser("update",
+ help=_("Update the whole system or one specific package"))
+ update.add_argument("package", nargs="*",
+ help=_("Give a name of a package to update or leave emtpy for all"))
+ update.add_argument("--exclude", "-x", nargs="+", default=[],
+ help=_("Exclude package from update"))
+ update.add_argument("--allow-uninstall", action="store_true",
+ help=_("Allow uninstalling packages"))
+ update.add_argument("--allow-downgrade", action="store_true",
+ help=_("Allow downgrading packages"))
+ update.set_defaults(func=self._update)
+
+ args = parser.parse_args()
+
+ # Print usage if no action was given
+ if not "func" in args:
+ parser.print_usage()
+ sys.exit(2)
+
+ return args
+
+ def __call__(self):
+ # Parse command line arguments
+ args = self.parse_cli()
+
+ # Create Pakfire instance
+ p = pakfire.Pakfire(
+ conf=args.config,
+ arch=args.arch,
+ path=args.root,
+ offline=args.offline,
+ )
+
+ # Disable repositories
+ for name in args.disable_repo:
+ repo = p.get_repo(name)
+ repo.enabled = False
+
+ # Enable repositories
+ for name in args.enable_repo:
+ repo = p.get_repo(name)
+ repo.enabled = True
+
+ # Call function
+ try:
+ ret = args.func(p, args)
+
+ # Catch invalid inputs
+ except ValueError as e:
+ sys.stderr.write("%s\n" % e)
+ ret = 2
+
+ # Return with exit code
+ sys.exit(ret or 0)
+
+ def _check(self, p, args):
+ p.check()
+
+ def _clean(self, p, args):
+ print(_("Cleaning up everything..."))
+ p.clean()
+
+ def _execute(self, p, args):
+ """
+ Executes a command
+ """
+ # Bind-mount everything
+ for bind in args.binds:
+ p.bind(bind)
+
+ # Log everything to the console
+ def logging_callback(level, line):
+ if level >= logging.ERROR:
+ sys.stderr.write("%s\n" % line)
+ else:
+ sys.stdout.write("%s\n" % line)
+
+ return p.execute(args.command, logging_callback=logging_callback)
+
+ def _info(self, p, args):
+ for pkg in p.search(args.package, name_only=True):
+ s = pkg.dump(long=args.long)
+ print(s)
+
+ def _install(self, p, args):
+ p.install(
+ args.package,
+ without_recommended=args.without_recommended,
+ allow_uninstall=args.allow_uninstall,
+ allow_downgrade=args.allow_downgrade,
+ )
+
+ def _provides(self, p, args):
+ for pkg in p.whatprovides(args.pattern):
+ s = pkg.dump(long=True)
+ print(s)
+
+ def _remove(self, p, args):
+ p.erase(args.package, keep_dependencies=args.keep_dependencies)
+
+ def _repolist(self, p, args):
+ FORMAT = " %-20s %8s %12s %12s "
+ title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
+ print(title)
+ print("=" * len(title)) # spacing line
+
+ for repo in p.repos:
+ print(FORMAT % (repo.name, repo.enabled, repo.priority, len(repo)))
+
+ def _requires(self, p, args):
+ for pkg in p.whatrequires(args.pattern):
+ s = pkg.dump(long=True)
+ print(s)
+
+ def _search(self, p, args):
+ for pkg in p.search(args.pattern):
+ # Skip any -debuginfo packages
+ if pkg.name.endswith("-debuginfo"):
+ continue
+
+ print("%-24s: %s" % (pkg.name, pkg.summary))
+
+ def _sync(self, p, args):
+ p.sync(keep_orphaned=args.keep_orphaned)
+
+ def _update(self, p, args):
+ p.update(
+ args.package,
+ excludes=args.exclude,
+ allow_uninstall=args.allow_uninstall,
+ allow_downgrade=args.allow_downgrade,
+ )
+
+
+if __name__ == "__main__":
+ c = Cli()
+ c()