pmb.kconfig: refactor to remove args (MR 2346)

Co-authored-by: Stefan Hansson <newbyte@postmarketos.org>

Closes https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/issues/2402
This commit is contained in:
jane400 2024-07-04 13:29:32 +02:00 committed by Caleb Connolly
parent 4f3ede3329
commit afb036da0d
No known key found for this signature in database
GPG key ID: 0583312B195F64B6
7 changed files with 155 additions and 106 deletions

View file

@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from pmb.build.init import init, init_abuild_minimal, init_compiler from pmb.build.init import init, init_abuild_minimal, init_compiler
from pmb.build.envkernel import package_kernel from pmb.build.envkernel import package_kernel
from pmb.build.kconfig import menuconfig
from pmb.build.newapkbuild import newapkbuild from pmb.build.newapkbuild import newapkbuild
from pmb.build.other import copy_to_buildpath, get_status, index_repo from pmb.build.other import copy_to_buildpath, get_status, index_repo
from .backend import mount_pmaports from .backend import mount_pmaports

View file

@ -1,10 +1,11 @@
# Copyright 2023 Oliver Smith # Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import enum
import os import os
from pathlib import Path
from pmb.core.arch import Arch from pmb.core.arch import Arch
from pmb.core.context import get_context from pmb.core.context import get_context
from pmb.helpers import logging from pmb.helpers import logging
from pathlib import Path
from typing import Any from typing import Any
import pmb.build import pmb.build
@ -13,14 +14,38 @@ import pmb.build.checksum
import pmb.chroot import pmb.chroot
import pmb.chroot.apk import pmb.chroot.apk
import pmb.chroot.other import pmb.chroot.other
from pmb.types import PmbArgs
import pmb.helpers.pmaports import pmb.helpers.pmaports
import pmb.helpers.run import pmb.helpers.run
import pmb.parse import pmb.parse
from pmb.core import Chroot from pmb.core import Chroot
def get_arch(apkbuild) -> Arch: class KConfigUI(enum.Enum):
MENUCONFIG = "menuconfig"
XCONFIG = "xconfig"
NCONFIG = "nconfig"
def is_graphical(self) -> bool:
match self:
case KConfigUI.MENUCONFIG | KConfigUI.NCONFIG:
return False
case KConfigUI.XCONFIG:
return True
def depends(self) -> list[str]:
match self:
case KConfigUI.MENUCONFIG:
return ["ncurses-dev"]
case KConfigUI.NCONFIG:
return ["ncurses-dev"]
case KConfigUI.XCONFIG:
return ["qt5-qtbase-dev", "font-noto"]
def __str__(self) -> str:
return self.value
def get_arch(apkbuild: dict[str, Any]) -> Arch:
"""Take the architecture from the APKBUILD or complain if it's ambiguous. """Take the architecture from the APKBUILD or complain if it's ambiguous.
This function only gets called if --arch is not set. This function only gets called if --arch is not set.
@ -109,66 +134,13 @@ def extract_and_patch_sources(pkgname: str, arch) -> None:
) )
def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig) -> None: def _make(chroot: pmb.core.Chroot, make_command: str, env, pkgname, arch, apkbuild) -> None:
# Pkgname: allow omitting "linux-" prefix
if not pkgname.startswith("linux-"):
pkgname = "linux-" + pkgname
# Read apkbuild
aport = pmb.helpers.pmaports.find(pkgname) aport = pmb.helpers.pmaports.find(pkgname)
apkbuild = pmb.parse.apkbuild(aport / "APKBUILD")
arch = args.arch or get_arch(apkbuild)
chroot = pmb.build.autodetect.chroot(apkbuild, arch)
cross = pmb.build.autodetect.crosscompile(apkbuild, arch)
hostspec = arch.alpine_triple()
# Set up build tools and makedepends
pmb.build.init(chroot)
if cross:
pmb.build.init_compiler(get_context(), [], cross, arch)
depends = apkbuild["makedepends"] + ["gcc", "make"]
copy_xauth = False
if use_oldconfig:
kopt = "oldconfig"
else:
kopt = "menuconfig"
if args.xconfig:
depends += ["qt5-qtbase-dev", "font-noto"]
kopt = "xconfig"
copy_xauth = True
elif args.nconfig:
kopt = "nconfig"
depends += ["ncurses-dev"]
else:
depends += ["ncurses-dev"]
pmb.chroot.apk.install(depends, Chroot.native())
# Copy host's .xauthority into native
if copy_xauth:
pmb.chroot.other.copy_xauthority(args)
extract_and_patch_sources(pkgname, arch)
# Check for background color variable
color = os.environ.get("MENUCONFIG_COLOR")
# Run make menuconfig
outputdir = get_outputdir(pkgname, apkbuild) outputdir = get_outputdir(pkgname, apkbuild)
logging.info("(native) make " + kopt)
env = { logging.info("(native) make " + make_command)
"ARCH": arch.kernel(),
"DISPLAY": os.environ.get("DISPLAY"), pmb.chroot.user(["make", str(make_command)], chroot, outputdir, output="tui", env=env)
"XAUTHORITY": "/home/pmos/.Xauthority",
}
if cross:
env["CROSS_COMPILE"] = f"{hostspec}-"
env["CC"] = f"{hostspec}-gcc"
if color:
env["MENUCONFIG_COLOR"] = color
pmb.chroot.user(["make", kopt], Chroot.native(), outputdir, output="tui", env=env)
# Find the updated config # Find the updated config
source = Chroot.native() / outputdir / ".config" source = Chroot.native() / outputdir / ".config"
@ -181,3 +153,71 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig) -> None:
target = aport / config target = aport / config
pmb.helpers.run.user(["cp", source, target]) pmb.helpers.run.user(["cp", source, target])
pmb.build.checksum.update(pkgname) pmb.build.checksum.update(pkgname)
def _init(pkgname: str, arch: Arch | None) -> tuple[str, Arch, Any, Chroot, dict[str, str]]:
"""
:returns: pkgname, arch, apkbuild, chroot, env
"""
# Pkgname: allow omitting "linux-" prefix
if not pkgname.startswith("linux-"):
pkgname = "linux-" + pkgname
aport = pmb.helpers.pmaports.find(pkgname)
apkbuild = pmb.parse.apkbuild(aport / "APKBUILD")
if arch is None:
arch = get_arch(apkbuild)
chroot = pmb.build.autodetect.chroot(apkbuild, arch)
cross = pmb.build.autodetect.crosscompile(apkbuild, arch)
hostspec = arch.alpine_triple()
# Set up build tools and makedepends
pmb.build.init(chroot)
if cross:
pmb.build.init_compiler(get_context(), [], cross, arch)
depends = apkbuild["makedepends"] + ["gcc", "make"]
pmb.chroot.apk.install(depends, chroot)
extract_and_patch_sources(pkgname, arch)
env = {
"ARCH": arch.kernel(),
}
if cross:
env["CROSS_COMPILE"] = f"{hostspec}-"
env["CC"] = f"{hostspec}-gcc"
return pkgname, arch, apkbuild, chroot, env
def migrate_config(pkgname: str, arch: Arch | None) -> None:
pkgname, arch, apkbuild, chroot, env = _init(pkgname, arch)
_make(chroot, "oldconfig", env, pkgname, arch, apkbuild)
pass
def edit_config(pkgname: str, arch: Arch | None, config_ui: KConfigUI) -> None:
pkgname, arch, apkbuild, chroot, env = _init(pkgname, arch)
pmb.chroot.apk.install(config_ui.depends(), chroot)
# Copy host's .xauthority into native
if config_ui.is_graphical():
pmb.chroot.other.copy_xauthority(chroot)
env["DISPLAY"] = os.environ.get("DISPLAY") or ":0"
env["XAUTHORITY"] = "/home/pmos/.Xauthority"
# Check for background color variable
color = os.environ.get("MENUCONFIG_COLOR")
if color:
env["MENUCONFIG_COLOR"] = color
mode = os.environ.get("MENUCONFIG_MODE")
if mode:
env["MENUCONFIG_MODE"] = mode
_make(chroot, str(config_ui), env, pkgname, arch, apkbuild)

