mirror of
https://github.com/peridotbuild/pv2.git
synced 2024-12-22 18:58:30 +00:00
185d144567
Adds the importutil module that allows targetting a specific source RPM file and importing and tagging. It aims to keep the same structure of git.centos.org. Other changes: * constants.py: New constants added for git and rpm * error.py: New git and rpm error classes added * fileutil.py: * Add filter_files_inverse (matches everything but the filter) * Add get_magic_file (returns magic data from a file) * Add get_magic_content (returns magic data from data/content) * generic.py: Add safe_encoding to return a urlquote string * processor.py: * Add run_proc_foreground_shell to support shell calls * Add run_proc_no_output_shell to support shell calls * rpmutil.py: * get_rpm_header now supports verify_signature parameter (default false). If set to true and key is not available, raises exception. * Add verify_rpm_signature, which allows local rpm verification without ingesting the whole header into a usable object. * Add add_rpm_key, which enables a user to add a key to the rpm keyring.
157 lines
4.1 KiB
Python
157 lines
4.1 KiB
Python
# -*-:python; coding:utf-8; -*-
|
|
# author: Louis Abel <label@rockylinux.org>
|
|
"""
|
|
Git Utilities and Accessories
|
|
"""
|
|
|
|
import os
|
|
import git as rawgit
|
|
from git import Repo
|
|
from git import exc as gitexc
|
|
from pv2.util import error as err
|
|
|
|
__all__ = [
|
|
'add_all',
|
|
'clone',
|
|
'commit',
|
|
'init',
|
|
'push',
|
|
'tag',
|
|
'lsremote'
|
|
]
|
|
|
|
def add_all(repo):
|
|
"""
|
|
Add all files to repo
|
|
"""
|
|
try:
|
|
repo.git.add(all=True)
|
|
except Exception as exc:
|
|
raise err.GitCommitError('Unable to add files') from exc
|
|
|
|
def checkout(repo, branch: str, orphan: bool = False):
|
|
"""
|
|
Checkout a branch for some reason or another
|
|
|
|
Only set orphan to true if this is a brand new branch that never existed
|
|
and you want to avoid tracking from another branch.
|
|
"""
|
|
|
|
# We are NOT using repo.heads.NAME.checkout() because it does not play
|
|
# very well with branches that have dashes in the name
|
|
try:
|
|
if orphan:
|
|
repo.git.checkout('--orphan', branch)
|
|
else:
|
|
repo.git.checkout(branch)
|
|
except repo.git.exc.CheckoutError as exc:
|
|
raise err.GitCheckoutError('Unable to checkout that branch.') from exc
|
|
|
|
def clone(
|
|
git_url_path: str,
|
|
repo_name: str,
|
|
to_path: str = None,
|
|
branch: str = None
|
|
):
|
|
"""
|
|
clone a repo. if branch is None, it will just clone the repo in general and
|
|
you'll be expected to checkout.
|
|
"""
|
|
if not to_path:
|
|
clone_path = f'/var/tmp/{repo_name}'
|
|
|
|
try:
|
|
repo = Repo.clone_from(
|
|
url=git_url_path,
|
|
to_path=clone_path,
|
|
branch=branch
|
|
)
|
|
# pylint: disable=no-member
|
|
except gitexc.CommandError as exc:
|
|
raise err.GitInitError(f'Repo could not be cloned: {exc.stderr}') from exc
|
|
|
|
return repo
|
|
|
|
def commit(repo, message: str):
|
|
"""
|
|
create a commit message (no tag)
|
|
"""
|
|
try:
|
|
repo.index.commit(message=message)
|
|
# pylint: disable=no-member
|
|
except gitexc.CommandError as exc:
|
|
raise err.GitCommitError('Unable to create commit') from exc
|
|
|
|
def init(
|
|
git_url_path: str,
|
|
repo_name: str,
|
|
to_path: str = None,
|
|
branch: str = None
|
|
):
|
|
"""
|
|
init a git repo
|
|
"""
|
|
path_way = to_path
|
|
if not to_path:
|
|
path_way = f'/var/tmp/{repo_name}'
|
|
|
|
if os.path.exists(path_way):
|
|
raise err.GenericError(f'File or directory already exists: {path_way}')
|
|
|
|
try:
|
|
repo = Repo.init(path_way, initial_branch=branch)
|
|
repo.create_remote(
|
|
name='origin',
|
|
url=git_url_path
|
|
)
|
|
# pylint: disable=no-member
|
|
except gitexc.CommandError as exc:
|
|
raise err.GitInitError('Could not generate git repository') from exc
|
|
|
|
return repo
|
|
|
|
|
|
def push(repo, ref=None):
|
|
"""
|
|
push what we want
|
|
|
|
if ref is not none (aka an object), we'll push the commit first and
|
|
then the tag ref, this way the commits and tags are in sync.
|
|
"""
|
|
active_branch = f'{repo.active_branch.name}:{repo.active_branch.name}'
|
|
try:
|
|
if ref:
|
|
repo.remote('origin').push(active_branch).raise_if_error()
|
|
repo.remote('origin').push(ref).raise_if_error()
|
|
else:
|
|
repo.remote('origin').push(active_branch).raise_if_error()
|
|
# pylint: disable=no-member
|
|
except gitexc.CommandError as exc:
|
|
raise err.GitPushError('Unable to push commit to remote') from exc
|
|
|
|
def tag(repo, tag_name:str, message: str):
|
|
"""
|
|
make a tag with message
|
|
"""
|
|
ref = repo.create_tag(tag_name, message=message)
|
|
return ref
|
|
|
|
def lsremote(url):
|
|
"""
|
|
Helps check if a repo exists, and if it does, return references. If not,
|
|
return None and assume it doesn't exist.
|
|
"""
|
|
remote_refs = {}
|
|
git_cmd = rawgit.cmd.Git()
|
|
try:
|
|
git_cmd.ls_remote(url)
|
|
# pylint: disable=no-member
|
|
except gitexc.CommandError as exc:
|
|
print(f'Repo does not exist or is not accessible: {exc.stderr}')
|
|
return None
|
|
|
|
for ref in git_cmd.ls_remote(url).split('\n'):
|
|
hash_ref_list = ref.split('\t')
|
|
remote_refs[hash_ref_list[1]] = hash_ref_list[0]
|
|
return remote_refs
|