e78ad80
From 8667d5379161183b306bdd4a6733c666cd2ef310 Mon Sep 17 00:00:00 2001
e78ad80
From: Otto Liljalaakso <otto.liljalaakso@iki.fi>
e78ad80
Date: Sun, 2 Apr 2023 17:21:00 +0300
e78ad80
Subject: [PATCH 1/2] Use release's rpmdefines in unused sources check
e78ad80
e78ad80
Conditional Source: tags are problematic and, in fact, forbidden in at
e78ad80
least Fedora. However, there are packages that conditionalize packages
e78ad80
based on macros such as %{rhel} or %{fedora}. 'x-pkg sources' did not
e78ad80
handle such packages correctly, because when the specfile was parsed
e78ad80
to check for unused sources, values for those macros were not set. This
e78ad80
was different from other commands which set such macros based on the
e78ad80
value of --release parameter or Git branch name.
e78ad80
e78ad80
Improve support for conditional Source: tags by using the standard set
e78ad80
of rpmdefines when the specfile is parsed in 'fedpkg sources'.
e78ad80
e78ad80
Fixes: #671
e78ad80
JIRA: RHELCMP-11465
e78ad80
Merges: https://pagure.io/rpkg/pull-request/678
e78ad80
e78ad80
Signed-off-by: Otto Liljalaakso <otto.liljalaakso@iki.fi>
e78ad80
---
e78ad80
 pyrpkg/__init__.py | 21 +++++++++++++++------
e78ad80
 pyrpkg/spec.py     | 12 +++++++-----
e78ad80
 tests/test_cli.py  | 21 ++++++++++++++++++++-
e78ad80
 tests/test_spec.py |  8 ++++++--
e78ad80
 4 files changed, 48 insertions(+), 14 deletions(-)
e78ad80
e78ad80
diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py
e78ad80
index 3f934d3..817ef33 100644
e78ad80
--- a/pyrpkg/__init__.py
e78ad80
+++ b/pyrpkg/__init__.py
e78ad80
@@ -2261,13 +2261,22 @@ class Commands(object):
e78ad80
         sourcesf = SourcesFile(self.sources_filename, self.source_entry_type)
e78ad80
 
e78ad80
         try:
e78ad80
-            specf = SpecFile(os.path.join(self.layout.specdir, self.spec),
e78ad80
-                             self.layout.sourcedir)
e78ad80
-            spec_parsed = True
e78ad80
-        except Exception:
e78ad80
-            self.log.warning("Parsing specfile for used sources failed. "
e78ad80
-                             "Falling back to downloading all sources.")
e78ad80
+            # Try resolving rpmdefines separately. This produces a clear error
e78ad80
+            # message in the common failure case of custom branch name.
e78ad80
+            self.rpmdefines
e78ad80
+        except Exception as err:
e78ad80
+            self.log.warning("Parsing specfile for used sources failed: %s" % err)
e78ad80
+            self.log.warning("Falling back to downloading all sources.")
e78ad80
             spec_parsed = False
e78ad80
+        else:
e78ad80
+            try:
e78ad80
+                specf = SpecFile(os.path.join(self.layout.specdir, self.spec),
e78ad80
+                                 self.rpmdefines)
e78ad80
+                spec_parsed = True
e78ad80
+            except Exception:
e78ad80
+                self.log.warning("Parsing specfile for used sources failed. "
e78ad80
+                                 "Falling back to downloading all sources.")
e78ad80
+                spec_parsed = False
e78ad80
 
e78ad80
         args = dict()
e78ad80
         if self.lookaside_request_params:
e78ad80
diff --git a/pyrpkg/spec.py b/pyrpkg/spec.py
e78ad80
index d72f1fb..5400de3 100644
e78ad80
--- a/pyrpkg/spec.py
e78ad80
+++ b/pyrpkg/spec.py
e78ad80
@@ -18,16 +18,16 @@ class SpecFile(object):
e78ad80
         r'^((source[0-9]*|patch[0-9]*)\s*:\s*(?P<val>.*))\s*$',
e78ad80
         re.IGNORECASE)
e78ad80
 
e78ad80
-    def __init__(self, spec, sourcedir):
e78ad80
+    def __init__(self, spec, rpmdefines):
e78ad80
         self.spec = spec
e78ad80
-        self.sourcedir = sourcedir
e78ad80
+        self.rpmdefines = rpmdefines
e78ad80
         self.sources = []
e78ad80
 
e78ad80
         self.parse()
e78ad80
 
e78ad80
     def parse(self):
e78ad80
         """Call rpmspec and find source tags from the result."""
e78ad80
-        stdout = run(self.spec, self.sourcedir)
e78ad80
+        stdout = run(self.spec, self.rpmdefines)
e78ad80
         for line in stdout.splitlines():
e78ad80
             m = self.sourcefile_expression.match(line)
e78ad80
             if not m:
e78ad80
@@ -38,8 +38,10 @@ class SpecFile(object):
e78ad80
             self.sources.append(val)
e78ad80
 
e78ad80
 
e78ad80
-def run(spec, sourcedir):
e78ad80
-    cmdline = ['rpmspec', '--define', "_sourcedir %s" % sourcedir, '-P', spec]
e78ad80
+def run(spec, rpmdefines):
e78ad80
+    cmdline = ['rpmspec']
e78ad80
+    cmdline.extend(rpmdefines)
e78ad80
+    cmdline.extend(['-P', spec])
e78ad80
     try:
e78ad80
         process = subprocess.Popen(cmdline,
e78ad80
                                    stdout=subprocess.PIPE,
e78ad80
diff --git a/tests/test_cli.py b/tests/test_cli.py
e78ad80
index 02620ef..58df047 100644
e78ad80
--- a/tests/test_cli.py
e78ad80
+++ b/tests/test_cli.py
e78ad80
@@ -1607,6 +1607,25 @@ class TestSources(LookasideCacheMock, CliTestCase):
e78ad80
     def test_unused_sources_are_not_downloaded(self):
e78ad80
         self._upload_unused()
e78ad80
 
e78ad80
+        cli_cmd = ['rpkg', '--path', self.cloned_repo_path, 'sources']
e78ad80
+        with patch('sys.argv', new=cli_cmd):
e78ad80
+            with patch('pyrpkg.Commands.rpmdefines',
e78ad80
+                        new=['--define', '_sourcedir %s' % self.cloned_repo_path]):
e78ad80
+                cli = self.new_cli()
e78ad80
+                with patch('pyrpkg.lookaside.CGILookasideCache.download',
e78ad80
+                           new=self.lookasidecache_download):
e78ad80
+                    cli.sources()
e78ad80
+
e78ad80
+        path = os.path.join(self.cloned_repo_path, 'unused.patch')
e78ad80
+        self.assertFalse(os.path.exists(path))
e78ad80
+
e78ad80
+    @patch('pyrpkg.Commands.load_rpmdefines')
e78ad80
+    def test_download_sources_including_unused(self, rpmdefines):
e78ad80
+        self._upload_unused()
e78ad80
+        # SpecFile parsing executes 'rpmspec', that needs '--define' arguments from rpmdefines
e78ad80
+        # when rpmdefines raises eception, SpecFile parsing fails --> all sources are downloaded.
e78ad80
+        rpmdefines.side_effect = rpkgError
e78ad80
+
e78ad80
         cli_cmd = ['rpkg', '--path', self.cloned_repo_path, 'sources']
e78ad80
         with patch('sys.argv', new=cli_cmd):
e78ad80
             cli = self.new_cli()
e78ad80
@@ -1615,7 +1634,7 @@ class TestSources(LookasideCacheMock, CliTestCase):
e78ad80
                 cli.sources()
e78ad80
 
e78ad80
         path = os.path.join(self.cloned_repo_path, 'unused.patch')
e78ad80
-        self.assertFalse(os.path.exists(path))
e78ad80
+        self.assertTrue(os.path.exists(path))
e78ad80
 
e78ad80
     def test_force_option_downloads_unused_sources(self):
e78ad80
         self._upload_unused()
e78ad80
diff --git a/tests/test_spec.py b/tests/test_spec.py
e78ad80
index eefc475..0c7907a 100644
e78ad80
--- a/tests/test_spec.py
e78ad80
+++ b/tests/test_spec.py
e78ad80
@@ -10,6 +10,10 @@ from pyrpkg.errors import rpkgError
e78ad80
 class SpecFileTestCase(unittest.TestCase):
e78ad80
     def setUp(self):
e78ad80
         self.workdir = tempfile.mkdtemp(prefix='rpkg-tests.')
e78ad80
+        self.rpmdefines = ["--define", "_sourcedir %s" % self.workdir,
e78ad80
+                           "--define", "_specdir %s" % self.workdir,
e78ad80
+                           "--define", "_builddir %s" % self.workdir,
e78ad80
+                           "--eval", "%%undefine rhel"]
e78ad80
         self.specfile = os.path.join(self.workdir, self._testMethodName)
e78ad80
 
e78ad80
         # Write common header
e78ad80
@@ -43,7 +47,7 @@ class SpecFileTestCase(unittest.TestCase):
e78ad80
             "PAtch999: https://remote.patch-sourcce.org/another-patch.bz2\n")
e78ad80
         spec_fd.close()
e78ad80
 
e78ad80
-        s = spec.SpecFile(self.specfile, self.workdir)
e78ad80
+        s = spec.SpecFile(self.specfile, self.rpmdefines)
e78ad80
         actual = s.sources
e78ad80
         expected = [
e78ad80
             "tarball.tar.gz",
e78ad80
@@ -65,4 +69,4 @@ class SpecFileTestCase(unittest.TestCase):
e78ad80
         self.assertRaises(rpkgError,
e78ad80
                           spec.SpecFile,
e78ad80
                           self.specfile,
e78ad80
-                          self.workdir)
e78ad80
+                          self.rpmdefines)
e78ad80
-- 
e78ad80
2.40.0
e78ad80