pmbootstrap status: basic checks for git repos (!1882)

Extend "pmbootstrap status" with checks for all git repositories,
derived from relevant checks in pmb.helpers.git.pull (using shared
code):
* on official branch
* workdir is clean
* tracking proper remote
* up to date

Related: #1829
This commit is contained in:
Oliver Smith 2020-02-12 17:03:42 +01:00 committed by Alexey Min
parent 6977f5f3e5
commit c8526f2fcb
No known key found for this signature in database
GPG Key ID: 0B19D2A65870B448
2 changed files with 112 additions and 1 deletions

View File

@ -41,6 +41,74 @@ def print_git_repos(args):
logging.info("- {} ({})".format(repo, ref))
def print_checks_git_repo(args, repo, details=True):
""" Perform various checks on one checked out git repo.
:param details: if True, print each passing check (this is True by
default for the testsuite)
:returns: status, todo_msg
- status: integer, 0 if all passed, < 0 on failure
- msg_todo: message to help the user resolve the failure """
def log_ok(msg_ok):
if details:
logging.info("[OK ] {}: {}".format(repo, msg_ok))
def log_nok_ret(status, msg_nok, msg_todo):
logging.warning("[NOK] {}: {}".format(repo, msg_nok))
return (status, msg_todo)
# On official branch
path = pmb.helpers.git.get_path(args, repo)
branches = pmb.helpers.git.get_branches_official(args, repo)
ref = pmb.helpers.git.rev_parse(args, path, extra_args=["--abbrev-ref"])
if ref not in branches:
return log_nok_ret(-1, "not on official channel branch",
"consider checking out: " + ", ".join(branches))
log_ok("on official channel branch")
# Workdir clean
if not pmb.helpers.git.clean_worktree(args, path):
return log_nok_ret(-2, "workdir is not clean",
"consider cleaning your workdir")
log_ok("workdir is clean")
# Tracking proper remote
remote_upstream = pmb.helpers.git.get_upstream_remote(args, repo)
branch_upstream = remote_upstream + "/" + ref
remote_ref = pmb.helpers.git.rev_parse(args, path, ref + "@{u}",
["--abbrev-ref"])
if remote_ref != branch_upstream:
return log_nok_ret(-3, "tracking unexpected remote branch",
"consider tracking remote branch '{}' instead of"
" '{}'".format(branch_upstream, remote_ref))
log_ok("tracking proper remote branch '{}'".format(branch_upstream))
# Up to date
ref_branch = pmb.helpers.git.rev_parse(args, path, ref)
ref_branch_upstream = pmb.helpers.git.rev_parse(args, path,
branch_upstream)
if ref_branch != ref_branch_upstream:
return log_nok_ret(-4, "not up to date with remote branch",
"update with 'pmbootstrap pull'")
log_ok("up to date with remote branch")
return (0, "")
def print_checks_git_repos(args, details):
""" Perform various checks on the checked out git repos.
:param details: if True, print each passing check
:returns: list of unresolved checklist items """
ret = []
for repo in pmb.config.git_repos.keys():
path = pmb.helpers.git.get_path(args, repo)
if not os.path.exists(path):
continue
status, todo_msg = print_checks_git_repo(args, repo, details)
if status:
ret += ["{}: {}".format(repo, todo_msg)]
return ret
def print_checks_chroots_outdated(args, details):
""" Check if chroots were zapped recently.
:param details: if True, print each passing check instead of a summary
@ -59,6 +127,7 @@ def print_checks(args, details):
logging.info("*** CHECKS ***")
checklist = []
checklist += print_checks_chroots_outdated(args, details)
checklist += print_checks_git_repos(args, details)
# All OK
if not checklist:

View File

@ -1,10 +1,13 @@
# Copyright 2020 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
""" Test pmb/helpers/status.py """
import os
import pytest
import shutil
import sys
import pmb_test # noqa
import pmb_test
import pmb_test.git
import pmb.config
import pmb.config.workdir
@ -41,3 +44,42 @@ def test_pmbootstrap_status(args, tmpdir):
ret = pmb.helpers.run.user(args, [pmbootstrap, "-w", work, "status"],
check=False)
assert ret == 1
def test_print_checks_git_repo(args, monkeypatch, tmpdir):
""" Test pmb.helpers.status.print_checks_git_repo """
path, run_git = pmb_test.git.prepare_tmpdir(args, monkeypatch, tmpdir)
# Not on official branch
func = pmb.helpers.status.print_checks_git_repo
name_repo = "test"
run_git(["checkout", "-b", "inofficial-branch"])
status, _ = func(args, name_repo)
assert status == -1
# Workdir is not clean
run_git(["checkout", "master"])
shutil.copy(__file__, path + "/test.py")
status, _ = func(args, name_repo)
assert status == -2
os.unlink(path + "/test.py")
# Tracking different remote
status, _ = func(args, name_repo)
assert status == -3
# Let master track origin/master
run_git(["checkout", "-b", "temp"])
run_git(["branch", "-D", "master"])
run_git(["checkout", "-b", "master", "--track", "origin/master"])
# Not up to date
run_git(["commit", "--allow-empty", "-m", "new"], "remote")
run_git(["fetch"])
status, _ = func(args, name_repo)
assert status == -4
# Up to date
run_git(["pull"])
status, _ = func(args, name_repo)
assert status == 0