jw.pkg.cmds.distro: Add directory

Add the subdirectory structure for the distro subcommand.

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-01-23 14:54:27 +01:00
commit ad45ee8510
4 changed files with 98 additions and 0 deletions

View file

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
import re, sys
from argparse import ArgumentParser
from ..App import App
from .Cmd import Cmd as CmdBase
class CmdDistro(CmdBase): # export
def __init__(self, parent: App) -> None:
self.__id = None
super().__init__(parent, 'distro', help="System package manager wrapper")
self._add_subcommands()
self.__interactive: bool|None = None
@property
def distro_id(self):
if self.__id is None:
if self.app.args.id is not None:
self.__id = self.app.args.id
else:
os_release = '/etc/os-release'
with open(os_release, 'r') as file:
matches = re.findall(r'^ID="?([^"]+)"?$', file.read(), re.MULTILINE)
if len(matches) != 1:
raise Exception(f'Could not read "ID=" from "{os_release}"')
self.__id = matches[0]
return self.__id
def add_arguments(self, p: ArgumentParser) -> None:
super().add_arguments(p)
p.add_argument('--id', default=None, help='Distribution ID (default is taken from /etc/os-release)')
p.add_argument('--interactive', choices=['true', 'false', 'auto'], default='false', help="Wait for user input or try to proceed unattended")
@property
def interactive(self) -> bool:
if self.__interactive is None:
match self.app.args.interactive:
case 'true':
self.__interactive = True
case 'false':
self.__interactive = False
case 'auto':
self.__interactive = sys.stdin.isatty()
return self.__interactive
async def _run(self, args):
raise Exception("Running with args", args)

View file

@ -1 +1,2 @@
from .CmdProjects import CmdProjects from .CmdProjects import CmdProjects
from .CmdDistro import CmdDistro

View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
import os, importlib
from ..Cmd import Cmd as Base
from ..CmdDistro import CmdDistro
class Cmd(Base): # export
def __init__(self, parent: CmdDistro, name: str, help: str) -> None:
super().__init__(parent, name, help)
self.__backend = None
@property
def distro_id(self) -> str:
return self.parent.distro_id
@property
def interactive(self) -> bool:
return self.parent.interactive
@property
def _backend(self):
if self.__backend is None:
class_name = self.__class__.__name__[3:] # Get rid of "Cmd"
backend_id = self.parent.distro_id.lower().replace('-', '_')
match backend_id:
case 'ubuntu' | 'raspbian':
backend_id = 'debian'
case 'centos':
backend_id = 'redhat'
case 'opensuse_tumbleweed':
backend_id = 'suse'
module_name = (
os.path.splitext(__name__)[0]
+ '.backend.'
+ backend_id
+ '.'
+ class_name
)
module = importlib.import_module(module_name)
cls = getattr(module, class_name)
self.__backend = cls(self)
return self.__backend

View file

@ -0,0 +1,4 @@
TOPDIR = ../../../../../..
include $(TOPDIR)/make/proj.mk
include $(JWBDIR)/make/py-mod.mk