View file

@ -4,7 +4,6 @@ import os
from pmb.core.context import get_context from pmb.core.context import get_context
from pmb.helpers import logging from pmb.helpers import logging
import pmb.chroot.apk import pmb.chroot.apk
from pmb.types import PmbArgs
import pmb.install import pmb.install
from pmb.core import Chroot from pmb.core import Chroot
@ -34,7 +33,7 @@ def kernel_flavor_installed(chroot: Chroot, autoinstall=True) -> str | None:
return glob_result[0].name if glob_result else None return glob_result[0].name if glob_result else None
def copy_xauthority(args: PmbArgs) -> None: def copy_xauthority(chroot: Chroot) -> None:
""" """
Copy the host system's Xauthority file to the pmos user inside the chroot, Copy the host system's Xauthority file to the pmos user inside the chroot,
so we can start X11 applications from there. so we can start X11 applications from there.
@ -60,7 +59,7 @@ def copy_xauthority(args: PmbArgs) -> None:
) )
# Copy to chroot and chown # Copy to chroot and chown
copy = Chroot.native() / "home/pmos/.Xauthority" copy = chroot / "home/pmos/.Xauthority"
if os.path.exists(copy): if os.path.exists(copy):
pmb.helpers.run.root(["rm", copy]) pmb.helpers.run.root(["rm", copy])
pmb.helpers.run.root(["cp", original, copy]) pmb.helpers.run.root(["cp", original, copy])

