mrhlpr package

Submodules

mrhlpr.frontend module

Pretty outputs and such.

class mrhlpr.frontend.ActionType(*values)

Bases: str, Enum

NOK = '[NOK]'
OK = '[OK ]'
UNKNOWN = '[???]'
property color: ColorCode
class mrhlpr.frontend.ColorCode(*values)

Bases: str, Enum

ENDC = '\x1b[0m'
OKGREEN = '\x1b[1;32m'
ORANGE = '\x1b[93m'
RED = '\x1b[91m'
mrhlpr.frontend.get_parser() ArgumentParser
mrhlpr.frontend.main() None
mrhlpr.frontend.print_action(msg_type: ActionType, message: str) None
mrhlpr.frontend.print_error(message: str) None
mrhlpr.frontend.print_status(mr_id: int, no_cache: bool = False) None

Print the merge request status. Most info is only visible, when the branch is checked out locally. Always display a checklist of things to do next, in order to get the MR shipped.

Parameters:
  • mr_id – merge request ID

  • no_cache – do not cache the API result for the merge request data

mrhlpr.git module

Low level git functions.

mrhlpr.git.branch_current() str
Returns:

current branch name (if any) or “HEAD”

mrhlpr.git.branch_remote(branch_name: str = 'HEAD') str | None
Returns:

remote name, or None

mrhlpr.git.branches(obj: str = 'refs/heads') list[str]
Returns:

a list of all local branch names

mrhlpr.git.clean_worktree(print_warning: bool = False) bool

Check if there are not modified files in the git dir.

mrhlpr.git.commits_on_top_of(branch_name: str) list[str]
Returns:

list of commit ID strings

mrhlpr.git.get_remote_url(remote: str = 'origin') str | None
Returns:

the remote URL as string, e.g. “https://gitlab.postmarketos.org/postmarketOS/pmaports.git

mrhlpr.git.is_rebased(branch_name: str) bool

Check if the current branch needs to be rebased on a given branch.

mrhlpr.git.push_head(remote: str, branch: str) None

Push HEAD to branch in remote

mrhlpr.git.run(parameters: list[str], env: dict[str, str] | None = None, check: bool = True) str | None

Run a git command.

Parameters:
  • parameters – list of arguments to pass to git

  • env – environment variables passed to the process

  • check – when set to True, raise an exception on exit code not being 0

Returns:

on success: output of the command (last new line removed) on failure: None

mrhlpr.git.sha() str
Returns:

current SHA

mrhlpr.git.topdir() str
Returns:

current branch name (if any) or “HEAD”

mrhlpr.gitlab module

GitLab related functions on top of git.

mrhlpr.gitlab.download_artifacts_zip(api: str, pipeline: PipelineMetadata, no_cache: bool = False) str

Download the job artifacts zip file, with a cache.

Parameters:
  • api – gitlab API url, from parse_git_origin()[“api”]

  • pipeline – information about the pipeline

  • no_cache – download again, even if already cached

Returns:

path to downloaded zip file

mrhlpr.gitlab.parse_git_origin() GitLabOrigin

Parse the origin remote’s URL, so it can easily be used in API calls. When adjusting the output of this function, also adjust mrtest/origin.py.

Returns:

a GitLabOrigin object like the following: api: “https://gitlab.postmarketos.org/api/v4” api_project_id: “postmarketOS%2Fmrhlpr” full: “git@gitlab.postmarketos.org:postmarketOS/mrhlpr.git” project: “postmarketOS” project_id: “postmarketOS/mrhlpr” host: “gitlab.postmarketos.org” username: None

mrhlpr.mr module

High level merge request related functions on top of git, gitlab, mrdb, pipeline.

class mrhlpr.mr.MergeRequestStatus(title: str, source_branch: str, target_branch: str, source: str, source_namespace: str, source_project_id: int, allow_push: bool, state: str)

Bases: object

allow_push: bool
source: str
source_branch: str
source_namespace: str
source_project_id: int
state: str
target_branch: str
title: str
exception mrhlpr.mr.UnknownReleaseError

Bases: ValueError

mrhlpr.mr.checked_out() int
Returns:

checked out MR ID or None

mrhlpr.mr.checkout(mr_id: int, no_cache: bool = False, fetch: bool = False, overwrite_remote: bool = False) None

Add the MR’s source repository as git remote, fetch it and checkout the branch used in the merge request.

Parameters:
  • mr_id – merge request ID

  • no_cache – do not cache the API result for the merge request data

  • fetch – always fetch the source repository

  • overwrite_remote – overwrite URLs of existing remote

mrhlpr.mr.commits_are_signed(commits: list[str]) bool

Check if all given commits are signed.

Parameters:

commits – return value from git.commits_on_top_of()

Returns:

True if all are signed, False otherwise

mrhlpr.mr.commits_follow_format(commits: list[str]) tuple[bool | None, list[Any]]

Check if the commit subjects follow the correct naming format.

Parameters:

commits – return value from git.commits_on_top_of()

Returns:

  • result: True if the commits are formatted correctly, False if something is obviously wrong and None if it is something between

  • subject_err: string with commit hash and explanation of what is wrong with the subject

mrhlpr.mr.commits_have_mr_id(commits: list[str], mr_id: int) bool

Check if all given commits have the MR-ID in the subject.

Parameters:

commits – return value from git.commits_on_top_of()

Returns:

True if the MR-ID is in each subject, False otherwise

