public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
To: git-commits@fedoraproject.org
Subject: [rpms/rpkg] 1.70-1: Patch: added layout module to deal with different package layouts
Date: Mon, 10 Aug 2026 21:44:15 GMT	[thread overview]
Message-ID: <178639825517.1.7709173975332351660.rpms-rpkg-30dab817d151@fedoraproject.org> (raw)

            A new commit has been pushed.

            Repo   : rpms/rpkg
            Branch : 1.70-1
            Commit : 30dab817d1515bc8838e1eba10344c188fe8de57
            Author : Ondřej Nosek <onosek@redhat.com>
            Date   : 2020-08-07T15:17:23+00:00
            Stats  : +672/-2 in 3 file(s)
            URL    : https://src.fedoraproject.org/rpms/rpkg/c/30dab817d1515bc8838e1eba10344c188fe8de57?branch=1.70-1

            Log:
            Patch: added layout module to deal with different package layouts

Signed-off-by: Ondřej Nosek <onosek@redhat.com>

---
diff --git a/0004-added-a-extendable-layout-module-to-deal-with-differ.patch b/0004-added-a-extendable-layout-module-to-deal-with-differ.patch
new file mode 100644
index 0000000..088702a
--- /dev/null
+++ b/0004-added-a-extendable-layout-module-to-deal-with-differ.patch
@@ -0,0 +1,630 @@
+From a95bad2ed57e500a9f9c1ec50d1c5cdacffca5f4 Mon Sep 17 00:00:00 2001
+From: odra <2183506+odra@users.noreply.github.com>
+Date: Mon, 20 Jul 2020 15:41:31 -0300
+Subject: [PATCH] added a extendable layout module to deal with different
+ package layouts within the CLI
+
+Signed-off-by: lrossett <lrossett@redhat.com>
+---
+ pyrpkg/__init__.py                            | 31 ++++---
+ pyrpkg/errors.py                              |  5 +
+ pyrpkg/layout/__init__.py                     | 30 ++++++
+ pyrpkg/layout/base.py                         | 93 +++++++++++++++++++
+ pyrpkg/layout/layouts.py                      | 80 ++++++++++++++++
+ .../fixtures/layouts/dead-module/dead.module  |  0
+ .../fixtures/layouts/dead-module/foobar.spec  |  0
+ .../layouts/dead-package/dead.package         |  0
+ .../fixtures/layouts/dead-package/foobar.spec |  0
+ tests/fixtures/layouts/dist-git/foobar.spec   |  0
+ tests/fixtures/layouts/dist-git/foobar.txt    |  0
+ tests/fixtures/layouts/dist-git/sources       |  0
+ tests/fixtures/layouts/specless/.gitkeep      |  0
+ .../layouts/srpm-dead-module/.foobar.metadata |  0
+ .../SOURCES/foobar-firstcommit.patch          |  0
+ .../srpm-dead-module/SPECS/foobar.spec        |  0
+ .../layouts/srpm-dead-module/dead.module      |  0
+ .../srpm-dead-package/.foobar.metadata        |  0
+ .../SOURCES/foobar-firstcommit.patch          |  0
+ .../srpm-dead-package/SPECS/foobar.spec       |  0
+ .../layouts/srpm-dead-package/dead.package    |  0
+ .../srpm-dead-package/srpm/.foobar.metadata   |  0
+ .../srpm/SOURCES/foobar-firstcommit.patch     |  0
+ .../srpm-dead-package/srpm/SPECS/foobar.spec  |  0
+ .../layouts/srpm-specless/.foobar.metadata    |  0
+ .../layouts/srpm-specless/SPECS/.gitkeep      |  0
+ tests/fixtures/layouts/srpm/.foobar.metadata  |  0
+ .../srpm/SOURCES/foobar-firstcommit.patch     |  0
+ tests/fixtures/layouts/srpm/SPECS/foobar.spec |  0
+ tests/test_cli.py                             | 22 +++--
+ tests/test_layout_distgit.py                  | 50 ++++++++++
+ tests/test_layout_srpm.py                     | 49 ++++++++++
+ 32 files changed, 340 insertions(+), 20 deletions(-)
+ create mode 100644 pyrpkg/layout/__init__.py
+ create mode 100644 pyrpkg/layout/base.py
+ create mode 100644 pyrpkg/layout/layouts.py
+ create mode 100644 tests/fixtures/layouts/dead-module/dead.module
+ create mode 100644 tests/fixtures/layouts/dead-module/foobar.spec
+ create mode 100644 tests/fixtures/layouts/dead-package/dead.package
+ create mode 100644 tests/fixtures/layouts/dead-package/foobar.spec
+ create mode 100644 tests/fixtures/layouts/dist-git/foobar.spec
+ create mode 100644 tests/fixtures/layouts/dist-git/foobar.txt
+ create mode 100644 tests/fixtures/layouts/dist-git/sources
+ create mode 100644 tests/fixtures/layouts/specless/.gitkeep
+ create mode 100644 tests/fixtures/layouts/srpm-dead-module/.foobar.metadata
+ create mode 100644 tests/fixtures/layouts/srpm-dead-module/SOURCES/foobar-firstcommit.patch
+ create mode 100644 tests/fixtures/layouts/srpm-dead-module/SPECS/foobar.spec
+ create mode 100644 tests/fixtures/layouts/srpm-dead-module/dead.module
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/.foobar.metadata
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/SOURCES/foobar-firstcommit.patch
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/SPECS/foobar.spec
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/dead.package
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/srpm/.foobar.metadata
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/srpm/SOURCES/foobar-firstcommit.patch
+ create mode 100644 tests/fixtures/layouts/srpm-dead-package/srpm/SPECS/foobar.spec
+ create mode 100644 tests/fixtures/layouts/srpm-specless/.foobar.metadata
+ create mode 100644 tests/fixtures/layouts/srpm-specless/SPECS/.gitkeep
+ create mode 100644 tests/fixtures/layouts/srpm/.foobar.metadata
+ create mode 100644 tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch
+ create mode 100644 tests/fixtures/layouts/srpm/SPECS/foobar.spec
+ create mode 100644 tests/test_layout_distgit.py
+ create mode 100644 tests/test_layout_srpm.py
+
+diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py
+index 6a24033..1252251 100644
+--- a/pyrpkg/__init__.py
++++ b/pyrpkg/__init__.py
+@@ -49,6 +49,7 @@ from pyrpkg.sources import SourcesFile
+ from pyrpkg.utils import (cached_property, extract_srpm, find_me,
+                           is_file_tracked, is_lookaside_eligible_file,
+                           log_result)
++from pyrpkg import layout
+ 
+ from .gitignore import GitIgnore
+ 
+@@ -212,6 +213,8 @@ class Commands(object):
+         self.block_retire_ns = ['rpms']
+         # Git excludes patterns
+         self.git_excludes = git_excludes or []
++        # Layout setup
++        self.layout = layout.build(self.path)
+ 
+     # Define properties here
+     # Properties allow us to "lazy load" various attributes, which also means
+@@ -759,14 +762,16 @@ class Commands(object):
+             raise rpkgError('Could not find the base OS ver from branch name'
+                             ' %s. Consider using --release option' %
+                             self.branch_merge)
++        if self.layout is None:
++            raise rpkgError('Unexpected error while loading the package.')
+         self._distvar, self._distval = osver.split('-')
+         self._distval = self._distval.replace('.', '_')
+         self._disttag = 'el%s' % self._distval
+-        self._rpmdefines = ["--define '_sourcedir %s'" % self.path,
+-                            "--define '_specdir %s'" % self.path,
+-                            "--define '_builddir %s'" % self.path,
+-                            "--define '_srcrpmdir %s'" % self.path,
+-                            "--define '_rpmdir %s'" % self.path,
++        self._rpmdefines = ["--define '_sourcedir %s'" % self.layout.sourcedir,
++                            "--define '_specdir %s'" % self.layout.specdir,
++                            "--define '_builddir %s'" % self.layout.builddir,
++                            "--define '_srcrpmdir %s'" % self.layout.srcrpmdir,
++                            "--define '_rpmdir %s'" % self.layout.rpmdir,
+                             "--define 'dist .%s'" % self._disttag,
+                             "--define '%s %s'" % (self._distvar,
+                                                   self._distval.split('_')[0]),
+@@ -784,11 +789,14 @@ class Commands(object):
+     def load_spec(self):
+         """This sets the spec attribute"""
+ 
++        if self.layout is None:
++            raise rpkgError('Spec file is not available')
++
+         if self.is_retired():
+             raise rpkgError('This package or module is retired. The action has stopped.')
+ 
+         # Get a list of files in the path we're looking at
+-        files = os.listdir(self.path)
++        files = os.listdir(self.layout.specdir)
+         # Search the files for the first one that ends with ".spec"
+         for f in files:
+             if f.endswith('.spec') and not f.startswith('.'):
+@@ -1015,7 +1023,9 @@ class Commands(object):
+ 
+     @property
+     def sources_filename(self):
+-        return os.path.join(self.path, 'sources')
++        if self.layout is None:
++            return os.path.join(self.path, 'sources')
++        return os.path.join(self.path, self.layout.sources_file_template)
+ 
+     @property
+     def osbs_config_filename(self):
+@@ -3188,12 +3198,7 @@ class Commands(object):
+         The state is indicated by present of files 'dead.package'
+         or 'dead.module'.
+         """
+-        marker = 'dead.package'
+-        if os.path.isfile(os.path.join(self.path, marker)):
+-            return marker
+-        marker = 'dead.module'
+-        if os.path.isfile(os.path.join(self.path, marker)):
+-            return marker
++        return self.layout.is_retired()
+ 
+     def retire(self, message):
+         """Delete all tracked files and commit a new dead.package file for rpms
+diff --git a/pyrpkg/errors.py b/pyrpkg/errors.py
+index 1378bf2..49b71d4 100644
+--- a/pyrpkg/errors.py
++++ b/pyrpkg/errors.py
+@@ -62,3 +62,8 @@ class UploadError(rpkgError):
+ 
+     def __unicode__(self):
+         return six.text_type(self.message)
++
++
++class LayoutError(rpkgError):
++    """Raised when something went wrong while parsing/loading a layout"""
++    pass
+diff --git a/pyrpkg/layout/__init__.py b/pyrpkg/layout/__init__.py
+new file mode 100644
+index 0000000..bdb2a79
+--- /dev/null
++++ b/pyrpkg/layout/__init__.py
+@@ -0,0 +1,30 @@
++# Copyright (c) 2015 - Red Hat Inc.
++#
++# 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.
++
++"""package layout management"""
++
++
++from pyrpkg.errors import LayoutError
++from .base import MetaLayout
++from .layouts import DistGitLayout, SRPMLayout # noqa
++
++
++def build(path):
++    """
++    Tries to create a layout instance based on MetaLayout._layouts
++    and will return an instance in the first successfull attempt to
++    create a new object from the MetaLayout._layouts list.
++
++    Returns None if no layouts can be created.
++    """
++    for layout in MetaLayout._layouts:
++        try:
++            return layout.from_path(path)
++        except LayoutError:
++            continue
++    return None
+diff --git a/pyrpkg/layout/base.py b/pyrpkg/layout/base.py
+new file mode 100644
+index 0000000..db30540
+--- /dev/null
++++ b/pyrpkg/layout/base.py
+@@ -0,0 +1,93 @@
++# Copyright (c) 2015 - Red Hat Inc.
++#
++# 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.
++
++"""base and meta package layout classes"""
++
++
++import os
++import abc
++from abc import abstractmethod, ABCMeta
++
++import six
++
++from pyrpkg.errors import LayoutError
++
++
++if six.PY2:
++    ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()})
++else:
++    ABC = abc.ABC
++
++
++class MetaLayout(type):
++    """
++    Layout meta class that keeps track of all layout subclasses.
++
++    Classes are appended in the _layouts property in order of code execution.
++    """
++    def __init__(cls, name, bases, dct):
++        """
++        This method registers a subclass in a class property (_layouts)
++        so those can be used as valid layout classes.
++        """
++        if not hasattr(cls, '_layouts'):
++            MetaLayout._layouts = []
++        if cls not in cls._layouts and cls.__name__ != 'BaseLayout':
++            MetaLayout._layouts.append(cls)
++        super(MetaLayout, cls).__init__(name, bases, dct)
++
++
++class ABCMetaLayout(MetaLayout, ABCMeta):
++    """
++    A mixin metaclass to enable usage of both Metalayout and ABC meta classes as a single metaclass.
++    """
++    pass
++
++
++@six.add_metaclass(ABCMetaLayout)
++class BaseLayout(ABC):
++    """
++    The abstract class to be inherited from when implemeting specific layouts.
++
++    Every subclass will be registered in the MetaLayout class.
++
++    Inherited classes will be registered in order or code execution.
++    """
++    root_dir = None
++    sourcedir = None
++    specdir = None
++    builddir = None
++    rpmdir = None
++    srcrpmdir = None
++    sources_file_template = None
++
++    @classmethod
++    @abstractmethod
++    def from_path(cls, path):
++        """
++        Class constructor based on a package path.
++
++        This method's implementation is madatory and
++        should return an instance of the object class.
++
++        It should return None if it can't read the path
++        or if the dir path contains an invalid layout.
++        """
++        if not os.path.exists(path):
++            raise LayoutError('package path does not exist')
++
++    def is_retired(self):
++        """
++        Checks whether package or module is already retired.
++        The state is indicated by present of files 'dead.package'
++        or 'dead.module'.
++        """
++        for fname in ['dead.package', 'dead.module']:
++            if os.path.exists('%s/%s' % (self.root_dir, fname)):
++                return fname
++        return None
+diff --git a/pyrpkg/layout/layouts.py b/pyrpkg/layout/layouts.py
+new file mode 100644
+index 0000000..96143b9
+--- /dev/null
++++ b/pyrpkg/layout/layouts.py
+@@ -0,0 +1,80 @@
++# Copyright (c) 2015 - Red Hat Inc.
++#
++# 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.
++
++"""package layout implementation"""
++
++
++import os
++
++from .base import BaseLayout
++from pyrpkg.errors import LayoutError
++
++
++class DistGitLayout(BaseLayout):
++    """
++    This class represents a dist-git package layout.
++    """
++    def __init__(self, root_dir=None, sources_file_template='sources'):
++        """
++        Default class constructor to create a new object instance.
++        """
++        self.root_dir = root_dir
++        self.sourcedir = root_dir
++        self.specdir = root_dir
++        self.builddir = root_dir
++        self.rpmdir = root_dir
++        self.srcrpmdir = root_dir
++        self.sources_file_template = sources_file_template
++
++    @classmethod
++    def from_path(cls, path):
++        """
++        Creates a new object instance from a valid path in the file system.
++
++        Returns none if path or package structure is invalid.
++        """
++        super(DistGitLayout, cls).from_path(path)
++
++        if len([f for f in os.listdir(path) if f.endswith('.spec')]) == 0:
++            raise LayoutError('spec file not found.')
++        sources = 'sources' if os.path.exists('%s/sources' % path) else None
++        return cls(root_dir=path, sources_file_template=sources)
++
++
++class SRPMLayout(BaseLayout):
++    """
++    This class represents an exposed source RPM package layout.
++    """
++    def __init__(self, root_dir=None, sources_file_template='.{0.repo_name}.metadata'):
++        """
++        Default class constructor to create a new object instance.
++        """
++        self.root_dir = root_dir
++        self.sourcedir = os.path.join(root_dir, 'SOURCES')
++        self.specdir = os.path.join(root_dir, 'SPECS')
++        self.builddir = os.path.join(root_dir, 'BUILD')
++        self.rpmdir = os.path.join(root_dir, 'RPMS')
++        self.srcrpmdir = os.path.join(root_dir, 'SRPMS')
++        self.sources_file_template = sources_file_template
++
++    @classmethod
++    def from_path(cls, path):
++        """
++        Creates a new object instance from a valid path in the file system.
++
++        Returns none if path or package structure is invalid.
++        """
++        super(SRPMLayout, cls).from_path(path)
++
++        if not os.path.exists(os.path.join(path, 'SPECS')):
++            raise LayoutError('SPECS dir not found.')
++        if len([f for f in os.listdir(os.path.join(path, 'SPECS')) if f.endswith('.spec')]) == 0:
++            raise LayoutError('spec file not found.')
++        if len([f for f in os.listdir(path) if f.endswith('.metadata')]) == 0:
++            raise LayoutError('metadata file not found.')
++        return cls(root_dir=path)
+diff --git a/tests/fixtures/layouts/dead-module/dead.module b/tests/fixtures/layouts/dead-module/dead.module
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/dead-module/foobar.spec b/tests/fixtures/layouts/dead-module/foobar.spec
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/dead-package/dead.package b/tests/fixtures/layouts/dead-package/dead.package
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/dead-package/foobar.spec b/tests/fixtures/layouts/dead-package/foobar.spec
+new file mode 100644
+index 0000000..e69de29
+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
+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
+diff --git a/tests/fixtures/layouts/dist-git/sources b/tests/fixtures/layouts/dist-git/sources
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/specless/.gitkeep b/tests/fixtures/layouts/specless/.gitkeep
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-module/.foobar.metadata b/tests/fixtures/layouts/srpm-dead-module/.foobar.metadata
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-module/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm-dead-module/SOURCES/foobar-firstcommit.patch
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-module/SPECS/foobar.spec b/tests/fixtures/layouts/srpm-dead-module/SPECS/foobar.spec
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-module/dead.module b/tests/fixtures/layouts/srpm-dead-module/dead.module
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/.foobar.metadata b/tests/fixtures/layouts/srpm-dead-package/.foobar.metadata
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm-dead-package/SOURCES/foobar-firstcommit.patch
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/SPECS/foobar.spec b/tests/fixtures/layouts/srpm-dead-package/SPECS/foobar.spec
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/dead.package b/tests/fixtures/layouts/srpm-dead-package/dead.package
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/srpm/.foobar.metadata b/tests/fixtures/layouts/srpm-dead-package/srpm/.foobar.metadata
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/srpm/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm-dead-package/srpm/SOURCES/foobar-firstcommit.patch
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-dead-package/srpm/SPECS/foobar.spec b/tests/fixtures/layouts/srpm-dead-package/srpm/SPECS/foobar.spec
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-specless/.foobar.metadata b/tests/fixtures/layouts/srpm-specless/.foobar.metadata
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm-specless/SPECS/.gitkeep b/tests/fixtures/layouts/srpm-specless/SPECS/.gitkeep
+new file mode 100644
+index 0000000..e69de29
+diff --git a/tests/fixtures/layouts/srpm/.foobar.metadata b/tests/fixtures/layouts/srpm/.foobar.metadata
+new file mode 100644
+index 0000000..e69de29
+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
+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
+diff --git a/tests/test_cli.py b/tests/test_cli.py
+index a8b34f4..eb9c79e 100644
+--- a/tests/test_cli.py
++++ b/tests/test_cli.py
+@@ -19,7 +19,7 @@ from six.moves import StringIO, configparser, http_client
+ import koji_cli.lib
+ import pyrpkg.cli
+ import utils
+-from pyrpkg import Commands, Modulemd, rpkgError
++from pyrpkg import Commands, Modulemd, rpkgError, layout
+ from utils import CommandTestCase, FakeThreadPool
+ 
+ try:
+@@ -64,6 +64,11 @@ def mock_get_rpm_package_name(self, rpm_file):
+     return(os.path.basename(rpm_file)[:-len('.src.rpm')])
+ 
+ 
++class MockLayout(layout.DistGitLayout):
++    def is_retired(self):
++        return None
++
++
+ class CliTestCase(CommandTestCase):
+ 
+     def new_cli(self, cfg=None):
+@@ -1561,11 +1566,13 @@ class TestMockbuild(CliTestCase):
+     @patch('os.path.exists', return_value=False)
+     def test_use_mock_config_got_from_koji(
+             self, exists, config_dir_other, config_dir_basic):
+-        config_dir_basic.return_value = '/path/to/config-dir'
++        mock_layout = layout.DistGitLayout(root_dir=self.cloned_repo_path)
++        with patch('pyrpkg.layout.build', return_value=mock_layout):
++            config_dir_basic.return_value = '/path/to/config-dir'
+ 
+-        cli_cmd = ['rpkg', '--path', self.cloned_repo_path,
+-                   '--release', 'rhel-7', 'mockbuild']
+-        self.mockbuild(cli_cmd)
++            cli_cmd = ['rpkg', '--path', self.cloned_repo_path,
++                       '--release', 'rhel-7', 'mockbuild']
++            self.mockbuild(cli_cmd)
+ 
+         args, kwargs = self.mock_run_command.call_args
+         cmd_to_execute = args[0]
+@@ -3449,8 +3456,9 @@ class TestBuildPackage(FakeKojiCreds, CliTestCase):
+     @patch('pyrpkg.Commands.nvr', new_callable=PropertyMock)
+     @patch('pyrpkg.Commands._run_command')
+     def test_option_srpm_by_generate_srpm_from_repo(self, _run_command, nvr):
+-        nvr.return_value = 'docpkg-0.1-1.fc28'
+-        self.assert_option_srpm_use()
++        with patch('pyrpkg.layout.build', return_value=MockLayout(root_dir=self.cloned_repo_path)):
++            nvr.return_value = 'docpkg-0.1-1.fc28'
++            self.assert_option_srpm_use()
+ 
+         args, kwargs = _run_command.call_args
+         self.assertEqual({'shell': True}, kwargs)
+diff --git a/tests/test_layout_distgit.py b/tests/test_layout_distgit.py
+new file mode 100644
+index 0000000..a4c4944
+--- /dev/null
++++ b/tests/test_layout_distgit.py
+@@ -0,0 +1,50 @@
++import os
++import unittest
++
++from pyrpkg.layout import layouts
++from pyrpkg import errors
++
++
++fixtures_dir = os.path.join(os.path.dirname(__file__), 'fixtures')
++
++
++class DistGitLayoutTestCase(unittest.TestCase):
++    def setUp(self):
++        self.workdir = os.path.join(fixtures_dir, 'layouts/dist-git')
++        self.layout = layouts.DistGitLayout.from_path(self.workdir)
++
++    def test_layout_data(self):
++        self.assertEqual(self.layout.sourcedir, self.workdir)
++        self.assertEqual(self.layout.specdir, self.workdir)
++        self.assertEqual(self.layout.specdir, self.workdir)
++        self.assertEqual(self.layout.root_dir, self.workdir)
++        self.assertEqual(self.layout.builddir, self.workdir)
++        self.assertEqual(self.layout.rpmdir, self.workdir)
++        self.assertEqual(self.layout.srcrpmdir, self.workdir)
++        self.assertEqual(self.layout.sources_file_template, 'sources')
++
++    def test_layout_retired(self):
++        self.assertEqual(None, self.layout.is_retired())
++
++
++class DistGitLayoutErrorsTestCase(unittest.TestCase):
++    def setUp(self):
++        self.workdir = os.path.join(fixtures_dir, 'layouts')
++
++    def test_path_error(self):
++        with self.assertRaises(errors.LayoutError) as e:
++            layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'notfound'))
++        self.assertEqual('package path does not exist', e.exception.args[0])
++
++    def test_specless_error(self):
++        with self.assertRaises(errors.LayoutError) as e:
++            layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'specless'))
++        self.assertEqual('spec file not found.', e.exception.args[0])
++
++    def test_dead_module_error(self):
++        layout = layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'dead-module'))
++        self.assertEqual('dead.module', layout.is_retired())
++
++    def test_dead_package_error(self):
++        layout = layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'dead-package'))
++        self.assertEqual('dead.package', layout.is_retired())
+diff --git a/tests/test_layout_srpm.py b/tests/test_layout_srpm.py
+new file mode 100644
+index 0000000..562406f
+--- /dev/null
++++ b/tests/test_layout_srpm.py
+@@ -0,0 +1,49 @@
++import os
++import unittest
++
++from pyrpkg.layout import layouts
++from pyrpkg import errors
++
++
++fixtures_dir = os.path.join(os.path.dirname(__file__), 'fixtures')
++
++
++class SRPMLayoutTestCase(unittest.TestCase):
++    def setUp(self):
++        self.workdir = os.path.join(fixtures_dir, 'layouts/srpm')
++        self.layout = layouts.SRPMLayout.from_path(self.workdir)
++
++    def test_layout_data(self):
++        self.assertEqual(self.layout.sourcedir, os.path.join(self.workdir, 'SOURCES'))
++        self.assertEqual(self.layout.specdir, os.path.join(self.workdir, 'SPECS'))
++        self.assertEqual(self.layout.root_dir, self.workdir)
++        self.assertEqual(self.layout.builddir, os.path.join(self.workdir, 'BUILD'))
++        self.assertEqual(self.layout.rpmdir, os.path.join(self.workdir, 'RPMS'))
++        self.assertEqual(self.layout.srcrpmdir, os.path.join(self.workdir, 'SRPMS'))
++        self.assertEqual(self.layout.sources_file_template, '.{0.repo_name}.metadata')
++
++    def test_layout_retired(self):
++        self.assertEqual(None, self.layout.is_retired())
++
++
++class SRPMLayoutErrorsTestCase(unittest.TestCase):
++    def setUp(self):
++        self.workdir = os.path.join(fixtures_dir, 'layouts')
++
++    def test_path_error(self):
++        with self.assertRaises(errors.LayoutError) as e:
++            layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'notfound'))
++        self.assertEqual('package path does not exist', e.exception.args[0])
++
++    def test_specless_error(self):
++        with self.assertRaises(errors.LayoutError) as e:
++            layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'srpm-specless'))
++        self.assertEqual('spec file not found.', e.exception.args[0])
++
++    def test_dead_module_error(self):
++        layout = layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'srpm-dead-module'))
++        self.assertEqual('dead.module', layout.is_retired())
++
++    def test_dead_package_error(self):
++        layout = layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'srpm-dead-package'))
++        self.assertEqual('dead.package', layout.is_retired())
+-- 
+2.26.2
+

diff --git a/0005-clog-tests-workaround.patch b/0005-clog-tests-workaround.patch
new file mode 100644
index 0000000..c80adcb
--- /dev/null
+++ b/0005-clog-tests-workaround.patch
@@ -0,0 +1,34 @@
+From 76eccea730446a44e11a4d85146666220763cbff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= <onosek@redhat.com>
+Date: Wed, 5 Aug 2020 01:08:25 +0000
+Subject: [PATCH] Re-enable clog tests
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Applied workaround described here:
+https://github.com/rpm-software-management/rpm/issues/1301
+
+Signed-off-by: Ondřej Nosek <onosek@redhat.com>
+---
+ pyrpkg/__init__.py | 5 +++++
+ tests/test_cli.py  | 6 ------
+ 2 files changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py
+index 6a24033..ad53257 100644
+--- a/pyrpkg/__init__.py
++++ b/pyrpkg/__init__.py
+@@ -2328,7 +2328,12 @@ class Commands(object):
+         """Write the latest spec changelog entry to a clog file"""
+ 
+         spec_file = os.path.join(self.path, self.spec)
++        # TODO: remove when fixed
++        # Command contains workaround (undefines _changelog_trimtime) described at:
++        # https://github.com/rpm-software-management/rpm/issues/1301
++        # It caused, that older changelog records were not displayed.
+         cmd = ['rpm'] + self.rpmdefines + ['-q', '--qf', '"%{CHANGELOGTEXT}\n"',
++                                           '--undefine', '"_changelog_trimtime"',
+                                            '--specfile', '"%s"' % spec_file]
+         proc = subprocess.Popen(' '.join(cmd), shell=True,
+                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE,

diff --git a/rpkg.spec b/rpkg.spec
index 4c6ad5a..073f898 100644
--- a/rpkg.spec
+++ b/rpkg.spec
@@ -1,6 +1,6 @@
 Name:           rpkg
 Version:        1.60
-Release:        6%{?dist}
+Release:        7%{?dist}
 
 Summary:        Python library for interacting with rpm+git
 License:        GPLv2+ and LGPLv2
@@ -19,7 +19,9 @@ Source0:        https://pagure.io/releases/rpkg/%{name}-%{version}.tar.gz
 Patch0:         remove-koji-and-rpm-py-installer-from-requires.patch
 Patch1:         0001-Repair-downloading-sources-into-external-directory.patch
 Patch2:         0002-Repair-compatible-formatting-for-Python-2.6.patch
-Patch3:		0003-Switch-from-krb_login-to-gssapi_login.patch
+Patch3:         0003-Switch-from-krb_login-to-gssapi_login.patch
+Patch4:         0004-added-a-extendable-layout-module-to-deal-with-differ.patch
+Patch5:         0005-clog-tests-workaround.patch
 
 %if 0%{?fedora} || 0%{?rhel} > 7
 # Disable python2 build by default
@@ -271,6 +273,10 @@ nosetests tests
 
 
 %changelog
+* Fri Aug 07 2020 Ondřej Nosek <onosek@redhat.com> - 1.60-7
+- Patch: added layout module to deal with different package layouts
+- Patch: clog tests workaround
+
 * Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.60-6
 - Second attempt - Rebuilt for
   https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild

                 reply	other threads:[~2026-08-10 21:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178639825517.1.7709173975332351660.rpms-rpkg-30dab817d151@fedoraproject.org \
    --to=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox