pmb.helpers.git: parse channels.cfg (MR 1912)

Prepare to base postmarketOS on Alpine stable by parsing the new
channels.cfg file in pmaports.git, that describes which channel
needs which branches and mirror dirs from postmarketOS and Alpine.

Use the information in pmb.helpers.git.get_branches_official() first,
more is coming in follow-up commits.

Read the file from origin/master, so we get the latest fetched version
even if the last checked out master branch is not up-to-date (think of
currently checked out release branch instead of master, master will
never be updated to point to latest origin/master). Allow to override
the file with a new --config-channels parameter.

Related: https://postmarketos.org/channels.cfg
This commit is contained in:
Oliver Smith 2020-02-27 23:04:38 +01:00
parent ed16a9d080
commit c616874443
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
5 changed files with 102 additions and 5 deletions

View File

@ -3,6 +3,7 @@
import copy
import os
import pmb.config
import pmb.helpers.git
""" This file constructs the args variable, which is passed to almost all
functions in the pmbootstrap code base. Here's a listing of the kind of
@ -131,7 +132,8 @@ def add_cache(args):
"find_aport": {},
"pmb.helpers.package.depends_recurse": {},
"pmb.helpers.package.get": {},
"pmb.helpers.repo.update": repo_update})
"pmb.helpers.repo.update": repo_update,
"pmb.helpers.git.parse_channels_cfg": {}})
def add_deviceinfo(args):
@ -162,6 +164,8 @@ def init(args):
"pull", "shutdown", "zap"]:
pmb.config.pmaports.read_config_into_args(args)
add_deviceinfo(args)
pmb.helpers.git.parse_channels_cfg(args)
return args

View File

@ -1,5 +1,6 @@
# Copyright 2020 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import configparser
import logging
import os
import time
@ -100,12 +101,71 @@ def get_upstream_remote(args, name_repo):
" repository: {}".format(name_repo, url, path))
def parse_channels_cfg(args):
""" Parse channels.cfg from pmaports.git, origin/master branch.
Reference: https://postmarketos.org/channels.cfg
:returns: dict like: {"meta": {"recommended": "edge"},
"channels": {"edge": {"description": ...,
"branch_pmaports": ...,
"branch_aports": ...,
"mirrordir_alpine": ...},
...}} """
# Cache during one pmbootstrap run
cache_key = "pmb.helpers.git.parse_channels_cfg"
if args.cache[cache_key]:
return args.cache[cache_key]
# Read with configparser
cfg = configparser.ConfigParser()
if args.config_channels:
cfg.read([args.config_channels])
else:
remote = get_upstream_remote(args, "pmaports")
command = ["git", "show", f"{remote}/master:channels.cfg"]
stdout = pmb.helpers.run.user(args, command, args.aports,
output_return=True, check=False)
try:
cfg.read_string(stdout)
except configparser.MissingSectionHeaderError:
logging.info("NOTE: fix this by fetching your pmaports.git, e.g."
" with 'pmbootstrap pull'")
raise RuntimeError("Failed to read channels.cfg from"
f" '{remote}/master' branch of your local"
" pmaports clone")
# Meta section
ret = {"channels": {}}
ret["meta"] = {"recommended": cfg.get("channels.cfg", "recommended")}
# Channels
for channel in cfg.sections():
if channel == "channels.cfg":
continue # meta section
ret["channels"][channel] = {}
for key in ["description", "branch_pmaports", "branch_aports",
"mirrordir_alpine"]:
value = cfg.get(channel, key)
ret["channels"][channel][key] = value
args.cache[cache_key] = ret
return ret
def get_branches_official(args, name_repo):
""" Get all branches that point to official release channels.
:returns: list of supported branches, e.g. ["master", "3.11"] """
# More sophisticated logic to figure out the branches will be added soon:
# https://gitlab.com/postmarketOS/postmarketos/issues/11
return ["master"]
# This functions gets called with pmaports and aports_upstream, because
# both are displayed in "pmbootstrap status". But it only makes sense
# to display pmaports there, related code will be refactored soon (#1903).
if name_repo != "pmaports":
return ["master"]
channels_cfg = parse_channels_cfg(args)
ret = []
for channel, channel_data in channels_cfg["channels"].items():
ret.append(channel_data["branch_pmaports"])
return ret
def pull(args, name_repo):

View File

@ -342,6 +342,9 @@ def arguments():
default=pmb.config.defaults["config"],
help="path to pmbootstrap.cfg file (default in"
" ~/.config/)")
parser.add_argument("--config-channels",
help="path to channels.cfg (which is by default"
" read from pmaports.git, origin/master branch)")
parser.add_argument("-d", "--port-distccd", dest="port_distccd")
parser.add_argument("-mp", "--mirror-pmOS", dest="mirrors_postmarketos",
help="postmarketOS mirror, disable with: -mp='',"

View File

@ -7,6 +7,7 @@ import shutil
import time
import pmb_test # noqa
import pmb_test.const
import pmb_test.git
import pmb.helpers.git
import pmb.helpers.logging
@ -16,7 +17,8 @@ import pmb.helpers.run
@pytest.fixture
def args(request):
import pmb.parse
sys.argv = ["pmbootstrap", "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)
@ -108,6 +110,19 @@ def test_get_upstream_remote(args, monkeypatch, tmpdir):
assert func(args, name_repo) == "hello"
def test_parse_channels_cfg(args):
exp = {"meta": {"recommended": "edge"},
"channels": {"edge": {"description": "Rolling release channel",
"branch_pmaports": "master",
"branch_aports": "master",
"mirrordir_alpine": "edge"},
"stable": {"description": "For workgroups",
"branch_pmaports": "v20.05",
"branch_aports": "3.11-stable",
"mirrordir_alpine": "v3.11"}}}
assert pmb.helpers.git.parse_channels_cfg(args) == exp
def test_pull_non_existing(args):
assert pmb.helpers.git.pull(args, "non-existing-repo-name") == 1

15
test/testdata/channels.cfg vendored Normal file
View File

@ -0,0 +1,15 @@
# Reference: https://postmarketos.org/channels.cfg
[channels.cfg]
recommended=edge
[edge]
description=Rolling release channel
branch_pmaports=master
branch_aports=master
mirrordir_alpine=edge
[stable]
description=For workgroups
branch_pmaports=v20.05
branch_aports=3.11-stable
mirrordir_alpine=v3.11