mirror of
https://git.centos.org/centos/centpkg.git
synced 2025-02-23 08:12:55 +00:00
Improve package name detection
Look up the parent repo of forks for the package name. This requires the user to have a valid Gitlab API token in their configuration. It will raise an error if it takes this path and does not have permission. Note that when https://gitlab.com/gitlab-org/gitlab/-/issues/361952 is fixed in Gitlab, the token will not be required in this case. Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
This commit is contained in:
parent
5cc23ef01e
commit
5a7f92eab3
2 changed files with 57 additions and 2 deletions
|
@ -19,6 +19,7 @@ import argparse
|
|||
import textwrap
|
||||
|
||||
from centpkg.utils import config_get_safely, do_add_remote, do_fork
|
||||
import centpkg.utils
|
||||
from pyrpkg.cli import cliClient
|
||||
from pyrpkg import rpkgError
|
||||
from six.moves.urllib_parse import urlparse
|
||||
|
@ -31,6 +32,11 @@ class centpkgClient(cliClient):
|
|||
def __init__(self, config, name='centpkg'):
|
||||
self.DEFAULT_CLI_NAME = name
|
||||
|
||||
# Save the config for utilities such as get_repo_name()
|
||||
centpkg.utils.dist_git_config = config
|
||||
centpkg.utils.dist_git_config.add_section('__default')
|
||||
centpkg.utils.dist_git_config.set('__default', 'cli_name', name)
|
||||
|
||||
super(centpkgClient, self).__init__(config, name)
|
||||
|
||||
self.setup_centos_subparsers()
|
||||
|
|
|
@ -20,6 +20,7 @@ from requests.exceptions import ConnectionError
|
|||
from six.moves.configparser import NoOptionError, NoSectionError
|
||||
from six.moves.urllib.parse import quote_plus, urlparse
|
||||
|
||||
dist_git_config = None
|
||||
|
||||
def do_fork(logger, base_url, token, repo_name, namespace, cli_name):
|
||||
"""
|
||||
|
@ -180,6 +181,54 @@ def config_get_safely(config, section, option):
|
|||
raise
|
||||
|
||||
|
||||
def get_canonical_repo_name(config, repo_url):
|
||||
"""
|
||||
Check whether the current repo is a fork and if so, retrieve the parent
|
||||
fork to get the proper name.
|
||||
"""
|
||||
|
||||
# Look up the repo and query for forked_from_project
|
||||
cli_name = config_get_safely(dist_git_config, '__default', 'cli_name')
|
||||
distgit_section = '{0}.distgit'.format(cli_name)
|
||||
distgit_api_base_url = config_get_safely(dist_git_config, distgit_section, "apibaseurl")
|
||||
|
||||
# Make sure the fork comes from the same Gitlab instance
|
||||
parsed_repo_url = urlparse(repo_url)
|
||||
parsed_base_url = urlparse(distgit_api_base_url)
|
||||
|
||||
try:
|
||||
distgit_token = config_get_safely(dist_git_config, distgit_section, 'token')
|
||||
|
||||
api_url = '{0}/api/v4'.format(distgit_api_base_url.rstrip('/'))
|
||||
project_url = '{0}/projects/{1}'.format(api_url, quote_plus(parsed_repo_url.path.lstrip('/')))
|
||||
|
||||
headers = {
|
||||
'PRIVATE-TOKEN': distgit_token,
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
rv = requests.get(project_url, headers=headers)
|
||||
rv.raise_for_status()
|
||||
|
||||
# Extract response json for debugging
|
||||
rv_json = rv.json()
|
||||
|
||||
canonical_repo_name = rv_json['forked_from_project']['name']
|
||||
except KeyError as e:
|
||||
# There was no 'forked_from_project' key, likely meaning the
|
||||
# user lacked permissions to read the API. Usually this means
|
||||
# they haven't supplied a token or it is expired.
|
||||
raise rpkgError("Insufficient Gitlab API permissions. Missing token?")
|
||||
|
||||
except Exception as e:
|
||||
# For any other exception, just fall back to using the last segment
|
||||
# of the URL path.
|
||||
canonical_repo_name = parsed_repo_url.path.split('/')[-1]
|
||||
|
||||
# Chop off a trailing .git if any
|
||||
return canonical_repo_name.rsplit('.git', 1)[0]
|
||||
|
||||
def get_repo_name(name, org='rpms'):
|
||||
"""
|
||||
Try to parse the repository name in case it is a git url.
|
||||
|
@ -202,7 +251,7 @@ def get_repo_name(name, org='rpms'):
|
|||
if name.startswith(org):
|
||||
return name
|
||||
|
||||
parsed = '/'.join(name.split('/')[1:])
|
||||
repo_name = parsed.split('_')[-1:][0]
|
||||
# This is probably a renamed fork, so try to find the fork's parent
|
||||
repo_name = get_canonical_repo_name(dist_git_config, name)
|
||||
|
||||
return '%s/%s' % (org, repo_name)
|
||||
|
|
Loading…
Add table
Reference in a new issue