#63 Improve package name detection
Merged 2 years ago by tdawson. Opened 2 years ago by sgallagh.
centos/ sgallagh/centpkg fork_parent  into  develop

file modified
+6
@@ -19,6 +19,7 @@ 

  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 @@ 

      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()

file modified
+51 -2
@@ -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

Is there a centpkg issue that states what the bug is?
Since I don't know what the bug this is fixing, I'm not sure if this fixes it.

The status quo is that centpkg attempts to determine the package name by the last part of the default push URL. This works fine if the default push is to the main dist-git or a fork that was made with centpkg fork (that's what the parsed.split() does), but if the fork is created in any other format, it breaks and assumes the wrong package name.

This change queries for the actual origin of the fork instead.

Pull-Request has been merged by tdawson

2 years ago