mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-25 09:35:54 +02:00
cmds.distro: Move all modules to lib
Functions abstracting the distribution are not only needed in the context of the distro subcommand, but also by other code, so make the bulk of the code abstracting the distribution available in some place more universally useful than below cmds.distro. This commit leaves the source files mostly unchanged. They are only patched to fix import paths, so that functionality is preserved. Refactoring the code from command-line API to library API will be done by the next commit. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
f94a2ac037
commit
7e7cee6d11
45 changed files with 44 additions and 42 deletions
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
import os, importlib
|
||||
|
||||
from ...lib.log import *
|
||||
from ...lib.distros.Util import Util
|
||||
|
||||
from ..Cmd import Cmd as Base
|
||||
from ..CmdDistro import CmdDistro
|
||||
from .backend.Util import Util
|
||||
|
||||
class Cmd(Base): # export
|
||||
|
||||
from .backend.Backend import Backend
|
||||
from ...lib.distros.Backend import Backend
|
||||
|
||||
def __init__(self, parent: CmdDistro, name: str, help: str) -> None:
|
||||
super().__init__(parent, name, help)
|
||||
|
|
@ -35,16 +37,16 @@ class Cmd(Base): # export
|
|||
backend_id = 'redhat'
|
||||
case 'opensuse' | 'suse':
|
||||
backend_id = 'suse'
|
||||
self.__backend_path = (
|
||||
os.path.splitext(__name__)[0]
|
||||
+ '.backend.'
|
||||
+ backend_id
|
||||
+ '.'
|
||||
)
|
||||
self.__backend_path = 'jw.pkg.lib.distros.' + backend_id + '.'
|
||||
return self.__backend_path
|
||||
|
||||
def _instantiate(self, name: str, *args, **kwargs):
|
||||
module = importlib.import_module(self._backend_path + name)
|
||||
module_path = self._backend_path + name
|
||||
try:
|
||||
module = importlib.import_module(module_path)
|
||||
except Exception as e:
|
||||
log(ERR, f'Failed to import module {module_path} ({str(e)})')
|
||||
raise
|
||||
cls = getattr(module, name)
|
||||
return cls(self, *args, **kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
from argparse import Namespace, ArgumentParser
|
||||
import re
|
||||
|
||||
from ...lib.Package import Package
|
||||
from ...lib.distros.BeSelect import BeSelect
|
||||
from ..CmdDistro import CmdDistro
|
||||
from .lib.Package import Package
|
||||
from .Cmd import Cmd
|
||||
from .backend.BeSelect import BeSelect
|
||||
|
||||
class CmdSelect(Cmd): # export
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ....lib.util import run_sudo
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..Cmd import Cmd
|
||||
|
||||
class Backend:
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
self.__parent = parent
|
||||
|
||||
async def _sudo(self, *args, **kwargs):
|
||||
return await run_sudo(*args, interactive=self.interactive, **kwargs)
|
||||
|
||||
@property
|
||||
def util(self):
|
||||
return self.__parent.util
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self.__parent
|
||||
|
||||
@property
|
||||
def interactive(self) -> bool:
|
||||
return self.__parent.interactive
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import abc
|
||||
from argparse import Namespace
|
||||
|
||||
from .Backend import Backend as Base
|
||||
from ..CmdDelete import CmdDelete as Parent
|
||||
|
||||
class BeDelete(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def run(self, args: Namespace) -> None:
|
||||
pass
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import abc
|
||||
from argparse import Namespace
|
||||
|
||||
from .Backend import Backend as Base
|
||||
from ..CmdDup import CmdDup as Parent
|
||||
|
||||
class BeDup(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def run(self, args: Namespace) -> None:
|
||||
pass
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import abc
|
||||
from argparse import Namespace
|
||||
|
||||
from .Backend import Backend as Base
|
||||
from ..CmdInstall import CmdInstall as Parent
|
||||
|
||||
class BeInstall(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def run(self, args: Namespace) -> None:
|
||||
pass
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Iterable, TYPE_CHECKING
|
||||
|
||||
import abc
|
||||
|
||||
from ..lib.Package import Package
|
||||
from .Backend import Backend as Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..CmdPkg import CmdPkg as Parent
|
||||
|
||||
class BePkg(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
async def files(self, name: str) -> Iterable[str]:
|
||||
return await self._files(name)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def _files(self, name: str) -> Iterable[str]:
|
||||
pass
|
||||
|
||||
async def meta_data(self, names: Iterable[str]) -> Iterable[Package]:
|
||||
return await self._meta_data(names)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def _meta_data(self, names: Iterable[str]) -> Iterable[Package]:
|
||||
pass
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import abc
|
||||
from argparse import Namespace
|
||||
|
||||
from .Backend import Backend as Base
|
||||
from ..CmdRebootRequired import CmdRebootRequired as Parent
|
||||
|
||||
class BeRebootRequired(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def run(self, args: Namespace) -> None:
|
||||
pass
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import abc
|
||||
from argparse import Namespace
|
||||
|
||||
from .Backend import Backend as Base
|
||||
from ..CmdRefresh import CmdRefresh as Parent
|
||||
|
||||
class BeRefresh(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
@abc.abstractmethod
|
||||
async def run(self, args: Namespace) -> None:
|
||||
pass
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import abc
|
||||
from typing import Iterable
|
||||
|
||||
from .Backend import Backend as Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..CmdSelect import CmdSelect as Parent
|
||||
from .Package import Package
|
||||
|
||||
class BeSelect(Base):
|
||||
|
||||
def __init__(self, parent: Parent):
|
||||
super().__init__(parent)
|
||||
|
||||
@property
|
||||
async def all_installed_packages(self) -> Iterable[Package]:
|
||||
return await self._all_installed_packages()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def _all_installed_packages(self) -> Iterable[Package]:
|
||||
pass
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
TOPDIR = ../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-mod.mk
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from ....lib.util import run_sudo
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..Cmd import Cmd
|
||||
|
||||
class Util:
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
self.__parent = parent
|
||||
|
||||
async def _sudo(self, *args, **kwargs):
|
||||
return await run_sudo(*args, interactive=self.interactive, **kwargs)
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self.__parent
|
||||
|
||||
@property
|
||||
def interactive(self) -> bool:
|
||||
return self.__parent.interactive
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeDup import BeDup as Base
|
||||
|
||||
class Dup(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
pm_args = ['-Su']
|
||||
if args.download_only:
|
||||
pm_args.append('-w')
|
||||
return await self.util.pacman(pm_args)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeInstall import BeInstall as Base
|
||||
|
||||
class Install(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
if args.only_update:
|
||||
raise NotImplementedError('--only-update is not yet implemented for pacman')
|
||||
pacman_args = ['-S', '--needed']
|
||||
pacman_args.extend(args.packages)
|
||||
await self.util.pacman(*pacman_args)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-mod.mk
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeRefresh import BeRefresh as Base
|
||||
|
||||
class Refresh(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
raise NotImplementedError('distro refresh is not yet implemented for Arch-like distributions')
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..Util import Util as Base
|
||||
|
||||
class Util(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def pacman(self, *args):
|
||||
cmd = ['/usr/bin/pacman']
|
||||
if not self.interactive:
|
||||
cmd.extend(['--noconfirm'])
|
||||
cmd.extend(args)
|
||||
return await self._sudo(cmd)
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeDelete import BeDelete as Base
|
||||
|
||||
class Delete(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
return await self.util.dpkg(['-P', *args.names], sudo=True)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeDup import BeDup as Base
|
||||
|
||||
class Dup(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
apt_get_args: list[str] = []
|
||||
if args.download_only:
|
||||
apt_get_args.append('--download-only')
|
||||
apt_get_args.append('upgrade')
|
||||
return await self.util.apt_get(apt_get_args)
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeInstall import BeInstall as Base
|
||||
|
||||
class Install(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
apt_get_args = ['install']
|
||||
if args.only_update:
|
||||
apt_get_args.append('--only-upgrade')
|
||||
apt_get_args.append('--no-install-recommends')
|
||||
apt_get_args.extend(args.packages)
|
||||
return await self.util.apt_get(apt_get_args)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-mod.mk
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Iterable
|
||||
from argparse import Namespace
|
||||
|
||||
from ...lib.Package import Package
|
||||
from ...lib.dpkg import list_files, query_packages
|
||||
from ...Cmd import Cmd
|
||||
from ..BePkg import BePkg as Base
|
||||
|
||||
class Pkg(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def _files(self, name: str) -> Iterable[str]:
|
||||
return await list_files(name)
|
||||
|
||||
async def _meta_data(self, names: Iterable[str]) -> Iterable[Package]:
|
||||
return await query_packages(names)
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from argparse import Namespace
|
||||
|
||||
from .....lib.log import *
|
||||
from ...Cmd import Cmd
|
||||
from ..BeRebootRequired import BeRebootRequired as Base
|
||||
|
||||
class RebootRequired(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
reboot_required = '/run/reboot_required'
|
||||
if os.path.exists(reboot_required):
|
||||
if args.verbose:
|
||||
log(NOTICE, f'Yes. {reboot_required} exists.')
|
||||
required_pkgs = '/run/reboot-required.pkgs'
|
||||
if os.path.exists(required_pkgs):
|
||||
with open(required_pkgs, 'r') as f:
|
||||
content = f.read()
|
||||
print(f'-- From {required_pkgs}:')
|
||||
print(content.strip())
|
||||
return 1
|
||||
if args.verbose:
|
||||
log(NOTICE, f'No. {reboot_required} doesn\'t exist.')
|
||||
return 0
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeRefresh import BeRefresh as Base
|
||||
|
||||
class Refresh(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
return await self.util.apt_get(['update'])
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Iterable
|
||||
from argparse import Namespace
|
||||
|
||||
from ...lib.Package import Package
|
||||
from ...lib.dpkg import query_packages
|
||||
from ...Cmd import Cmd
|
||||
from ..BeSelect import BeSelect as Base
|
||||
|
||||
class Select(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def _all_installed_packages(self) -> Iterable[Package]:
|
||||
return await query_packages()
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ...lib.dpkg import run_dpkg
|
||||
from ..Util import Util as Base
|
||||
|
||||
class Util(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def apt_get(self, args: list[str]):
|
||||
cmd = ['/usr/bin/apt-get']
|
||||
mod_env = None
|
||||
if not self.interactive:
|
||||
cmd.extend(['--yes', '--quiet'])
|
||||
mod_env = { 'DEBIAN_FRONTEND': 'noninteractive' }
|
||||
cmd.extend(args)
|
||||
return await self._sudo(cmd, mod_env=mod_env)
|
||||
|
||||
async def dpkg(self, *args, **kwargs):
|
||||
return await run_dpkg(*args, **kwargs)
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeDup import BeDup as Base
|
||||
|
||||
class Dup(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
yum_args: list[str] = ['update']
|
||||
if args.download_only:
|
||||
yum_args.append('--downloadonly')
|
||||
return await self.yum(yum_args)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeInstall import BeInstall as Base
|
||||
|
||||
class Install(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
yum_args = ['update' if args.only_update else 'install']
|
||||
if not self.interactive:
|
||||
yum_args.append['-y']
|
||||
yum_args.extend(args.packages)
|
||||
return await self.util.yum(*yum_args)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-mod.mk
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeRefresh import BeRefresh as Base
|
||||
|
||||
class Refresh(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
await self.util.yum('clean', 'expire-cache')
|
||||
await self.util.yum('makecache')
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..Util import Util as Base
|
||||
|
||||
class Util(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def yum(self, *args):
|
||||
cmd = ['/usr/bin/yum']
|
||||
cmd.extend(args)
|
||||
return await self._sudo(cmd)
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeDelete import BeDelete as Base
|
||||
|
||||
class Delete(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
return await self.util.rpm(['-e', *args.names], sudo=True)
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeDup import BeDup as Base
|
||||
|
||||
class Dup(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
zypper_args = ['dup', '--force-resolution', '--auto-agree-with-licenses']
|
||||
if args.download_only:
|
||||
zypper_args.append('--download-only')
|
||||
return await self.util.zypper(zypper_args)
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeInstall import BeInstall as Base
|
||||
|
||||
class Install(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
zypper_cmd = 'update' if args.only_update else 'install'
|
||||
return await self.util.zypper([zypper_cmd, *args.packages])
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
TOPDIR = ../../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-mod.mk
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Iterable
|
||||
from argparse import Namespace
|
||||
|
||||
from ...lib.Package import Package
|
||||
from ...lib.rpm import list_files, query_packages
|
||||
from ...Cmd import Cmd
|
||||
from ..BePkg import BePkg as Base
|
||||
|
||||
class Pkg(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def _files(self, name: str) -> Iterable[str]:
|
||||
return await list_files(name)
|
||||
|
||||
async def _meta_data(self, names: Iterable[str]) -> Iterable[Package]:
|
||||
return await query_packages(names)
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeRebootRequired import BeRebootRequired as Base
|
||||
|
||||
class RebootRequired(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
opts = []
|
||||
if not args.verbose:
|
||||
pass
|
||||
#opts.append('--quiet')
|
||||
opts.append('needs-rebooting')
|
||||
stdout, stderr, ret = await self.util.zypper(opts, sudo=False, verbose=args.verbose)
|
||||
if ret != 0:
|
||||
return 1
|
||||
return 0
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from argparse import Namespace
|
||||
|
||||
from ...Cmd import Cmd
|
||||
from ..BeRefresh import BeRefresh as Base
|
||||
|
||||
class Refresh(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def run(self, args: Namespace):
|
||||
return await self.util.zypper(['refresh'])
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Iterable
|
||||
from argparse import Namespace
|
||||
|
||||
from ...lib.Package import Package
|
||||
from ...lib.rpm import query_packages
|
||||
from ...Cmd import Cmd
|
||||
from ..BeSelect import BeSelect as Base
|
||||
|
||||
class Select(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def _all_installed_packages(self) -> Iterable[Package]:
|
||||
return await query_packages()
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from .....lib.util import run_cmd
|
||||
from ...Cmd import Cmd
|
||||
from ..Util import Util as Base
|
||||
|
||||
from ...lib.rpm import run_rpm
|
||||
|
||||
class Util(Base):
|
||||
|
||||
def __init__(self, parent: Cmd):
|
||||
super().__init__(parent)
|
||||
|
||||
async def zypper(self, args: list[str], verbose: bool=False, sudo: bool=True):
|
||||
cmd = ['/usr/bin/zypper']
|
||||
if not self.interactive:
|
||||
cmd.extend(['--non-interactive', '--gpg-auto-import-keys', '--no-gpg-checks'])
|
||||
cmd.extend(args)
|
||||
if sudo:
|
||||
# Run sudo --login in case /etc/profile modifies ZYPP_CONF
|
||||
return await self._sudo(cmd, opts=['--login'], verbose=verbose)
|
||||
return await run_cmd(cmd, verbose=verbose)
|
||||
|
||||
async def rpm(self, *args, **kwargs):
|
||||
return await run_rpm(*args, **kwargs)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
TOPDIR = ../../../../../../..
|
||||
|
||||
include $(TOPDIR)/make/proj.mk
|
||||
include $(JWBDIR)/make/py-mod.mk
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Any
|
||||
|
||||
meta_tags = [
|
||||
"name",
|
||||
"vendor",
|
||||
"packager",
|
||||
"url",
|
||||
"maintainer",
|
||||
]
|
||||
|
||||
class Package:
|
||||
|
||||
name: str = None
|
||||
vendor: str|None = None
|
||||
packager: str|None = None
|
||||
url: str|None = None
|
||||
maintainer: str|None = None
|
||||
|
||||
@classmethod
|
||||
def parse_spec_str(cls, spec: str, delimiter='|'):
|
||||
tags = spec.split(delimiter)
|
||||
if len(tags) != 5:
|
||||
raise ValueError(f'Invalid package spec string \"{spec}\"')
|
||||
return cls(name=tags[0], vendor=tags[1], packager=tags[2], url=tags[3], maintainer=tags[4])
|
||||
|
||||
@classmethod
|
||||
def parse_specs_str(cls, specs: str, delimiter='|'):
|
||||
ret: list[Package] = []
|
||||
for spec in specs.splitlines():
|
||||
ret.append(cls.parse_spec_str(spec))
|
||||
return ret
|
||||
|
||||
@classmethod
|
||||
def order_tags(cls, mapping: dict[str, Any]):
|
||||
ret: dict[str, Any] = {}
|
||||
for tag in meta_tags:
|
||||
ret[tag] = mapping.get(tag, '')
|
||||
return ret
|
||||
|
||||
def __init__(self, name: str, vendor: str|None=None, packager: str|None=None, url: str|None=None, maintainer: str|None=None):
|
||||
self.name = name
|
||||
self.vendor = vendor
|
||||
self.packager = packager
|
||||
self.url = url
|
||||
self.maintainer = maintainer
|
||||
|
||||
def __repr__(self) -> str:
|
||||
global meta_tags
|
||||
return '\n'.join([f'{key:<15}: {getattr(self, key)}' for key in meta_tags])
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Iterable
|
||||
|
||||
from ....lib.util import run_cmd, run_sudo
|
||||
|
||||
from .Package import Package, meta_tags
|
||||
|
||||
_meta_map: dict[str, str]|None = None
|
||||
|
||||
def meta_map():
|
||||
global _meta_map
|
||||
if _meta_map is None:
|
||||
_meta_map = Package.order_tags({
|
||||
'name': 'binary:Package',
|
||||
'vendor': None, # deb doesn't have vendor field
|
||||
'packager': None, # -- packager --
|
||||
'url': 'Homepage',
|
||||
'maintainer': 'Maintainer',
|
||||
})
|
||||
return _meta_map
|
||||
|
||||
async def run_dpkg(args: list[str], sudo: bool=False): # export
|
||||
cmd = ['/usr/bin/dpkg']
|
||||
cmd.extend(args)
|
||||
if sudo:
|
||||
return await run_sudo(cmd)
|
||||
return await run_cmd(cmd)
|
||||
|
||||
async def run_dpkg_query(args: list[str], sudo: bool=False): # export
|
||||
cmd = ['/usr/bin/dpkg-query']
|
||||
cmd.extend(args)
|
||||
if sudo:
|
||||
return await run_sudo(cmd)
|
||||
return await run_cmd(cmd)
|
||||
|
||||
async def query_packages(names: Iterable[str] = []) -> Iterable[Package]: # export
|
||||
fmt_str = '|'.join([(f'${{{tag}}}' if tag else '') for tag in meta_map().values()]) + r'\n'
|
||||
# dpkg-query -W -f='${binary:Package}|${Maintainer}| ... \n'
|
||||
specs, stderr, status = await run_dpkg_query(['-W', '-f=' + fmt_str, *names], sudo=False)
|
||||
return Package.parse_specs_str(specs)
|
||||
|
||||
async def list_files(pkg: str) -> list[str]: # export
|
||||
file_list_str, stderr, status = await run_dpkg(['-L', pkg], sudo=False)
|
||||
return file_list_str.splitlines()
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from typing import Iterable
|
||||
|
||||
from ....lib.util import run_cmd, run_sudo
|
||||
|
||||
from .Package import Package, meta_tags
|
||||
|
||||
_meta_map: dict[str, str]|None = None
|
||||
|
||||
def meta_map():
|
||||
global _meta_map
|
||||
if _meta_map is None:
|
||||
_meta_map = Package.order_tags({
|
||||
'name': 'Name',
|
||||
'vendor': 'Vendor',
|
||||
'packager': 'Packager',
|
||||
'url': 'URL',
|
||||
'maintainer': None, # RPM doesn't have a maintainer field
|
||||
})
|
||||
return _meta_map
|
||||
|
||||
async def run_rpm(args: list[str], sudo: bool=False, **kwargs): # export
|
||||
cmd = ['/usr/bin/rpm']
|
||||
cmd.extend(args)
|
||||
if sudo:
|
||||
return await run_sudo(cmd, **kwargs)
|
||||
return await run_cmd(cmd, **kwargs)
|
||||
|
||||
async def query_packages(names: Iterable[str] = []) -> Iterable[Package]: # export
|
||||
fmt_str = '|'.join([(f'%{{{tag}}}' if tag else '') for tag in meta_map().values()]) + r'\n'
|
||||
opts = ['-q', '--queryformat', fmt_str]
|
||||
if not names:
|
||||
opts.append('-a')
|
||||
specs, stderr, status = await run_rpm([*opts, *names], throw=True, sudo=False)
|
||||
return Package.parse_specs_str(specs)
|
||||
|
||||
async def list_files(pkg: str) -> list[str]: # export
|
||||
file_list_str, stderr, status = await run_rpm(['-ql', pkg], throw=True, sudo=False)
|
||||
return file_list_str.splitlines()
|
||||
|
|
@ -7,7 +7,7 @@ from ..CmdPkg import CmdPkg as Parent
|
|||
|
||||
class Cmd(Base): # export
|
||||
|
||||
from ..backend.Backend import Backend
|
||||
from ....lib.distros.Backend import Backend
|
||||
|
||||
def __init__(self, parent: Parent, name: str, help: str) -> None:
|
||||
super().__init__(parent, name, help)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue