#167 Use PkgHistoryProcessor for process-distgit & koji
Merged 2 years ago by scoady. Opened 2 years ago by nphilipp.
fedora-infra/ nphilipp/rpmautospec main--resurrect-process-distgit  into  main

@@ -1,3 +0,0 @@ 

- [pagure]

- url = https://src.fedoraproject.org

- token = <TOKEN>

@@ -1,19 +1,13 @@ 

  import logging

  

- import koji

  from koji.plugin import callback

  

- from rpmautospec import process_distgit

+ from rpmautospec.process_distgit import process_distgit

  

  

- CONFIG_FILE = "/etc/kojid/plugins/rpmautospec.conf"

- CONFIG = None

- 

  log = logging.getLogger(__name__)

  log.setLevel(logging.DEBUG)

  

- pagure_proxy = None

- 

  

  @callback("postSCMCheckout")

  def process_distgit_cb(cb_type, *, srcdir, taskinfo, **kwargs):
@@ -22,18 +16,5 @@ 

          # i.e. maven and image builds don't have spec-files

          return

  

-     if not process_distgit.needs_processing(srcdir):

-         log.info("No %autorelease/%autochangelog found, skipping.")

-         return

- 

-     global CONFIG, pagure_proxy

- 

-     if not CONFIG:

-         try:

-             CONFIG = koji.read_config_files([(CONFIG_FILE, True)])

-         except Exception:

-             message = "While attempting to read config file %s, an exception occurred:"

-             log.exception(message, CONFIG_FILE)

-             return

- 

-     process_distgit.process_specfile(srcdir=srcdir)

+     if not process_distgit(srcdir):

+         log.info("No %autorelease/%autochangelog features used, skipping.")

