mirror of
https://git.centos.org/centos/centpkg.git
synced 2025-02-23 16:22: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
|
import textwrap
|
||||||
|
|
||||||
from centpkg.utils import config_get_safely, do_add_remote, do_fork
|
from centpkg.utils import config_get_safely, do_add_remote, do_fork
|
||||||
|
import centpkg.utils
|
||||||
from pyrpkg.cli import cliClient
|
from pyrpkg.cli import cliClient
|
||||||
from pyrpkg import rpkgError
|
from pyrpkg import rpkgError
|
||||||
from six.moves.urllib_parse import urlparse
|
from six.moves.urllib_parse import urlparse
|
||||||
|
@ -31,6 +32,11 @@ class centpkgClient(cliClient):
|
||||||
def __init__(self, config, name='centpkg'):
|
def __init__(self, config, name='centpkg'):
|
||||||
self.DEFAULT_CLI_NAME = name
|
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)
|
super(centpkgClient, self).__init__(config, name)
|
||||||
|
|
||||||
self.setup_centos_subparsers()
|
self.setup_centos_subparsers()
|
||||||
|
|
|
@ -20,6 +20,7 @@ from requests.exceptions import ConnectionError
|
||||||
from six.moves.configparser import NoOptionError, NoSectionError
|
from six.moves.configparser import NoOptionError, NoSectionError
|
||||||
from six.moves.urllib.parse import quote_plus, urlparse
|
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):
|
def do_fork(logger, base_url, token, repo_name, namespace, cli_name):
|
||||||
"""
|
"""
|
||||||
|
@ -180,6 +181,54 @@ def config_get_safely(config, section, option):
|
||||||
raise
|
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'):
|
def get_repo_name(name, org='rpms'):
|
||||||
"""
|
"""
|
||||||
Try to parse the repository name in case it is a git url.
|
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):
|
if name.startswith(org):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
parsed = '/'.join(name.split('/')[1:])
|
# This is probably a renamed fork, so try to find the fork's parent
|
||||||
repo_name = parsed.split('_')[-1:][0]
|
repo_name = get_canonical_repo_name(dist_git_config, name)
|
||||||
|
|
||||||
return '%s/%s' % (org, repo_name)
|
return '%s/%s' % (org, repo_name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue