Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • postmarketOS/pmbootstrap
  • fossdd/pmbootstrap
  • Adrian/pmbootstrap
  • JustSoup321/pmbootstrap
  • longnoserob/pmbootstrap
  • sixthkrum/pmbootstrap
  • ollieparanoid/pmbootstrap
  • magdesign/pmbootstrap
  • anjandev/pmbootstrap
  • HenriDellal/pmbootstrap
  • Minecrell/pmbootstrap
  • chipiguay/pmbootstrap
  • ijiki16/pmbootstrap
  • whynothugo/pmbootstrap
  • amessier/pmbootstrap
  • Eisenbahnfan/pmbootstrap
  • user0-07161/pmbootstrap
  • SzczurekYT/pmbootstrap
  • neuschaefer/pmbootstrap
  • knuxify/pmbootstrap
  • Frieder.Hannenheim/pmbootstrap
21 results
Show changes
Commits on Source (5)
Showing with 335 additions and 151 deletions
#!/bin/sh -e
set -x
if [ "$(id -u)" = 0 ]; then
exec su "${TESTUSER:-build}" -c "sh -e $0"
fi
pmbootstrap() {
./pmbootstrap.py --details-to-stdout "$@"
}
# Make sure that the work folder format is up to date, and that there are no
# mounts from aborted test cases (pmbootstrap#1595)
echo "Initializing pmbootstrap"
yes '' | ./pmbootstrap.py --details-to-stdout init
pmbootstrap work_migrate
pmbootstrap -q shutdown
# TODO: make device configurable?
device="qemu-amd64"
# TODO: make UI configurable?
ui="phosh"
pmbootstrap config device "$device"
pmbootstrap config ui "$ui"
# NOTE: --no-image is used because building images makes pmb try to
# "modprobe loop". This fails in CI.
echo "Building $ui image for $device"
pmbootstrap -y install --zap --password 147147 --no-image
echo "Building $ui image for $device, with FDE"
pmbootstrap -y install --zap --password 147147 --fde --no-image
......@@ -95,3 +95,19 @@ deploy:
- rsync -hrvz --delete -e "ssh -p ${SSH_PORT}" public/ "${SSH_HOST}":/var/www/docs.postmarketos.org/pmbootstrap/
environment:
name: deploy
integration:
stage: test
before_script:
- *global_before_scripts
- apk upgrade -U
- apk add doas git losetup python3 openssl
- echo "permit nopass build" > /etc/doas.d/ci-user.conf
script:
- ".ci/integration.sh"
after_script:
- "cp /home/build/.local/var/pmbootstrap/log.txt ."
artifacts:
when: on_failure
paths:
- "log.txt"
......@@ -20,6 +20,14 @@ pmb.commands.base module
:undoc-members:
:show-inheritance:
pmb.commands.flasher module
---------------------------
.. automodule:: pmb.commands.flasher
:members:
:undoc-members:
:show-inheritance:
pmb.commands.index module
-------------------------
......
......@@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from pmb.build.init import init, init_abuild_minimal, init_compiler
from pmb.build.envkernel import package_kernel
from pmb.build.kconfig import menuconfig
from pmb.build.newapkbuild import newapkbuild
from pmb.build.other import copy_to_buildpath, get_status, index_repo
from .backend import mount_pmaports
......
# Copyright 2023 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import enum
import os
from pathlib import Path
from pmb.core.arch import Arch
from pmb.core.context import get_context
from pmb.helpers import logging
from pathlib import Path
from typing import Any
import pmb.build
......@@ -13,14 +14,38 @@ import pmb.build.checksum
import pmb.chroot
import pmb.chroot.apk
import pmb.chroot.other
from pmb.types import PmbArgs
import pmb.helpers.pmaports
import pmb.helpers.run
import pmb.parse
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.
This function only gets called if --arch is not set.
......@@ -109,15 +134,41 @@ 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:
aport = pmb.helpers.pmaports.find(pkgname)
outputdir = get_outputdir(pkgname, apkbuild)
logging.info("(native) make " + make_command)
pmb.chroot.user(["make", str(make_command)], chroot, outputdir, output="tui", env=env)
# Find the updated config
source = Chroot.native() / outputdir / ".config"
if not source.exists():
raise RuntimeError(f"No kernel config generated: {source}")
# Update the aport (config and checksum)
logging.info("Copy kernel config back to pmaports dir")
config = f"config-{apkbuild['_flavor']}.{arch}"
target = aport / config
pmb.helpers.run.user(["cp", source, target])
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
# Read apkbuild
aport = pmb.helpers.pmaports.find(pkgname)
apkbuild = pmb.parse.apkbuild(aport / "APKBUILD")
arch = args.arch or get_arch(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()
......@@ -128,56 +179,45 @@ def menuconfig(args: PmbArgs, pkgname: str, use_oldconfig) -> None:
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)
pmb.chroot.apk.install(depends, chroot)
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)
logging.info("(native) make " + kopt)
env = {
"ARCH": arch.kernel(),
"DISPLAY": os.environ.get("DISPLAY"),
"XAUTHORITY": "/home/pmos/.Xauthority",
}
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
pmb.chroot.user(["make", kopt], Chroot.native(), outputdir, output="tui", env=env)
# Find the updated config
source = Chroot.native() / outputdir / ".config"
if not source.exists():
raise RuntimeError(f"No kernel config generated: {source}")
mode = os.environ.get("MENUCONFIG_MODE")
if mode:
env["MENUCONFIG_MODE"] = mode
# Update the aport (config and checksum)
logging.info("Copy kernel config back to pmaports dir")
config = f"config-{apkbuild['_flavor']}.{arch}"
target = aport / config
pmb.helpers.run.user(["cp", source, target])
pmb.build.checksum.update(pkgname)
_make(chroot, str(config_ui), env, pkgname, arch, apkbuild)
......@@ -4,7 +4,6 @@ import os
from pmb.core.context import get_context
from pmb.helpers import logging
import pmb.chroot.apk
from pmb.types import PmbArgs
import pmb.install
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
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,
so we can start X11 applications from there.
......@@ -60,7 +59,7 @@ def copy_xauthority(args: PmbArgs) -> None:
)
# Copy to chroot and chown
copy = Chroot.native() / "home/pmos/.Xauthority"
copy = chroot / "home/pmos/.Xauthority"
if os.path.exists(copy):
pmb.helpers.run.root(["rm", copy])
pmb.helpers.run.root(["cp", original, copy])
......
......@@ -11,6 +11,7 @@ from pmb.helpers import frontend
from .base import Command
from .aportgen import Aportgen
from .flasher import Flasher
from .log import Log
from .index import Index
from .repo_bootstrap import RepoBootstrap
......@@ -19,8 +20,7 @@ from .test import Test
from .pkgrel_bump import PkgrelBump
from .pkgver_bump import PkgverBump
from .pull import Pull
from .kconfig_check import KConfigCheck
from .kconfig_edit import KConfigEdit
from .kconfig import KConfigCheck, KConfigEdit, KConfigMigrate
"""New way to model pmbootstrap subcommands that can be invoked without PmbArgs."""
......@@ -32,7 +32,6 @@ unmigrated_commands = [
"export",
"sideload",
"netboot",
"flasher",
"initfs",
"qemu",
"aportupgrade",
......@@ -66,6 +65,16 @@ def run_command(args: PmbArgs):
match args.action:
case "aportgen":
command = Aportgen(args.packages, args.fork_alpine, args.fork_alpine_retain_branch)
case "flasher":
command = Flasher(
args.action_flasher,
args.autoinstall,
getattr(args, "cmdline", None),
args.flash_method,
getattr(args, "no_reboot", None),
getattr(args, "partition", None),
getattr(args, "resume", None),
)
case "log":
command = Log(args.clear_log, args.lines)
case "index":
......@@ -89,8 +98,10 @@ def run_command(args: PmbArgs):
command = KConfigCheck(
args.kconfig_check_details, args.file, args.package, args.keep_going
)
case "edit" | "migrate":
command = KConfigEdit(args.package[0], args.action_kconfig == "migrate")
case "edit":
command = KConfigEdit(args.package[0], args.arch, args.xconfig, args.nconfig)
case "migrate":
command = KConfigMigrate(args.package, args.arch)
case _:
raise NotImplementedError(f"Command '{args.action}' is not implemented.")
......
# Copyright 2023 Oliver Smith
# Copyright 2024 Stefan Hansson
# SPDX-License-Identifier: GPL-3.0-or-later
import pmb.parse.deviceinfo
from pmb import commands
from pmb.core.context import get_context
from pmb.flasher.frontend import flash_lk2nd, kernel, list_flavors, rootfs, sideload
from pmb.helpers import logging
class Flasher(commands.Command):
def __init__(
self,
action_flasher: str,
autoinstall: bool,
cmdline: str | None,
flash_method: str,
no_reboot: bool | None,
partition: str | None,
resume: bool | None,
) -> None:
self.action_flasher = action_flasher
self.autoinstall = autoinstall
self.cmdline = cmdline
self.flash_method = flash_method
self.no_reboot = no_reboot
self.partition = partition
self.resume = resume
def run(self) -> None:
context = get_context()
action = self.action_flasher
device = context.config.device
deviceinfo = pmb.parse.deviceinfo()
method = self.flash_method or deviceinfo.flash_method
if method == "none" and action in ["boot", "flash_kernel", "flash_rootfs", "flash_lk2nd"]:
logging.info("This device doesn't support any flash method.")
return
if action in ["boot", "flash_kernel"]:
kernel(deviceinfo, method, action == "boot", self.autoinstall)
elif action == "flash_rootfs":
rootfs(deviceinfo, method)
elif action == "flash_vbmeta":
logging.info("(native) flash vbmeta.img with verity disabled flag")
pmb.flasher.run(
deviceinfo,
method,
"flash_vbmeta",
cmdline=self.cmdline,
no_reboot=self.no_reboot,
partition=self.partition,
resume=self.resume,
)
elif action == "flash_dtbo":
logging.info("(native) flash dtbo image")
pmb.flasher.run(
deviceinfo,
method,
"flash_dtbo",
cmdline=self.cmdline,
no_reboot=self.no_reboot,
partition=self.partition,
resume=self.resume,
)
elif action == "flash_lk2nd":
flash_lk2nd(deviceinfo, method)
elif action == "list_flavors":
list_flavors(device)
elif action == "list_devices":
pmb.flasher.run(
deviceinfo,
method,
"list_devices",
cmdline=self.cmdline,
no_reboot=self.no_reboot,
partition=self.partition,
resume=self.resume,
)
elif action == "sideload":
sideload(deviceinfo, method)
......@@ -2,25 +2,25 @@
# SPDX-License-Identifier: GPL-3.0-or-later
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.config
import pmb.parse.kconfig
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):
details: bool
file: str
packages: list[str]
keep_going: bool
def __init__(self, details, file, packages, keep_going) -> None:
def __init__(
self, details: bool, file: str, pkgname: str | list[str], keep_going: bool
) -> None:
self.details = details
self.file = file
self.packages = packages
self.pkgname_list = [pkgname] if isinstance(pkgname, str) else pkgname
self.keep_going = keep_going
def run(self) -> None:
......@@ -36,16 +36,16 @@ class KConfigCheck(commands.Command):
raise NonBugError(error_msg)
# Default to all kernel packages
if not self.packages:
if not self.pkgname_list:
for pkg in pmb.helpers.pmaports.get_list():
if pkg.startswith("linux-"):
self.packages.append(pkg.split("linux-")[1])
self.pkgname_list.append(pkg.split("linux-")[1])
# Iterate over all kernels
error = False
skipped = 0
self.packages.sort()
for package in self.packages:
self.pkgname_list.sort()
for package in self.pkgname_list:
if not get_context().force:
pkgname = package if package.startswith("linux-") else f"linux-{package}"
aport = pmb.helpers.pmaports.find(pkgname)
......@@ -68,3 +68,34 @@ class KConfigCheck(commands.Command):
" (consider 'pmbootstrap kconfig check -f')"
)
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)
# 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)
......@@ -5,4 +5,3 @@ from pmb.flasher.init import install_depends
from pmb.flasher.run import run
from pmb.flasher.run import check_partition_blacklist
from pmb.flasher.variables import variables
from pmb.flasher.frontend import frontend
......@@ -7,7 +7,6 @@ from pmb.helpers import logging
import pmb.config
from pmb.parse.deviceinfo import Deviceinfo
from pmb.types import PmbArgs
import pmb.flasher
import pmb.install
import pmb.chroot.apk
......@@ -146,34 +145,3 @@ def flash_lk2nd(deviceinfo: Deviceinfo, method: str) -> None:
logging.info("(native) flash lk2nd image")
pmb.flasher.run(deviceinfo, method, "flash_lk2nd")
def frontend(args: PmbArgs) -> None:
context = get_context()
action = args.action_flasher
device = context.config.device
deviceinfo = pmb.parse.deviceinfo()
method = args.flash_method or deviceinfo.flash_method
if method == "none" and action in ["boot", "flash_kernel", "flash_rootfs", "flash_lk2nd"]:
logging.info("This device doesn't support any flash method.")
return
if action in ["boot", "flash_kernel"]:
kernel(deviceinfo, method, action == "boot", args.autoinstall)
elif action == "flash_rootfs":
rootfs(deviceinfo, method)
elif action == "flash_vbmeta":
logging.info("(native) flash vbmeta.img with verity disabled flag")
pmb.flasher.run(deviceinfo, method, "flash_vbmeta")
elif action == "flash_dtbo":
logging.info("(native) flash dtbo image")
pmb.flasher.run(deviceinfo, method, "flash_dtbo")
elif action == "flash_lk2nd":
flash_lk2nd(deviceinfo, method)
elif action == "list_flavors":
list_flavors(device)
elif action == "list_devices":
pmb.flasher.run(deviceinfo, method, "list_devices")
elif action == "sideload":
sideload(deviceinfo, method)
......@@ -24,7 +24,16 @@ def check_partition_blacklist(deviceinfo: Deviceinfo, key, value):
)
def run(deviceinfo: Deviceinfo, method: str, action: str, flavor=None):
def run(
deviceinfo: Deviceinfo,
method: str,
action: str,
flavor: str | None = None,
cmdline: str | None = None,
no_reboot: bool | None = None,
partition: str | None = None,
resume: bool | None = None,
) -> None:
pmb.flasher.init(deviceinfo.codename, method)
# Verify action
......@@ -42,9 +51,7 @@ def run(deviceinfo: Deviceinfo, method: str, action: str, flavor=None):
)
# Variable setup
# FIXME: handle argparsing and pass in only the args we need.
args = pmb.helpers.args.please_i_really_need_args()
fvars = pmb.flasher.variables(args, flavor, method)
fvars = pmb.flasher.variables(flavor, method, cmdline, no_reboot, partition, resume)
# vbmeta flasher requires vbmeta partition to be explicitly specified
if action == "flash_vbmeta" and not fvars["$PARTITION_VBMETA"]:
......@@ -69,12 +76,12 @@ def run(deviceinfo: Deviceinfo, method: str, action: str, flavor=None):
"Deviceinfo_reference>"
)
if args.no_reboot and ("flash" not in action or method != "heimdall-bootimg"):
if no_reboot and ("flash" not in action or method != "heimdall-bootimg"):
raise RuntimeError(
"The '--no-reboot' option is only" " supported when flashing with heimall-bootimg."
)
if args.resume and ("flash" not in action or method != "heimdall-bootimg"):
if resume and ("flash" not in action or method != "heimdall-bootimg"):
raise RuntimeError(
"The '--resume' option is only" " supported when flashing with heimall-bootimg."
)
......
......@@ -3,15 +3,21 @@
import pmb.config.pmaports
from pmb.core.chroot import Chroot
from pmb.core.context import get_context
from pmb.types import PmbArgs
def variables(args: PmbArgs, flavor: str, method: str):
def variables(
flavor: str | None,
method: str,
cmdline: str | None,
no_reboot: bool | None,
partition: str | None,
resume: bool | None,
) -> dict[str, str]:
device = get_context().config.device
deviceinfo = pmb.parse.deviceinfo()
_cmdline = deviceinfo.kernel_cmdline or ""
if "cmdline" in args and args.cmdline:
_cmdline = args.cmdline
if cmdline:
_cmdline = cmdline
flash_pagesize = deviceinfo.flash_pagesize
......@@ -54,22 +60,22 @@ def variables(args: PmbArgs, flavor: str, method: str):
_partition_vbmeta = deviceinfo.flash_heimdall_partition_vbmeta or None
_partition_dtbo = deviceinfo.flash_heimdall_partition_dtbo or None
if "partition" in args and args.partition:
if partition:
# Only one operation is done at same time so it doesn't matter
# sharing the arg
_partition_kernel = args.partition
_partition_rootfs = args.partition
_partition_vbmeta = args.partition
_partition_dtbo = args.partition
_partition_kernel = partition
_partition_rootfs = partition
_partition_vbmeta = partition
_partition_dtbo = partition
_dtb = deviceinfo.dtb + ".dtb"
_no_reboot = ""
if getattr(args, "no_reboot", False):
if no_reboot:
_no_reboot = "--no-reboot"
_resume = ""
if getattr(args, "resume", False):
if resume:
_resume = "--resume"
fvars = {
......
......@@ -191,7 +191,7 @@ def chroot(args: PmbArgs) -> None:
# Xauthority
env = {}
if args.xauth:
pmb.chroot.other.copy_xauthority(args)
pmb.chroot.other.copy_xauthority(chroot)
env["DISPLAY"] = os.environ.get("DISPLAY")
env["XAUTHORITY"] = "/home/pmos/.Xauthority"
......@@ -403,10 +403,6 @@ def install(args: PmbArgs) -> None:
pmb.install.install(args)
def flasher(args: PmbArgs) -> None:
pmb.flasher.frontend(args)
def export(args: PmbArgs) -> None:
pmb.export.frontend(args)
......
......@@ -21,7 +21,14 @@ def create_zip(args: PmbArgs, chroot: Chroot, device: str):
flavor = pmb.helpers.frontend._parse_flavor(device)
deviceinfo = pmb.parse.deviceinfo()
method = deviceinfo.flash_method
fvars = pmb.flasher.variables(args, flavor, method)
fvars = pmb.flasher.variables(
flavor,
method,
getattr(args, "cmdline", None),
getattr(args, "no_reboot", None),
getattr(args, "partition", None),
getattr(args, "resume", None),
)
# Install recovery installer package in buildroot
pmb.chroot.apk.install(["postmarketos-android-recovery-installer"], chroot)
......
......@@ -94,11 +94,11 @@ def parse_next_block(path: Path, lines: list[str]) -> ApkindexBlock | None:
return ApkindexBlock(
arch=Arch.from_str(ret["arch"]),
depends=ret["depends"],
origin=ret["origin"],
origin=ret.get("origin"),
pkgname=ret["pkgname"],
provides=ret["provides"],
provider_priority=ret.get("provider_priority"),
timestamp=ret["timestamp"],
timestamp=ret.get("timestamp"),
version=ret["version"],
)
......
......@@ -688,13 +688,14 @@ def arguments_kconfig(subparser):
# "pmbootstrap kconfig edit"
edit = sub.add_parser("edit", help="edit kernel aport config")
edit.add_argument("--arch", choices=arch_choices, dest="arch", type=lambda x: Arch.from_str(x))
edit.add_argument(
edit_ui_chooser = edit.add_mutually_exclusive_group()
edit_ui_chooser.add_argument(
"-x",
dest="xconfig",
action="store_true",
help="use xconfig rather than menuconfig for kernel configuration",
)
edit.add_argument(
edit_ui_chooser.add_argument(
"-n",
dest="nconfig",
action="store_true",
......