| |
@@ -20,6 +20,7 @@
|
| |
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 @@
|
| |
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 @@
|
| |
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)
|
| |
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