asaleh / centos / centpkg

Forked from centos/centpkg 2 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
import centpkg.utils
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

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

    def setup_centos_subparsers(self):
        self.register_do_fork()
        self.register_request_gated_side_tag()
        self.register_check_repo_name()
        self.register_fix_repo_name()

    def register_check_repo_name(self):
        help_msg = 'Check if the repo name is consistent with it\'s folder, repo url and specfile'
        description = textwrap.dedent('''
            Check if the repo name is consistent with it\'s folder, repo url and specfile
        '''.format(self.name))

        repo_checker = self.subparsers.add_parser(
            'checkname',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            help=help_msg,
            description=description)
        repo_checker.set_defaults(command=self.do_repo_checker)

    def do_repo_checker(self):
        spec_name, git_name, dir_name = centpkg.utils.get_project_names()
        if spec_name != dir_name:
            self.log.info(
                "Mistmatch between name of the spec-file {} and the directory {}".format(spec_name, dir_name))
        if spec_name != git_name:
            self.log.info(
                "Mistmatch between name of the spec-file {} and the git-remote {}".format(spec_name, git_name))
        if spec_name == dir_name and spec_name == git_name:
            self.log.info("Specfile, directory and git-remote match.")

    def register_fix_repo_name(self):
        help_msg = 'Check if the repo name is consistent with it\'s folder, repo url and specfile'
        description = textwrap.dedent('''
            Check if the repo name is consistent with it\'s folder, repo url and specfile
        '''.format(self.name))

        repo_checker = self.subparsers.add_parser(
            'fixname',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            help=help_msg,
            description=description)
        repo_checker.set_defaults(command=self.do_repo_fixer)

    def do_repo_fixer(self):
        self.do_repo_checker()
        centpkg.utils.fix_repo()

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

    def register_request_gated_side_tag(self):
        """Register command line parser for subcommand request-gated-side-tag"""
        parser = self.subparsers.add_parser(
            "request-gated-side-tag",
            help="Create a new dynamic gated side tag",
        )
        parser.add_argument("--base-tag", help="name of base tag")
        parser.set_defaults(command=self.request_gated_side_tag)

    def request_gated_side_tag(self):
        self.args.suffix = "stack-gate"
        super(centpkgClient, self).request_side_tag()

    def clone(self):
        super(centpkgClient, self).clone()
        project_dir = centpkg.utils.parse_project_dir(self.args.repo[0])
        centpkg.utils.fix_repo(project_dir)