Now uses transaction module. Conditional statement changed for checking if an argv is a bottle file: - Initially check for file suffix. Inform if file detected. - Then check if bottle file exists on the system. Report accordingly. - Attempt to load the bottle file as a package. Fail if otherwise unable to do this. Otherwise inform that it was loaded okay. Check if we have anything to install. Inform and exit if we have nothing. Start a new transaction: - This is to give greater control and ensure the goal is met. A transaction is initialised with a goal, and `.apply()` will perform this goal. - Compute the system dependencies with `.compute()`. Any dependencies which soypak can install (recognised in the packages database), will not be included here. Report if we have dependencies. - Apply the transaction to the system with `.apply()`. This will be dependent on the goal set. - Check for problems when applying the transaction with `.problems()`. - Finally commit the transaction to record.
77 lines
2.7 KiB
Python
77 lines
2.7 KiB
Python
import sys
|
|
import clog
|
|
import pathlib
|
|
import argparse
|
|
import soypak.cli.command as command
|
|
import soypak.deps.transaction as transaction
|
|
import soypak.deps.bottler as bottler
|
|
|
|
|
|
_log = clog.Logger.get("runtime_logger")
|
|
|
|
|
|
@command.register_command(name="install", help=command.CommandHelpStruct(
|
|
synopsis="Install debian binary packages.",
|
|
usage="install <package1> [<package2>, ..., <packagen>]",
|
|
summary=("Install one or multiple available packages via soypak."))
|
|
)
|
|
class Install(command.Command):
|
|
def __init__(self, *, data: argparse.Namespace, args: list[str] = []) -> None:
|
|
super().__init__()
|
|
self.data = data
|
|
self.rargs = args
|
|
|
|
|
|
def run(self):
|
|
candidates: list[bottler.PackageItem] = []
|
|
# any preinit before installing should occur here
|
|
for item in self.rargs:
|
|
# has a bottle file been directly passed?
|
|
if item.endswith(".bottle"):
|
|
_log.debug("Detected a bottle file. Attempting to sideload...", end="").withConsole()
|
|
_log.writeLog(header=False)
|
|
|
|
# check if the file actually exists on the system
|
|
if not pathlib.Path(item).resolve().exists():
|
|
_log.printLog("failed.", level=4)
|
|
_log.warn(f"Could not find bottle file {item!r}. Skipping package.").withConsole()
|
|
continue
|
|
|
|
# let's structure the file to be processed.
|
|
pkg = bottler.loadPackage(item)
|
|
if isinstance(pkg, Exception):
|
|
_log.printLog("failed.", level=4)
|
|
# :@Ethan: maybe the loadPackage could give us some information.
|
|
_log.error(f"Unable to sideload bottle file {item!r}. The following error was raised: {str(pkg)}")
|
|
sys.exit(1)
|
|
|
|
_log.printLog("ok.", level=1)
|
|
_log.debug(f"Sideloaded: {item}")
|
|
candidates.append(pkg)
|
|
|
|
|
|
continue
|
|
# let's check the database for a package by the given name
|
|
...
|
|
|
|
if not candidates:
|
|
_log.info("Nothing to install.").withConsole()
|
|
sys.exit(0)
|
|
|
|
|
|
tx = transaction.Transaction(transaction.PkgGoal.PKG_INSTALL)
|
|
depends = tx.compute(candidates)
|
|
|
|
if len(depends) > 0:
|
|
_log.debug("Computed system dependencies required by the packages selected.\n", *depends)
|
|
_log.printLog("The following system dependencies have been identified:\n",
|
|
*depends, "", level=3, sep=" | ")
|
|
|
|
tx.apply()
|
|
if not tx.problems():
|
|
...
|
|
# :@TODO: handle all the problems
|
|
|
|
# commit the transaction to record
|
|
tx.commit()
|