pmbootstrap init: ask for release channel (MR 1912)
Ask for release channel and switch pmaports branch to the related branch defined in channels.cfg. Store in pmbootstrap.cfg whether the user chose a channel (boolean). If the user did not choose a channel yet, suggest the recommended channel from channels.cfg (currently "edge").
This commit is contained in:
parent
261e8595ad
commit
17f3b3c2f0
|
@ -42,6 +42,7 @@ config_keys = ["aports",
|
|||
"device",
|
||||
"extra_packages",
|
||||
"hostname",
|
||||
"is_default_channel",
|
||||
"jobs",
|
||||
"kernel",
|
||||
"keymap",
|
||||
|
@ -61,6 +62,7 @@ defaults = {
|
|||
"alpine_version": "edge", # alternatively: latest-stable
|
||||
"aports": "$WORK/cache_git/pmaports",
|
||||
"ccache_size": "5G",
|
||||
"is_default_channel": True,
|
||||
# aes-xts-plain64 would be better, but this is not supported on LineageOS
|
||||
# kernel configs
|
||||
"cipher": "aes-cbc-plain64",
|
||||
|
|
|
@ -72,6 +72,39 @@ def ask_for_work_path(args):
|
|||
" inside it! Please try again.")
|
||||
|
||||
|
||||
def ask_for_channel(args):
|
||||
""" Ask for the postmarketOS release channel. The channel dictates, which
|
||||
pmaports branch pmbootstrap will check out, and which repository URLs
|
||||
will be used when initializing chroots.
|
||||
:returns: channel name (e.g. "edge", "stable") """
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(args)
|
||||
count = len(channels_cfg["channels"])
|
||||
|
||||
# List channels
|
||||
logging.info("Choose the postmarketOS release channel.")
|
||||
logging.info(f"Available ({count}):")
|
||||
for channel, channel_data in channels_cfg["channels"].items():
|
||||
logging.info(f"* {channel}: {channel_data['description']}")
|
||||
|
||||
# Default for first run: "recommended" from channels.cfg
|
||||
# Otherwise, if valid: channel from pmaports.cfg of current branch
|
||||
# The actual channel name is not saved in pmbootstrap.cfg, because then we
|
||||
# would need to sync it with what is checked out in pmaports.git.
|
||||
default = pmb.config.pmaports.read_config(args)["channel"]
|
||||
choices = channels_cfg["channels"].keys()
|
||||
if args.is_default_channel or default not in choices:
|
||||
default = channels_cfg["meta"]["recommended"]
|
||||
|
||||
# Ask until user gives valid channel
|
||||
while True:
|
||||
ret = pmb.helpers.cli.ask(args, "Channel", None, default,
|
||||
complete=choices)
|
||||
if ret in choices:
|
||||
return ret
|
||||
logging.fatal("ERROR: Invalid channel specified, please type in one"
|
||||
" from the list above.")
|
||||
|
||||
|
||||
def ask_for_ui(args):
|
||||
ui_list = pmb.helpers.ui.list(args)
|
||||
logging.info("Available user interfaces (" +
|
||||
|
@ -365,6 +398,11 @@ def frontend(args):
|
|||
# Clone pmaports
|
||||
pmb.config.pmaports.init(args)
|
||||
|
||||
# Choose release channel, possibly switch pmaports branch
|
||||
channel = ask_for_channel(args)
|
||||
pmb.config.pmaports.switch_to_channel_branch(args, channel)
|
||||
cfg["pmbootstrap"]["is_default_channel"] = "False"
|
||||
|
||||
# Device
|
||||
device, device_exists, kernel, nonfree = ask_for_device(args)
|
||||
cfg["pmbootstrap"]["device"] = device
|
||||
|
|
|
@ -124,3 +124,38 @@ def init(args):
|
|||
clone(args)
|
||||
symlink(args)
|
||||
read_config(args)
|
||||
|
||||
|
||||
def switch_to_channel_branch(args, channel_new):
|
||||
""" Checkout the channel's branch in pmaports.git.
|
||||
:channel_new: channel name (e.g. "edge", "stable")
|
||||
:returns: True if another branch was checked out, False otherwise """
|
||||
# Check current pmaports branch channel
|
||||
channel_current = read_config(args)["channel"]
|
||||
if channel_current == channel_new:
|
||||
return False
|
||||
|
||||
# List current and new branches/channels
|
||||
channels_cfg = pmb.helpers.git.parse_channels_cfg(args)
|
||||
branch_new = channels_cfg["channels"][channel_new]["branch_pmaports"]
|
||||
branch_current = pmb.helpers.git.rev_parse(args, args.aports,
|
||||
extra_args=["--abbrev-ref"])
|
||||
logging.info(f"Currently checked out branch '{branch_current}' of"
|
||||
f" pmaports.git is on channel '{channel_current}'.")
|
||||
logging.info(f"Switching to branch '{branch_new}' on channel"
|
||||
f" '{channel_new}'...")
|
||||
|
||||
# Attempt to switch branch (git gives a nice error message, mentioning
|
||||
# which files need to be committed/stashed, so just pass it through)
|
||||
if pmb.helpers.run.user(args, ["git", "checkout", branch_new],
|
||||
args.aports, "interactive", check=False):
|
||||
raise RuntimeError("Failed to switch branch. Go to your pmaports and"
|
||||
" fix what git complained about, then try again: "
|
||||
f"{args.aports}")
|
||||
|
||||
# Invalidate all caches
|
||||
pmb.helpers.args.add_cache(args)
|
||||
|
||||
# Verify pmaports.cfg on new branch
|
||||
read_config(args)
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
# Copyright 2020 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
""" Test pmb/config/pmaports.py """
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
import pmb_test
|
||||
import pmb_test.const
|
||||
import pmb_test.git
|
||||
import pmb.config
|
||||
import pmb.config.workdir
|
||||
import pmb.config.pmaports
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def args(request):
|
||||
import pmb.parse
|
||||
cfg = f"{pmb_test.const.testdata}/channels.cfg"
|
||||
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = args.work + "/log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
request.addfinalizer(args.logfd.close)
|
||||
return args
|
||||
|
||||
|
||||
def test_switch_to_channel_branch(args, monkeypatch, tmpdir):
|
||||
path, run_git = pmb_test.git.prepare_tmpdir(args, monkeypatch, tmpdir)
|
||||
args.aports = path
|
||||
|
||||
# Pretend to have channel=edge in pmaports.cfg
|
||||
def read_config(args):
|
||||
return {"channel": "edge"}
|
||||
monkeypatch.setattr(pmb.config.pmaports, "read_config", read_config)
|
||||
|
||||
# Success: Channel does not change
|
||||
func = pmb.config.pmaports.switch_to_channel_branch
|
||||
assert func(args, "edge") is False
|
||||
|
||||
# Fail: git error (could be any error, but here: branch does not exist)
|
||||
with pytest.raises(RuntimeError) as e:
|
||||
func(args, "stable")
|
||||
assert str(e.value).startswith("Failed to switch branch")
|
||||
|
||||
# Success: switch channel and change branch
|
||||
run_git(["checkout", "-b", "v20.05"])
|
||||
run_git(["checkout", "master"])
|
||||
assert func(args, "stable") is True
|
||||
branch = pmb.helpers.git.rev_parse(args, path, extra_args=["--abbrev-ref"])
|
||||
assert branch == "v20.05"
|
|
@ -16,7 +16,8 @@ import pmb.helpers.logging
|
|||
@pytest.fixture
|
||||
def args(tmpdir, request):
|
||||
import pmb.parse
|
||||
sys.argv = ["pmbootstrap.py", "init"]
|
||||
cfg = f"{pmb_test.const.testdata}/channels.cfg"
|
||||
sys.argv = ["pmbootstrap.py", "--config-channels", cfg, "init"]
|
||||
args = pmb.parse.arguments()
|
||||
args.log = args.work + "/log_testsuite.txt"
|
||||
pmb.helpers.logging.init(args)
|
||||
|
@ -287,3 +288,8 @@ def test_questions_hostname(args, monkeypatch):
|
|||
# Device name: empty string
|
||||
fake_answers(monkeypatch, [device])
|
||||
assert func(args, device) == ""
|
||||
|
||||
|
||||
def test_questions_channel(args, monkeypatch):
|
||||
fake_answers(monkeypatch, ["invalid-channel", "stable"])
|
||||
assert pmb.config.init.ask_for_channel(args) == "stable"
|
||||
|
|
Loading…
Reference in New Issue