mrhlpr.mr.finish(mr_id: int, comment: str | None, no_cache: bool = False, skip_approve: bool = False) None
mrhlpr.mr.fixmsg(mr_id: int, skip_build: bool = False, ignore_count: bool = False, skip_vercheck: bool = False, skip_pipeline: bool = False) None

Add the MR-ID in each commit of the MR.

Parameters:

mr_id – merge request ID

mrhlpr.mr.get_artifacts_repo_urls(mr_id: int, no_cache: bool, origin: GitLabOrigin, alpine_mr: bool) list[str]

Get a list of URLs that can be used as repositories for apk. These URLs contain the apks built as part of the latest job for the host system’s architecture in the given MR.

mrhlpr.mr.get_artifacts_zip(mr_id: int, no_cache: bool, origin: GitLabOrigin) str

Download artifacts from the GitLab API.

Parameters:
  • mr_id – merge request ID

  • no_cache – do not cache the API result for the merge request data

  • origin – gitlab origin information, see gitlab.parse_git_origin()

Returns:

path to downloaded artifacts.zip file

mrhlpr.mr.get_status(mr_id: int, no_cache: bool = False, origin: GitLabOrigin | None = None) MergeRequestStatus

Get merge request related information from the GitLab API. To hack on this, run mrhlpr with -v to get the cached JSON files location. Then you can take a look at the data returned from the API.

Parameters:
  • mr_id – merge request ID

  • no_cache – do not cache the API result for the merge request data

  • origin – gitlab origin information, see gitlab.parse_git_origin()

Returns:

a MergeRequestStatus object like: title: “This is my first merge request” source_branch: “mymr” target_branch: “v20.05” source: “ollieparanoid/mrhlpr” source_namespace: “ollieparanoid” source_project_id: 12345 allow_push: True state: “merged”

mrhlpr.mr.get_url(mr_id: int, origin: GitLabOrigin | None = None) str

Get the URL to the merge request on the GitLab server.

Parameters:
  • mr_id – merge request ID

  • origin – gitlab origin information, see gitlab.parse_git_origin()

Returns:

URL to the merge request

mrhlpr.mr.push(mr_id: int, no_cache: bool = False) None
mrhlpr.mr.run_git_filter_branch(script: str, from_ref: str, mr_id: int | None = None, label: str | None = None) None

mrhlpr.mrdb module

Simple lookup table on disk for local (host, project, branch) to MR ID.

mrhlpr.mrdb.get_value(host: str, project_id: str, branch: str) int | None
Returns:

the MR-ID or None

mrhlpr.mrdb.load() dict[str, dict[str, dict[str, int]]]
Returns:

dict of the loaded lookup table, looks like:

{“gitlab.postmarketos.org”:
{“postmarketOS/pmaports”:
{“sailfish”: 66,

“grate-driver”: 67}}}

mrhlpr.mrdb.set_value(host: str, project_id: str, branch: str, mr_id: int) None

Save the MR-ID for the given host, project_id, branch to the database. The database file gets rewritten from scratch each time, we don’t really write often into it anyway, and this keeps the code simple.

mrhlpr.origin module

Origin information about gitlab instances relevant to mrtest, in the format needed for mrhlpr.gitlab.parse_git_origin().

class mrhlpr.origin.GitLabOrigin(api: str, api_project_id: str, full: str, project: str, project_id: str, host: str, username: str | None)

Bases: object

download_json(pathname: str, no_cache: bool = False) Any

Download and parse JSON from an API, with a cache.

Parameters:
  • pathname – gitlab URL pathname (without the usual prefix)

  • no_cache – download again, even if already cached

Returns:

parsed JSON

mrhlpr.pipeline module

Parse output from gitlab’s pipeline api.

class mrhlpr.pipeline.PipelineMetadata(mr_id: int, no_cache: bool, origin: GitLabOrigin)

Bases: object

property host_arch_job: dict
property project_id: int

mrhlpr.runner module

Verification of gitlab CI runners.

mrhlpr.runner.get_no_state_str(runner: dict[str, bool | int | str]) str

Create a human-readable json string of runner, with information about current state (active or not) removed. :returns: json string

mrhlpr.runner.get_runner_trusted_path(no_state_str: str, mkdir: bool = False) str
Parameters:

runner_no_state_str – as returned by get_no_state_str()

Returns:

path to store that the given runner is trusted

mrhlpr.runner.is_runner_known(no_state_str: str) bool
Parameters:

no_state_str – from get_no_state_str()

mrhlpr.runner.mark_as_known(no_state_str: str) None
Parameters:

no_state_str – from get_no_state_str()

mrhlpr.runner.verify(runner: dict[str, bool | int | str]) None

Verify that a runner is trusted, or ask the user if they want to trust it. Exit if the user does not trust it. :param runner: as returned from the gitlab jobs api:

{“id”: 12270837,

“description”: “4-blue.shared.runners-manager.gitlab.postmarketos.org/default”, “ip_address”: “34.74.35.215”, “active”: true, “paused”: false, “is_shared”: true, “runner_type”: “instance_type”, “name”: “gitlab-runner”, “online”: true, “status”: “online”}

mrhlpr.version module

mrhlpr.version.get_full_version_information() str

Provides a full version string, including an educated guess about whether the program was compiled by mypyc.

mrhlpr.version.is_mypyc_compiled() bool

Attempts to determine whether the program was compiled by mypyc.

Module contents