#68 Commands to fix-up repository with mismatched name to work around #64
Closed a year ago by tdawson. Opened 2 years ago by asaleh.
centos/ asaleh/centpkg fixup_repo  into  develop

file modified
+48
@@ -44,6 +44,49 @@ 

      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'
@@ -138,3 +181,8 @@ 

      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) 

\ No newline at end of file

file modified
+52
@@ -10,6 +10,8 @@ 

  # option) any later version.  See http://www.gnu.org/copyleft/gpl.html for

  # the full text of the license.

  

+ import os

+ from pathlib import Path

  import re

  import json

  
@@ -140,6 +142,56 @@ 

          raise rpkgError(error_msg)

      return True

  

+ def get_names_from_specs(specdir=None):

+     prev_cwd = Path.cwd()

+     if specdir:

+         os.chdir(specdir)

+     try:

+         return [f[:-5] for f in os.listdir() if f.endswith('.spec')]

+     except ValueError as e:

+         raise ValueError("Didn't find source file with name.")

+     finally:

+         os.chdir(prev_cwd)

+ 

+ def get_names_from_git(gitdir=None):

+     prev_cwd = Path.cwd()

+     return  list(Path(urlparse(u).path).with_suffix('').name

+         for r in git.Repo(gitdir or Path.cwd()).remotes

+         for u in r.urls if "redhat" in u)

+ 

+ def reset_git_origin(old_name, new_name, gitdir=None):

+     for r in git.Repo(gitdir or Path.cwd()).remotes:

+         if r.name == 'origin':

+             current_url = r.url

+             new_url = current_url.replace(old_name, new_name)

+             r.set_url(new_url)

+ 

+ def parse_project_dir(repo):

+     return Path(repo).with_suffix('').name

+ 

+ def fix_repo(project_dir=None):

+     path = Path(project_dir) if project_dir else Path.cwd()

+     spec_name, git_name, dir_name = get_project_names(path)

+     if spec_name != git_name:

+         #self.log.info("Changing the git-remote {} to match {}".format(git_name, spec_name))

+         reset_git_origin(git_name,spec_name,path)

+     if spec_name != dir_name:

+         #self.log.info("Changing the directory {} to match the specfile {}.spec".format(dir_name, spec_name))

+         os.rename(path,path.parent / spec_name)

+ 

+ def get_project_names(projectdir=None):

+     cwd = Path(projectdir) if projectdir else Path.cwd()

+     spec_names = get_names_from_specs(cwd)

+     git_names = get_names_from_git(cwd)

+     dir_name = cwd.name

+     lcase_names = set(s.lower() for s in spec_names).intersection(set(s.lower() for s in git_names))

+     try:

+         [spec_name] = [s for s in spec_names if s.lower() in lcase_names]

+         [git_name,*_] = [s for s in git_names if s.lower() in lcase_names]

+         return spec_name, git_name, dir_name

+     except ValueError as e:

+         raise ValueError("Instead of a single project name found {}".format(spec_names))

+ 

  

  def config_get_safely(config, section, option):

      """

There is an assumption that the name of the directory, repository and package as described in the specfile is the same.
This assumption can be easily broken when checking out the package from gitlab, where repositort-names are not case sensitive.
This code adds a workaround, that checks the three names are matching:
- directory name
- name of the specfile
- the git origin remote
and if not, uses the name of the specfile for all of them.

We probably should use the name of from the specfile for this, but the load_repo_name of the underlying rpkg library
is using git remote for this information and this might have been necessary to be able to get the namespace alongside of the name.

Does this work?
Yes it does. Very well.

Are there problems?
Yes, but I don't think it's from your code.
The problem is with the assumption "the spec file is the correct name."
I'm going to go back to the original issue and discuss it there.

I wrote the above comment several days ago, but evidently didn't click the submit button.
After testing and discussion, it was decided to make centpkg act like rhpkg and fedpkg. That is, if a user requests a misspelled repo, it fails. A misspelled repo could be the wrong letter, or the wrong capitalization of a letter (Bash vs bash).

Closing this pull request, in favor of #76

Pull-Request has been closed by tdawson

a year ago