lrossett / centos / centpkg

Forked from centos/centpkg 3 years ago
Clone
Blob Blame History Raw
'''
    Command line behavior for centpkg
'''
#
# Author(s):
#            Jesse Keating <jkeating@redhat.com>
#            Pat Riehecky <riehecky@fnal.gov>
#            Brian Stinson <bstinson@ksu.edu>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.

from __future__ import print_function

import argparse
import textwrap

from centpkg.utils import config_get_safely, do_add_remote, do_fork
from pyrpkg.cli import cliClient
from pyrpkg import rpkgError
from six.moves.urllib_parse import urlparse


_DEFAULT_API_BASE_URL = 'https://gitlab.com'


class centpkgClient(cliClient):
    def __init__(self, config, name='centpkg'):
        self.DEFAULT_CLI_NAME = name

        super(centpkgClient, self).__init__(config, name)

        self.setup_centos_subparsers()

    def setup_centos_subparsers(self):
        self.register_do_fork()

    def register_do_fork(self):
        help_msg = 'Create a new fork of the current repository'
        distgit_section = '{0}.distgit'.format(self.name)
        # uses default dist-git url in case section is not present
        try:
            distgit_api_base_url = config_get_safely(self.config, distgit_section, "apibaseurl")
        except rpkgError:
            distgit_api_base_url = _DEFAULT_API_BASE_URL
        description = textwrap.dedent('''
            Create a new fork of the current repository

            Before the operation, you need to generate an API token at
            https://{1}/-/profile/personal_access_tokens, select the "api"
            scope and save it in your local user configuration located
            at ~/.config/rpkg/{0}.conf. For example:

                [{0}.distgit]
                token = <api_key_here>

            Below is a basic example of the command to fork a current repository:

                {0} fork
        '''.format(self.name, urlparse(distgit_api_base_url).netloc))

        fork_parser = self.subparsers.add_parser(
            'fork',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            help=help_msg,
            description=description)
        fork_parser.set_defaults(command=self.do_distgit_fork)

    def do_distgit_fork(self):
        """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_token = config_get_safely(self.config, distgit_section, 'token')

        ret, repo_path = do_fork(
            logger=self.log,
            base_url=distgit_api_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}/{1}'.format(
            distgit_api_base_url.rstrip('/'),
            repo_path,
        )

        if ret:
            msg = "Fork of the repository has been created: '{0}'"
        else:
            msg = "Repo '{0}' already exists."
        self.log.info(msg.format(fork_url))

        distgit_remote_base_url = self.config.get(
            '{0}'.format(self.name),
            "gitbaseurl",
            vars={'repo': '{0}/{1}'.format(self.cmd.ns, self.cmd.repo_name)},
        )
        remote_name = repo_path.split('/')[0]

        ret = do_add_remote(
            base_url=distgit_api_base_url,
            remote_base_url=distgit_remote_base_url,
            repo=self.cmd.repo,
            repo_path=repo_path,
            remote_name=remote_name,
        )
        if ret:
            msg = "Adding as remote '{0}'."
        else:
            msg = "Remote with name '{0}' already exists."
        self.log.info(msg.format(remote_name))