file modified
+3 -6
@@ -93,8 +93,6 @@ 

  %files -n koji-builder-plugin-rpmautospec

  %{_prefix}/lib/koji-builder-plugins/*

  

- %config(noreplace) %{_sysconfdir}/kojid/plugins/rpmautospec.conf

- 

  # Package the placeholder rpm-macros

  

  %package -n rpmautospec-rpm-macros
@@ -131,10 +129,6 @@ 

  %endif

  %py_byte_compile %{python3} %{buildroot}%{_prefix}/lib/koji-builder-plugins/

  

- mkdir -p %{buildroot}%{_sysconfdir}/kojid/plugins/

- install -m 0644 koji_plugins/rpmautospec.conf \

-     %{buildroot}%{_sysconfdir}/kojid/plugins/rpmautospec.conf

- 

  # RPM macros

  mkdir -p %{buildroot}%{rpmmacrodir}

  install -m 644  rpm/macros.d/macros.rpmautospec %{buildroot}%{rpmmacrodir}/
@@ -147,6 +141,9 @@ 

  %endif

  

  %changelog

+ * Thu May 27 2021 Nils Philippsen <nils@redhat.com>

+ - don't ship obsolete Koji configuration snippet

+ 

  * Wed May 19 2021 Nils Philippsen <nils@redhat.com>

  - remove git-core, fix RPM related dependencies

  

file modified
+48 -54
@@ -1,21 +1,19 @@ 

  import re

  import subprocess

+ from collections import namedtuple

  from pathlib import Path

  from typing import Optional

  from typing import Union

  

- import koji

  

- 

- # The %autorelease macro including parameters. This is imported into the main package to be used

- # from 3rd party code like fedpkg etc.

+ # the %autorelease macro including parameters

+ AUTORELEASE_MACRO = "autorelease(e:s:hp)"

  AUTORELEASE_MACRO = "autorelease(e:s:po:)"

- AUTORELEASE_SENTINEL = "__AUTORELEASE_SENTINEL__"

  

+ autorelease_re = re.compile(r"\s*(?i:Release)\s*:.*%(?:autorelease(?:\s|$)|\{\??autorelease\})")

+ changelog_re = re.compile(r"^%changelog(?:\s.*)?$", re.IGNORECASE)

  autochangelog_re = re.compile(r"\s*%(?:autochangelog|\{\??autochangelog\})\s*")

  

- _kojiclient = None

- 

  

  def get_rpm_current_version(

      path: str, name: Optional[str] = None, with_epoch: bool = False
@@ -67,60 +65,56 @@ 

      return output

  

  

- def koji_init(koji_url_or_session: Union[str, koji.ClientSession]) -> koji.ClientSession:

-     global _kojiclient

-     if isinstance(koji_url_or_session, str):

-         _kojiclient = koji.ClientSession(koji_url_or_session)

-     else:

-         _kojiclient = koji_url_or_session

-     return _kojiclient

+ SpecfileFeatures = namedtuple(

+     "SpecfileFeatures",

+     ("has_autorelease", "has_autochangelog", "changelog_lineno", "autochangelog_lineno"),

+ )

+ 

+ 

+ def check_specfile_features(specpath: Union[Path, str]) -> SpecfileFeatures:

+     if not isinstance(specpath, Path):

+         specpath = Path(specpath)

+ 

+     has_autorelease = False

+     changelog_lineno = None

+     autochangelog_lineno = None

+ 

+     with specpath.open("r", encoding="utf-8", errors="replace") as specfile:

+         for lineno, line in enumerate(iter(specfile), start=1):

+             line = line.rstrip("\n")

+ 

+             if not has_autorelease and autorelease_re.match(line):

+                 has_autorelease = True

+ 

+             if changelog_lineno is None and changelog_re.match(line):

+                 changelog_lineno = lineno

+ 

+             if autochangelog_lineno is None and autochangelog_re.match(line):

+                 autochangelog_lineno = lineno

+ 

+     return SpecfileFeatures(

+         has_autorelease=has_autorelease,

+         has_autochangelog=bool(autochangelog_lineno),

+         changelog_lineno=changelog_lineno,

+         autochangelog_lineno=autochangelog_lineno,

+     )

  

  

  def specfile_uses_rpmautospec(

-     specfile: str, check_autorelease: bool = True, check_autochangelog: bool = True

+     specpath: Union[Path, str], check_autorelease: bool = True, check_autochangelog: bool = True

  ) -> bool:

      """Check whether or not an RPM spec file uses rpmautospec features."""

- 

-     autorelease = check_autorelease_presence(specfile)

-     autochangelog = check_autochangelog_presence(specfile)

- 

-     if check_autorelease and check_autochangelog:

-         return autorelease or autochangelog

-     elif check_autorelease:

-         return autorelease

-     elif check_autochangelog:

-         return autochangelog

-     else:

+     if not check_autorelease and not check_autochangelog:

          raise ValueError("One of check_autorelease and check_autochangelog must be set")

  

+     features = check_specfile_features(specpath)

  

- def check_autorelease_presence(filename: str) -> bool:

-     """

-     Use the rpm package to detect the presence of an

-     autorelease macro and return true if found.

-     """

-     cmd = (

-         "rpm",

-         "--define",

-         "{} {}".format(AUTORELEASE_MACRO, AUTORELEASE_SENTINEL),

-         "-q",

-         "--queryformat",

-         "%{release}\n",

-         "--specfile",

-         filename,

-     )

-     popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)

-     release = popen.communicate()[0].decode(errors="replace").split("\n")[0]

-     return release == AUTORELEASE_SENTINEL

+     retval = False

  

+     if check_autorelease:

+         retval = retval or features.has_autorelease

  

- def check_autochangelog_presence(filename: str) -> bool:

-     """

-     Search for the autochangelog macro and return true if found.

-     """

-     with open(filename, "r") as specfile:

-         for _, line in enumerate(iter(specfile), start=1):

-             line = line.rstrip("\n")

-             if autochangelog_re.match(line):

-                 return True

-         return False

+     if check_autochangelog:

+         retval = retval or features.has_autochangelog

+ 

+     return retval

file modified
+1 -1
@@ -199,7 +199,7 @@ 

          elif changelog_changed:

              if changelog_blob:

                  # Don't decode, we'll paste as is.

-                 changelog_entry["data"] = changelog_blob.data

+                 changelog_entry["data"] = changelog_blob.data.decode("utf-8", errors="replace")

              else:

                  # Changelog removed. Oops.

                  changelog_entry[

file modified
+39 -158
@@ -1,14 +1,12 @@ 

- from glob import glob

  import logging

  import os

- import re

  import shutil

  import tempfile

+ from pathlib import Path

+ from typing import Union

  

- 

- from .changelog import produce_changelog

- from .misc import koji_init

- from .release import calculate_release

+ from .misc import check_specfile_features

+ from .pkg_history import PkgHistoryProcessor

  

  

  log = logging.getLogger(__name__)
@@ -23,10 +21,6 @@ 

  ## END: Set by rpmautospec

  """  # noqa: E501

  

- autorelease_re = re.compile(r"\s*(?i:Release)\s*:.*%(?:autorelease(?:\s|$)|\{\??autorelease\})")

- changelog_re = re.compile(r"^%changelog(?:\s.*)?$", re.IGNORECASE)

- autochangelog_re = re.compile(r"\s*%(?:autochangelog|\{\??autochangelog\})\s*")

- 

  

  def register_subcommand(subparsers):

      subcmd_name = "process-distgit"
@@ -36,106 +30,44 @@ 

          help="Modify the contents of the specfile according to the repo",

      )

  

-     process_distgit_parser.add_argument("worktree_path", help="Path to the dist-git worktree")

-     process_distgit_parser.add_argument(

-         "dist", nargs="?", help="The dist tag (taken from the %%dist RPM macro if not specified)"

-     )

- 

-     process_distgit_parser.add_argument(

-         "--check",

-         dest="actions",

-         action="append_const",

-         const="check",

-         help="Check if the spec file uses %%autorelease or %%autochangelog macros at all.",

-     )

- 

-     process_distgit_parser.add_argument(

-         "--tag-package",

-         dest="actions",

-         action="append_const",

-         const="tag-package",

-         help="Tag existing builds in the specified package repository.",

-     )

- 

      process_distgit_parser.add_argument(

-         "--process-specfile",

-         dest="action",

-         action="append_const",

-         const="process-specfile",

-         help="Generate next release and changelog values and write them into the spec file.",

+         "spec_or_path",

+         help="Path to package worktree or the spec file within",

      )

  

      return subcmd_name

  

  

- def is_autorelease(line):

-     return autorelease_re.match(line)

- 

- 

- def is_autochangelog(line):

-     return autochangelog_re.match(line)

- 

- 

- def get_autorelease(srcdir):

-     # Not setting latest_evr, next_epoch_version just goes with what's in the package and latest

-     # builds.

-     release = calculate_release(srcdir=srcdir)

-     return release

- 

- 

- def get_specfile_name(srcdir):

-     specfile_names = glob(f"{srcdir}/*.spec")

-     if len(specfile_names) != 1:

-         raise RuntimeError(f"Didn't find exactly one spec file in {srcdir}.")

- 

-     return specfile_names[0]

- 

- 

- def check_distgit(srcdir):

-     has_autorelease = False

-     changelog_lineno = None

-     has_autochangelog = None

-     autochangelog_lineno = None

- 

-     specfile_name = get_specfile_name(srcdir)

+ def process_distgit(spec_or_path: Union[Path, str]) -> bool:

+     """Process an RPM spec file in a distgit repository.

  

-     # Detect if %autorelease, %autochangelog are in use

-     with open(specfile_name, "r") as specfile:

-         # Process line by line to cope with large files

-         for lineno, line in enumerate(iter(specfile), start=1):

-             line = line.rstrip("\n")

- 

-             if not has_autorelease and is_autorelease(line):

-                 has_autorelease = True

- 

-             if changelog_lineno is None:

-                 if changelog_re.match(line):

-                     changelog_lineno = lineno

-             if has_autochangelog is None and is_autochangelog(line):

-                 has_autochangelog = True

-                 autochangelog_lineno = lineno

- 

-     return has_autorelease, has_autochangelog, changelog_lineno, autochangelog_lineno

+     :param spec_or_path: the spec file or path of the repository

+     :return: whether or not the spec file needed processing

+     """

+     processor = PkgHistoryProcessor(spec_or_path)

  

+     features = check_specfile_features(processor.specfile)

+     processing_necessary = (

+         features.has_autorelease or features.has_autochangelog or not features.changelog_lineno

+     )

+     if not processing_necessary:

+         return False

  

- def needs_processing(srcdir):

-     has_autorelease, has_autochangelog, changelog_lineno, _ = check_distgit(srcdir)

-     return has_autorelease or has_autochangelog or not changelog_lineno

+     needs_autochangelog = (

+         features.changelog_lineno is None and features.autochangelog_lineno is None

+         or features.has_autochangelog

+     )

  

+     visitors = [processor.release_number_visitor]

+     if needs_autochangelog:

+         visitors.append(processor.changelog_visitor)

+     result = processor.run(visitors=visitors)

  

- def process_specfile(

-     srcdir,

-     has_autorelease=None,

-     has_autochangelog=None,

-     changelog_lineno=None,

-     autochangelog_lineno=None,

- ):

-     specfile_name = get_specfile_name(srcdir)

+     autorelease_number = result["release-number"]

  

-     autorelease_number = get_autorelease(srcdir)

-     with open(specfile_name, "r") as specfile, tempfile.NamedTemporaryFile("w") as tmp_specfile:

+     with processor.specfile.open("r") as specfile, tempfile.NamedTemporaryFile("w") as tmp_specfile:

          # Process the spec file into a temporary file...

-         if has_autorelease:

+         if features.has_autorelease:

              # Write %autorelease macro header

              print(

                  autorelease_template.format(autorelease_number=autorelease_number),
@@ -143,83 +75,32 @@ 

              )

  

          for lineno, line in enumerate(specfile, start=1):

-             if changelog_lineno:

-                 if has_autochangelog and lineno > changelog_lineno:

+             if features.changelog_lineno:

+                 if features.has_autochangelog and lineno > features.changelog_lineno:

                      break

  

              else:

-                 if has_autochangelog and lineno == autochangelog_lineno:

+                 if features.has_autochangelog and lineno == features.autochangelog_lineno:

                      print("%changelog\n", file=tmp_specfile, end="")

                      break

              print(line, file=tmp_specfile, end="")

  

-         if has_autochangelog:

-             print(

-                 "\n".join(produce_changelog(srcdir, latest_rel=autorelease_number)),

-                 file=tmp_specfile,

-             )

-         elif changelog_lineno is None:

-             print("No changelog found, auto creating")

+         if not features.has_autochangelog and features.changelog_lineno is None:

              print("\n%changelog\n", file=tmp_specfile, end="")

+ 

+         if needs_autochangelog:

              print(

-                 "\n".join(produce_changelog(srcdir, latest_rel=autorelease_number)),

+                 "\n\n".join(entry["data"] for entry in result["changelog"]),

                  file=tmp_specfile,

              )

  

          tmp_specfile.flush()

  

          # ...and copy it back (potentially across device boundaries)

-         shutil.copy2(tmp_specfile.name, specfile_name)

- 

- 

- def process_distgit(srcdir, dist, session, actions=None):

-     if not actions:

-         actions = ["process-specfile"]

- 

-     retval = True

- 

-     if "check" in actions or "process-specfile" in actions:

-         has_autorelease, has_autochangelog, changelog_lineno, autochangelog_lineno = check_distgit(

-             srcdir

-         )

-         processing_necessary = has_autorelease or has_autochangelog or not changelog_lineno

-         if "process-specfile" not in actions:

-             retval = processing_necessary

- 

-         # Only print output if explicitly requested

-         if "check" in actions:

-             features_used = []

-             if has_autorelease:

-                 features_used.append("%autorelease")

-             if has_autochangelog:

-                 features_used.append("%autochangelog")

- 

-             if not features_used:

-                 log.info("The spec file doesn't use automatic release or changelog.")

-             else:

-                 log.info("Features used by the spec file: %s", ", ".join(features_used))

- 

-     if "process-specfile" in actions and processing_necessary:

-         process_specfile(

-             srcdir,

-             dist,

-             has_autorelease,

-             has_autochangelog,

-             changelog_lineno,

-             autochangelog_lineno,

-         )

- 

-     return retval

+         shutil.copy2(tmp_specfile.name, processor.specfile)

  

  

  def main(args):

      """Main method."""

- 

-     repopath = args.worktree_path.rstrip(os.path.sep)

-     dist = args.dist

-     kojiclient = koji_init(args.koji_url)

- 

-     if process_distgit(repopath, dist, kojiclient, actions=args.actions):

-         return 0

-     else:

-         return 1

+     spec_or_path = args.spec_or_path.rstrip(os.path.sep)

+     process_distgit(spec_or_path)

@@ -1,3 +1,4 @@ 

+ import logging

  from unittest import mock

  

  import pytest
@@ -17,18 +18,16 @@ 

  class TestRpmautospecBuilder:

      """Test the rpmautospec builder plugin for Koji."""

  

-     commit = "5ab06967a36e72f66add9b6cfe08bd98f8900693"

-     url = f"git+https://src.fedoraproject.org/rpms/dummy-test-package-gloster.git#{commit}"

- 

-     data_scm_info = {

-         "host": "src.fedoraproject.org",

-         "module": "",

-         "repository": "/rpms/dummy-test-package-gloster.git",

-         "revision": commit,

-         "scheme": "git+https://",

-         "scmtype": "GIT",

-         "url": url,

-         "user": None,

+     data_build_tag = {

+         "id": 11522,

+         "name": "f32-build",

+         "arches": "armv7hl i686 x86_64 aarch64 ppc64le s390x",

+         "extra": {},

+         "locked": False,

+         "maven_include_all": False,

+         "maven_support": False,

+         "perm": "admin",

+         "perm_id": 1,

      }

  

      @pytest.mark.parametrize(
@@ -36,51 +35,46 @@ 

          (

              "normal",

              "other taskinfo method",

-             "skip processing",

+             "no features used",

          ),

      )

-     @mock.patch("rpmautospec.process_distgit.process_specfile")

-     @mock.patch("rpmautospec.process_distgit.needs_processing")

+     @mock.patch("koji_plugins.rpmautospec_builder.process_distgit")

      @mock.patch("koji.read_config_files")

      def test_process_distgit_cb(

          self,

          read_config_files,

-         needs_processing_fn,

-         process_specfile_fn,

+         process_distgit_fn,

          testcase,

+         caplog,

      ):

          """Test the process_distgit_cb() function"""

          read_config_files.return_value = MockConfig()

  

          taskinfo_method_responsible = testcase != "other taskinfo method"

-         skip_processing = testcase == "skip processing"

  

          # prepare test environment

          specfile_dir = "some dummy path"

          args = ["postSCMCheckout"]

          koji_session = mock.MagicMock()

          kwargs = {

-             "scminfo": self.data_scm_info,

+             "build_tag": self.data_build_tag,

              "scratch": mock.MagicMock(),

              "srcdir": specfile_dir,

              "taskinfo": {"method": "buildSRPMFromSCM"},

              "session": koji_session,

          }

  

-         if not taskinfo_method_responsible:

-             kwargs["taskinfo"]["method"] = "not the method you're looking for"

- 

-         if skip_processing:

-             needs_processing_fn.return_value = False

+         # return value is if processing was needed

+         process_distgit_fn.return_value = testcase != "no features used"

  

-         # verify what the callback did

          if not taskinfo_method_responsible:

-             needs_processing_fn.assert_not_called()

-             return

- 

-         needs_processing_fn.return_value = True

-         process_specfile_fn.return_value = None

+             kwargs["taskinfo"]["method"] = "not the method you're looking for"

  

-         process_distgit_cb(*args, **kwargs)

+         # test the callback

+         with caplog.at_level(logging.DEBUG):

+             process_distgit_cb(*args, **kwargs)

  

-         process_specfile_fn.assert_called_once()

+         if testcase == "no features used":

+             assert "skipping" in caplog.text

+         else:

+             assert not caplog.records

@@ -1,5 +1,7 @@ 

  import logging

  import os

+ from tempfile import NamedTemporaryFile

+ from typing import TextIO

  

  import pytest

  
@@ -11,6 +13,68 @@ 

  class TestMisc:

      """Test the rpmautospec.misc module"""

  

+     @staticmethod

+     def _generate_spec_with_features(

+         specfile: TextIO,

+         *,

+         with_autorelease=True,

+         autorelease_flags="",

+         with_changelog=True,

+         with_autochangelog=True,

+     ):

+         contents = [

+             "Line 1",

+             "Line 2",

+             f"Release: %autorelease {autorelease_flags}" if with_autorelease else "Release: 1",

+             "Line 4",

+             "Line 5",

+         ]

+         if with_changelog:

+             contents.append("%changelog")

+         if with_autochangelog:

+             contents.append("%autochangelog")

+         else:

+             contents.extend([

+                 "* Thu Jan 01 1970 Some Name <email@example.com>",

+                 "- some entry"

+             ])

+ 

+         print("\n".join(contents), file=specfile)

+         specfile.flush()

+ 

+     @pytest.mark.parametrize(

+         "with_autorelease,autorelease_flags,with_changelog,with_autochangelog",

+         (

+             pytest.param(True, "", True, True, id="all features"),

+             pytest.param(True, "-o 200", True, True, id="with autorelease offset"),

+             pytest.param(False, "", False, False, id="nothing")

+         )

+     )

+     def test_check_specfile_features(

+         self, with_autorelease, autorelease_flags, with_changelog, with_autochangelog,

+     ):

+         with NamedTemporaryFile(mode="w+") as specfile:

+             self._generate_spec_with_features(

+                 specfile,

+                 with_autorelease=with_autorelease,

+                 autorelease_flags=autorelease_flags,

+                 with_changelog=with_changelog,

+                 with_autochangelog=with_autochangelog,

+             )

+ 

+             features = misc.check_specfile_features(specfile.name)

+ 

+             assert features.has_autorelease == with_autorelease

+             if with_changelog:

+                 assert features.changelog_lineno == 6

+             else:

+                 assert features.changelog_lineno is None

+             assert features.has_autochangelog == with_autochangelog

+             if with_autochangelog:

+                 assert features.autochangelog_lineno == 7

+             else:

+                 assert features.autochangelog_lineno is None

+ 

      def test_specfile_uses_rpmautospec_no_macros(self, caplog):

          """Test no macros on specfile_uses_rpmautospec()"""

          caplog.set_level(logging.DEBUG)

@@ -3,7 +3,6 @@ 

  from subprocess import check_output

  import tarfile

  import tempfile

- from unittest import mock

  

  import pytest

  
@@ -71,18 +70,6 @@ 

  

          os.rename(spec_file_path + ".new", spec_file_path)

  

-     def test_is_autorelease(self):

-         assert process_distgit.is_autorelease("Release: %{autorelease}")

-         assert process_distgit.is_autorelease("Release: %autorelease")

-         assert process_distgit.is_autorelease("release: %{autorelease}")

-         assert process_distgit.is_autorelease(" release :  %{autorelease}")

- 

-         assert not process_distgit.is_autorelease("Release: %{autorelease_special}")

-         assert not process_distgit.is_autorelease("NotRelease: %{autorelease}")

-         assert not process_distgit.is_autorelease("release: 1%{?dist}")

- 

-     # Expected to fail until we've implemented the new release number algorithm

-     @pytest.mark.xfail

      @pytest.mark.parametrize("autorelease_case,autochangelog_case", autorelease_autochangelog_cases)

      def test_process_distgit(self, autorelease_case, autochangelog_case):

          """Test the process_distgit() function"""
@@ -109,22 +96,7 @@ 

                      unprocessed_spec_file_path, autorelease_case, autochangelog_case

                  )

  

-             koji_session = mock.MagicMock()

-             koji_session.getPackageID.return_value = 30489

-             name = "dummy-test-package-gloster"

-             builds = [

-                 {

-                     "epoch": None,

-                     "nvr": f"{name}-0-{x}.f32",

-                     "name": name,

-                     "release": f"{x}.fc32",

-                     "version": "0",

-                 }

-                 for x in range(2, 7)

-             ]

-             koji_session.listBuilds.return_value = builds

- 

-             process_distgit.process_distgit(unpacked_repo_dir, "fc32", koji_session)

+             process_distgit.process_distgit(unpacked_repo_dir)

  

              expected_spec_file_path = os.path.join(

                  __here__,
@@ -135,6 +107,7 @@ 

              )

  

              with tempfile.NamedTemporaryFile() as tmpspec:

+                 shutil.copy2(expected_spec_file_path, tmpspec.name)

                  if autorelease_case != "unchanged" or autochangelog_case != "unchanged":

                      if autochangelog_case not in (

                          "changelog case insensitive",
@@ -143,7 +116,6 @@ 

                          # "%changelog", "%ChAnGeLoG", ... stay verbatim, trick fuzz_spec_file() to

                          # leave the rest of the cases as is, the %autorelease macro is expanded.

                          autochangelog_case = "unchanged"

-                     shutil.copy2(expected_spec_file_path, tmpspec.name)

                      expected_spec_file_path = tmpspec.name

                      self.fuzz_spec_file(

                          expected_spec_file_path, autorelease_case, autochangelog_case

@@ -1,87 +1,23 @@ 

- import json

  import logging

  import os.path

  import tarfile

  import tempfile

  from pathlib import Path

- from unittest import mock

+ from unittest.mock import Mock

  

  import pytest

  

  from rpmautospec import release

- from ..common import MainArgs

  

  

  __here__ = os.path.dirname(__file__)

  

- test_data = [

-     {

-         "package": "gimp",

-         "expected_results": [

-             # 5 existing builds -> 6

-             {"dist": "fc32", "last": "gimp-2.10.14-4.fc32.1", "next": "gimp-2.10.14-6.fc32"},

-             {"dist": "fc31", "last": "gimp-2.10.14-3.fc31", "next": "gimp-2.10.14-4.fc31"},

-         ],

-     },

- ]

- 

- 

- def data_as_test_parameters(test_data):

-     parameters = []

- 

-     for datum in test_data:

-         blueprint = datum.copy()

-         expected_results = blueprint.pop("expected_results")

-         for expected in expected_results:

-             parameters.append({**blueprint, **expected})

- 

-     return parameters

- 

  

  class TestRelease:

      """Test the rpmautospec.release module"""

  

-     @pytest.mark.xfail

-     @pytest.mark.parametrize("test_data", data_as_test_parameters(test_data))

-     def test_main(self, test_data, caplog):

-         caplog.set_level(logging.DEBUG)

-         with open(

-             os.path.join(

-                 __here__,

-                 os.path.pardir,

-                 "test-data",

-                 "koji-output",

-                 "list-builds",

-                 test_data["package"] + ".json",

-             ),

-             "rb",

-         ) as f:

-             koji_list_builds_output = json.load(f)

- 

-         with mock.patch("rpmautospec.misc.koji") as mock_koji:

-             mock_client = mock.MagicMock()

-             mock_koji.ClientSession.return_value = mock_client

-             mock_client.getPackageID.return_value = 1234

-             mock_client.listBuilds.return_value = koji_list_builds_output

- 

-             main_args = MainArgs()

-             main_args.algorithm = "sequential_builds"

-             main_args.dist_git = os.path.sep.join(["tmp", test_data["package"]])

-             main_args.dist = test_data["dist"]

-             main_args.evr = None

-             main_args.koji_url = "http://192.0.2.1"

- 

-             release.main(main_args)

- 

-         mock_client.getPackageID.assert_called_once()

-         mock_client.listBuilds.assert_called_once()

- 

-         expected_messages = [f"Last build: {test_data['last']}", f"Next build: {test_data['next']}"]

- 

-         for msg in expected_messages:

-             assert msg in caplog.messages

- 

-     def test_calculate_release(self):

+     @pytest.mark.parametrize("method_to_test", ("calculate_release", "main"))

+     def test_calculate_release(self, method_to_test, caplog):

          with tempfile.TemporaryDirectory() as workdir:

              with tarfile.open(

                  os.path.join(
@@ -94,8 +30,15 @@ 

              ) as tar:

                  tar.extractall(path=workdir)

  

-             unpacked_repo_dir = (

-                 Path(workdir) / "dummy-test-package-gloster-git" / "dummy-test-package-gloster"

-             )

+             unpacked_repo_dir = Path(workdir) / "dummy-test-package-gloster"

+ 

+             expected_release_number = 11

  

-             assert release.calculate_release(unpacked_repo_dir) == 11

+             if method_to_test == "calculate_release":

+                 assert release.calculate_release(unpacked_repo_dir) == expected_release_number

+             else:

+                 with caplog.at_level(logging.INFO):

+                     args = Mock()

+                     args.spec_or_path = unpacked_repo_dir

+                     release.main(args)

+                 assert f"calculate_release release: {expected_release_number}" in caplog.text

@@ -1,11 +1,13 @@ 

- %define autorelease 7%{?dist}

+ ## START: Set by rpmautospec

+ %define autorelease(e:s:p) %{?-p:0.}11%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{?dist}

+ ## END: Set by rpmautospec

  

  # Our dummy-test-packages are named after canary varieties, meet Gloster, Rubino and Crested

  # Source: https://www.omlet.co.uk/guide/finches_and_canaries/canary/canary_varieties

  Name:           dummy-test-package-gloster

  

  Version:        0

- Release:        %{autorelease}

+ Release:        %autorelease

  Summary:        Dummy Test Package called Gloster

  License:        MIT

  URL:            http://fedoraproject.org/wiki/DummyTestPackages
@@ -34,27 +36,32 @@ 

  %{_datadir}/%{name}

  

  %changelog

- * Fri Mar 27 2020 Pierre-Yves Chibon <pingou@pingoured.fr> - 0-7

- - Undo vandalism

+ * Mon Apr 26 2021 Stephen Coady <scoady@redhat.com> 0-11

+ - use autorelease instead of autorel

+ 

+ * Fri Mar 27 2020 Pierre-Yves Chibon <pingou@pingoured.fr> 0-10

  - Change license to MIT

  

- * Fri Mar 27 2020 King ISØ-8859 <kingiso8859@example.com> - 0-7

+ * Fri Mar 27 2020 Pierre-Yves Chibon <pingou@pingoured.fr> 0-9

+ - Undo vandalism

+ 

+ * Fri Mar 27 2020 King ISØ-8859 <kingiso8859@example.com> 0-8

  - Honour the tradition of antiquated encodings!

  

- * Fri Mar 27 2020 Nils Philippsen <nils@redhat.com> - 0-6

+ * Fri Mar 27 2020 Nils Philippsen <nils@redhat.com> 0-7

  - Convert to automatic release and changelog

  

- * Tue Jan 21 2020 Pierre-Yves Chibon <pingou@pingoured.fr> - 0-5

- - rebuilt

+ * Fri Mar 27 2020 packagerbot <admin@fedoraproject.org> 0-6

+ - Bump release

  

- * Thu Jan 16 2020 Pierre-Yves Chibon <pingou@pingoured.fr> - 0-4

- - rebuilt

+ * Thu Jan 16 2020 Pierre-Yves Chibon <pingou@pingoured.fr> 0-5

+ - Bump release

  

- * Fri Jan 10 2020 Pierre-Yves Chibon <pingou@pingoured.fr> - 0-3

- - rebuilt

+ * Fri Jan 10 2020 Pierre-Yves Chibon <pingou@pingoured.fr> 0-4

+ - Bump release

  

- * Fri Jan 10 2020 Pierre-Yves Chibon <pingou@pingoured.fr> - 0-2

- - rebuilt

+ * Fri Jan 10 2020 Pierre-Yves Chibon <pingou@pingoured.fr> 0-3

+ - Bump release

  

- * Thu Dec 19 2019 Pierre-Yves Chibon <pingou@pingoured.fr> - 0-1

- - Initial packaging work

+ * Thu Jan 09 2020 Pierre-Yves Chibon <pingou@pingoured.fr> 0-1

+ - Initial import post review

Along with it, combine checking whether or not %autorelease or %autochangelog are used with where they are used (which is needed for processing such a spec file) in misc.check_specfile_features().

Plus more fixes and clean ups.

Depends-On: https://pagure.io/fedora-infra/rpmautospec/pull-request/166

Build succeeded.

This change depends on a change that failed to merge.

Build succeeded.

rebased onto 2b13d480034657e67b2c698267f6bd6763793208

2 years ago

Build succeeded.

rebased onto a41ba7a031e6d5a12cf71bf60099924244551988

2 years ago

lgtm! tested and everything is working fine

Build succeeded.

rebased onto bb24c3d

2 years ago

Build succeeded.

Pull-Request has been merged by scoady

2 years ago