View file

@ -19,8 +19,7 @@ from .test import Test
from .pkgrel_bump import PkgrelBump from .pkgrel_bump import PkgrelBump
from .pkgver_bump import PkgverBump from .pkgver_bump import PkgverBump
from .pull import Pull from .pull import Pull
from .kconfig_check import KConfigCheck from .kconfig import KConfigCheck, KConfigEdit, KConfigMigrate
from .kconfig_edit import KConfigEdit
"""New way to model pmbootstrap subcommands that can be invoked without PmbArgs.""" """New way to model pmbootstrap subcommands that can be invoked without PmbArgs."""
@ -89,8 +88,10 @@ def run_command(args: PmbArgs):
command = KConfigCheck( command = KConfigCheck(
args.kconfig_check_details, args.file, args.package, args.keep_going args.kconfig_check_details, args.file, args.package, args.keep_going
) )
case "edit" | "migrate": case "edit":
command = KConfigEdit(args.package[0], args.action_kconfig == "migrate") command = KConfigEdit(args.package[0], args.arch, args.xconfig, args.nconfig)
case "migrate":
command = KConfigMigrate(args.package, args.arch)
case _: case _:
raise NotImplementedError(f"Command '{args.action}' is not implemented.") raise NotImplementedError(f"Command '{args.action}' is not implemented.")

View file

@ -2,25 +2,25 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations from __future__ import annotations
from pmb import commands
from pmb.core.context import get_context
from pmb.helpers.exceptions import NonBugError
import pmb.parse.kconfig
import pmb.helpers.git import pmb.helpers.git
import pmb.config import pmb.config
import pmb.parse.kconfig
import logging import logging
from pmb import commands
from pmb.build.kconfig import KConfigUI
from pmb.core.arch import Arch
from pmb.core.context import get_context
from pmb.helpers.exceptions import NonBugError
class KConfigCheck(commands.Command): class KConfigCheck(commands.Command):
details: bool def __init__(
file: str self, details: bool, file: str, pkgname: str | list[str], keep_going: bool
packages: list[str] ) -> None:
keep_going: bool
def __init__(self, details, file, packages, keep_going) -> None:
self.details = details self.details = details
self.file = file self.file = file
self.packages = packages self.pkgname_list = [pkgname] if isinstance(pkgname, str) else pkgname
self.keep_going = keep_going self.keep_going = keep_going
def run(self) -> None: def run(self) -> None:
@ -36,16 +36,16 @@ class KConfigCheck(commands.Command):
raise NonBugError(error_msg) raise NonBugError(error_msg)
# Default to all kernel packages # Default to all kernel packages
if not self.packages: if not self.pkgname_list:
for pkg in pmb.helpers.pmaports.get_list(): for pkg in pmb.helpers.pmaports.get_list():
if pkg.startswith("linux-"): if pkg.startswith("linux-"):
self.packages.append(pkg.split("linux-")[1]) self.pkgname_list.append(pkg.split("linux-")[1])
# Iterate over all kernels # Iterate over all kernels
error = False error = False
skipped = 0 skipped = 0
self.packages.sort() self.pkgname_list.sort()
for package in self.packages: for package in self.pkgname_list:
if not get_context().force: if not get_context().force:
pkgname = package if package.startswith("linux-") else f"linux-{package}" pkgname = package if package.startswith("linux-") else f"linux-{package}"
aport = pmb.helpers.pmaports.find(pkgname) aport = pmb.helpers.pmaports.find(pkgname)
@ -68,3 +68,34 @@ class KConfigCheck(commands.Command):
" (consider 'pmbootstrap kconfig check -f')" " (consider 'pmbootstrap kconfig check -f')"
) )
logging.info("kconfig check succeeded!") logging.info("kconfig check succeeded!")
class KConfigEdit(commands.Command):
def __init__(
self, pkgname: str, arch: Arch | None, use_xconfig: bool, use_nconfig: bool
) -> None:
self.pkgname = pkgname
self.arch = arch
if use_xconfig and use_nconfig:
raise AssertionError
if use_xconfig:
self.chosen_ui = KConfigUI.XCONFIG
elif use_nconfig:
self.chosen_ui = KConfigUI.NCONFIG
else:
self.chosen_ui = KConfigUI.MENUCONFIG
def run(self) -> None:
pmb.build.kconfig.edit_config(self.pkgname, self.arch, self.chosen_ui)
class KConfigMigrate(commands.Command):
def __init__(self, pkgname: str | list[str], arch: Arch | None) -> None:
self.pkgname_list = [pkgname] if isinstance(pkgname, str) else pkgname
self.arch = arch
def run(self):
for pkgname in self.pkgname_list:
pmb.build.kconfig.migrate_config(pkgname, self.arch)

View file

@ -1,21 +0,0 @@
# Copyright 2024 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
from __future__ import annotations
from pmb import commands
import pmb.build
import pmb.helpers.args
class KConfigEdit(commands.Command):
pkgname: str
use_oldconfig: bool
def __init__(self, pkgname, use_oldconfig):
self.pkgname = pkgname
self.use_oldconfig = use_oldconfig
pass
def run(self):
args = pmb.helpers.args.please_i_really_need_args()
pmb.build.menuconfig(args, self.pkgname, self.use_oldconfig)

View file

@ -191,7 +191,7 @@ def chroot(args: PmbArgs) -> None:
# Xauthority # Xauthority
env = {} env = {}
if args.xauth: if args.xauth:
pmb.chroot.other.copy_xauthority(args) pmb.chroot.other.copy_xauthority(chroot)
env["DISPLAY"] = os.environ.get("DISPLAY") env["DISPLAY"] = os.environ.get("DISPLAY")
env["XAUTHORITY"] = "/home/pmos/.Xauthority" env["XAUTHORITY"] = "/home/pmos/.Xauthority"