#406 fedpkg fork checks if the fork already exists
Merged 3 years ago by onosek. Opened 3 years ago by onosek.
onosek/fedpkg fork_already  into  master

file modified
+37 -11
@@ -30,10 +30,11 @@ 

  

  from fedpkg.bugzilla import BugzillaClient

  from fedpkg.utils import (assert_new_tests_repo, assert_valid_epel_package,

-                           config_get_safely, do_fork, expand_release,

-                           get_dist_git_url, get_fedora_release_state,

-                           get_release_branches, get_stream_branches, is_epel,

-                           new_pagure_issue, sl_list_to_dict, verify_sls)

+                           config_get_safely, do_add_remote, do_fork,

+                           expand_release, get_dist_git_url,

+                           get_fedora_release_state, get_release_branches,

+                           get_stream_branches, is_epel, new_pagure_issue,

+                           sl_list_to_dict, verify_sls)

  from pyrpkg import rpkgError

  from pyrpkg.cli import cliClient

  
@@ -1094,7 +1095,10 @@ 

                  )

  

      def do_distgit_fork(self):

-         """create fork of the distgit repository"""

+         """create fork of the distgit repository

+         That includes creating fork itself using API call and then adding

+         remote tracked repository

+         """

          distgit_section = '{0}.distgit'.format(self.name)

          distgit_api_base_url = config_get_safely(self.config, distgit_section, "apibaseurl")

          distgit_remote_base_url = self.config.get(
@@ -1104,19 +1108,41 @@ 

          )

          distgit_token = config_get_safely(self.config, distgit_section, 'token')

  

-         fork_url = do_fork(

+         ret = do_fork(

              base_url=distgit_api_base_url,

-             remote_base_url=distgit_remote_base_url,

              token=distgit_token,

+             repo_name=self.cmd.repo_name,

+             namespace=self.cmd.ns,

+             cli_name=self.name,

+         )

+ 

+         # assemble url of the repo in web browser

+         fork_url = '{0}/fork/{1}/{2}/{3}'.format(

+             distgit_api_base_url.rstrip('/'),

+             self.cmd.user,

+             self.cmd.ns,

+             self.cmd.repo_name,

+         )

+ 

+         if ret:

+             msg = "Fork of the repository has been created: '{0}'"

+         else:

+             msg = "Repo '{0}' already exists."

+         self.log.info(msg.format(fork_url))

+ 

+         ret = do_add_remote(

+             base_url=distgit_api_base_url,

+             remote_base_url=distgit_remote_base_url,

              username=self.cmd.user,

              repo=self.cmd.repo,

              repo_name=self.cmd.repo_name,

              namespace=self.cmd.ns,

-             cli_name=self.name,

          )

-         if fork_url:

-             msg = "Fork of the repository has been created: {0}"

-             self.log.info(msg.format(fork_url))

+         if ret:

+             msg = "Adding as remote '{0}'."

+         else:

+             msg = "Remote with name '{0}' already exists."

+         self.log.info(msg.format(self.cmd.user))

  

      def create_buildroot_override(self):

          """Create a buildroot override in Bodhi"""

file modified
+38 -20
@@ -135,32 +135,19 @@ 

          url.rstrip('/'), rv.json()['issue']['id'])

  

  

- def do_fork(base_url, remote_base_url, token, username, repo, repo_name,

-             namespace, cli_name):

+ def do_fork(base_url, token, repo_name, namespace, cli_name):

      """

      Creates a fork of the project.

      :param base_url: a string of the URL repository

-     :param remote_base_url: a string of the remote tracked repository

      :param token: a string of the API token that has rights to make a fork

-     :param username: a string of the (FAS) user name

-     :param repo: object, current project git repository

      :param repo_name: a string of the repository name

      :param namespace: a string determines a type of the repository

      :param cli_name: string of the CLI's name (e.g. fedpkg)

-     :return: a string of the URL to the created fork in the UI

+     :return: a bool; True when fork was created, False when already exists

      """

      api_url = '{0}/api/0'.format(base_url.rstrip('/'))

      fork_url = '{0}/fork'.format(api_url)

  

-     parsed_url = urlparse(remote_base_url)

-     remote_url = '{0}://{1}/forks/{2}/{3}/{4}.git'.format(

-         parsed_url.scheme,

-         parsed_url.netloc,

-         username,

-         namespace,

-         repo_name,

-     )

- 

      headers = {

          'Authorization': 'token {0}'.format(token),

          'Accept': 'application/json',
@@ -187,6 +174,10 @@ 

              rv_error = rv.json().get('error')

          except ValueError:

              rv_error = rv.text

+ 

+         if re.search(r"Repo .+ already exists", rv_error, re.IGNORECASE):

+             return False

+ 

          # show hint for expired token

          if re.search(r"Invalid or expired token", rv_error, re.IGNORECASE):

              base_error_msg += '\nFor invalid or expired token refer to ' \
@@ -194,16 +185,43 @@ 

                  'configuration.'.format(cli_name)

          raise rpkgError(base_error_msg.format(rv_error))

  

+     return True

+ 

+ 

+ def do_add_remote(base_url, remote_base_url, username, repo, repo_name,

+                   namespace):

+     """

+     Adds remote tracked repository

+     :param base_url: a string of the URL repository

+     :param remote_base_url: a string of the remote tracked repository

+     :param username: a string of the (FAS) user name

+     :param repo: object, current project git repository

+     :param repo_name: a string of the repository name

+     :param namespace: a string determines a type of the repository

+     :return: a bool; True if remote was created, False when already exists

+     """

+     parsed_url = urlparse(remote_base_url)

+     remote_url = '{0}://{1}/forks/{2}/{3}/{4}.git'.format(

+         parsed_url.scheme,

+         parsed_url.netloc,

+         username,

+         namespace,

+         repo_name,

+     )

+ 

+     # check already existing remote

+     for remote in repo.remotes:

+         if remote.name == username:

+             return False

+ 

      try:

+         # create remote with username as its name

          repo.create_remote(username, url=remote_url)

      except git.exc.GitCommandError as e:

-         error_msg = "Fork was created; during create remote:\n  {0}\n  {1}".format(

+         error_msg = "During create remote:\n  {0}\n  {1}".format(

              " ".join(e.command), e.stderr)

          raise rpkgError(error_msg)

- 

-     # create and return url of the repo in web browser

-     return '{0}/fork/{1}/{2}/{3}'.format(

-         base_url.rstrip('/'), username, namespace, repo_name)

+     return True

  

  

  def get_release_branches(server_url):

When the fork already exists, method will try to add remote tracked
repository.

Fixes: #392
JIRA: RHELCMP-381
Signed-off-by: Ondrej Nosek onosek@redhat.com

I didn't test it, but the code looks reasonable to me.

Pull-Request has been merged by onosek

3 years ago