From 29dd93721c324eb751911d8c814b5a91a60be61e Mon Sep 17 00:00:00 2001 From: lrossett Date: Apr 16 2021 15:56:30 +0000 Subject: lookaside repo name fix --- diff --git a/src/centpkg/lookaside.py b/src/centpkg/lookaside.py index b1a0edf..b855e2f 100644 --- a/src/centpkg/lookaside.py +++ b/src/centpkg/lookaside.py @@ -19,18 +19,153 @@ import pycurl import six import sys - -from pyrpkg.errors import InvalidHashType, UploadError +from pyrpkg.errors import InvalidHashType, UploadError, LayoutError from pyrpkg.lookaside import CGILookasideCache +from pyrpkg.layout.layouts import DistGitLayout + +from . import utils + + +def is_dist_git(folder): + """ + Indicates if a folder is using a dist-git layout. + + Parameters + ---------- + folder: str + The directory to inspect. + + Returns + ------- + bool + A bool flag indicating if `folder` is using + a dist-git layout format. + """ + result = False + + try: + DistGitLayout.from_path(folder) + result = True + except LayoutError: + result = False + finally: + return result class StreamLookasideCache(CGILookasideCache): - def __init__(self, hashtype, download_url, upload_url): + """ + CentosStream lookaside specialized class. + + It inherits most of its behavior from `pyrpkg.lookasideCGILookasideCache`. + """ + + def __init__(self, hashtype, download_url, upload_url, client_cert=None, ca_cert=None): super(StreamLookasideCache, self).__init__( - hashtype, download_url, upload_url) + hashtype, download_url, upload_url, + client_cert=client_cert, ca_cert=ca_cert) - self.download_path = ( - '%(name)s/%(filename)s/%(hashtype)s/%(hash)s/%(filename)s') + def remote_file_exists(self, name, filename, hashstr): + """ + Check if a remote file exists. + + This method inherits the behavior of its parent class from pyrpkg. + + It uses the internal `utils.get_repo_name` mehtod to parse the name in case + it is a scm url. + + Parameters + ---------- + name: str + The repository name and org. + + filename: str + The filename (something.tar.gz). + + hash: + The hash string for the file. + + Returns + ------- + bool + A boolean value to inditicate if the file exists. + """ + _name = utils.get_repo_name(name) if is_dist_git(os.getcwd()) else name + + return super(StreamLookasideCache, self).remote_file_exists( + _name, filename, hashstr) + + def upload(self, name, filename, hashstr, offline=False): + """ + Uploads a file to lookaside cache. + + This method inherits the behavior of its parent class from pyrpkg. + + It uses the internal `utils.get_repo_name` mehtod to parse the name in case + it is a scm url. + + Parameters + ---------- + name: str + The repository name and org. + + filename: str + The filename (something.tar.gz). + + hash: + The hash string for the file. + + Raises + ------ + pyrpkg.errors.rpkgError + Raises specialized classes that inherits from pyrokg base errors. + + Returns + ------- + None + Does not return anything + """ + _name = utils.get_repo_name(name) if is_dist_git(os.getcwd()) else name + + return super(StreamLookasideCache, self).upload( + _name, filename, hashstr) + + def download(self, name, filename, hashstr, outfile, hashtype=None, **kwargs): + """ + Downloads a file from lookaside cache to the local filesystem. + + This method inherits the behavior of its parent class from pyrpkg. + + It uses the internal `utils.get_repo_name` mehtod to parse the name in case + it is a scm url. + + Parameters + ---------- + name: str + The repository name and org. + + filename: str + The filename (something.tar.gz). + + hash: str + The hash string for the file. + + outfile: str + + + Raises + ------ + pyrpkg.errors.rpkgError + Raises specialized implementations of `yrpkg.errors.rpkgError`. + + Returns + ------- + None + Does not return anything + """ + _name = utils.get_repo_name(name) if is_dist_git(os.getcwd()) else name + + return super(StreamLookasideCache, self).download( + _name, filename, hashstr, outfile, hashtype=hashtype, **kwargs) class SIGLookasideCache(CGILookasideCache): @@ -56,13 +191,15 @@ class SIGLookasideCache(CGILookasideCache): # type it would explode with "unsupported second type in tuple". Let's # convert to str just to be sure. # https://bugzilla.redhat.com/show_bug.cgi?id=1241059 + _name = utils.get_repo_name(name) if is_dist_git(os.getcwd()) else name + if six.PY2 and isinstance(filename, six.text_type): filename = filename.encode('utf-8') if six.PY2 and isinstance(self.branch, six.text_type): self.branch = self.branch.encode('utf-8') - post_data = [('name', name), + post_data = [('name', _name), ('%ssum' % self.hashtype, hash), ('branch', self.branch), ('filename', filename)] diff --git a/src/centpkg/utils.py b/src/centpkg/utils.py index 4da4f78..6637201 100644 --- a/src/centpkg/utils.py +++ b/src/centpkg/utils.py @@ -10,6 +10,7 @@ # option) any later version. See http://www.gnu.org/copyleft/gpl.html for # the full text of the license. +import re import json import git @@ -150,3 +151,31 @@ def config_get_safely(config, section, option): raise rpkgError("{0}\n{1}".format(msg, hint)) except Exception: raise + + +def get_repo_name(name, org='rpms'): + """ + Try to parse the repository name in case it is a git url. + + Parameters + ---------- + name: str + The repository name, including the org name. + It will try to retrieve both repository name and org in case "name" is an url. + + org: str + The org to use in case name parsing is needed. + + Returns + ------- + str + A string containing the repository name: $ORG/$REPO`. + It will return the original `name` parameter in case of regex match failure. + """ + if name.startswith(org): + return name + + parsed = '/'.join(name.split('/')[1:]) + repo_name = parsed.split('_')[-1:][0] + + return '%s/%s' % (org, repo_name) diff --git a/tests/fixtures/layouts/dist-git/foobar.spec b/tests/fixtures/layouts/dist-git/foobar.spec new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/fixtures/layouts/dist-git/foobar.spec diff --git a/tests/fixtures/layouts/dist-git/foobar.txt b/tests/fixtures/layouts/dist-git/foobar.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/fixtures/layouts/dist-git/foobar.txt diff --git a/tests/fixtures/layouts/dist-git/sources b/tests/fixtures/layouts/dist-git/sources new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/fixtures/layouts/dist-git/sources diff --git a/tests/fixtures/layouts/srpm/.foobar.metadata b/tests/fixtures/layouts/srpm/.foobar.metadata new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/fixtures/layouts/srpm/.foobar.metadata diff --git a/tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch diff --git a/tests/fixtures/layouts/srpm/SPECS/foobar.spec b/tests/fixtures/layouts/srpm/SPECS/foobar.spec new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/fixtures/layouts/srpm/SPECS/foobar.spec diff --git a/tests/test_lookaside.py b/tests/test_lookaside.py new file mode 100644 index 0000000..10af66a --- /dev/null +++ b/tests/test_lookaside.py @@ -0,0 +1,18 @@ +import os +import unittest + +from centpkg import lookaside + + +class TestIsDistGit(unittest.TestCase): + def setUp(self): + cwd = os.path.dirname(os.path.realpath(__file__)) + self.fixtures_dir = '%s/fixtures/layouts' % cwd + + def test_dist_git(self): + path = '%s/dist-git' % self.fixtures_dir + assert lookaside.is_dist_git(path) + + def test_dist_git_false(self): + path = '%s/srpm' % self.fixtures_dir + assert not lookaside.is_dist_git(path) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..37e6426 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,21 @@ +import unittest + +from centpkg import utils + + +class TestGetRepoName(unittest.TestCase): + def test_rpms_org(self): + assert utils.get_repo_name('rpms/time') == 'rpms/time' + + def test_gitlab_fork(self): + assert utils.get_repo_name('someuser/time') == 'rpms/time' + + def test_centpkg_fork(self): + assert utils.get_repo_name('someuser/centos_rpms_binutils') == 'rpms/binutils' + + def test_ssh_fork(self): + assert utils.get_repo_name('git@gitlab.com:nickc2/binutils') == 'rpms/binutils' + + +if __name__ == '__main__': + unittest.main()