From ded77b0369736b080f9fcb09f6501c6dc0040f78 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Nov 21 2017 03:40:50 +0000 Subject: lint: Avoid checking rpm's multiple times When using the lint command, the rpm list includes duplicate packages which are then checked via rpmlint multiple times. Simplify the listing of rpm files using `glob` rather than looping over `os.listdir()`. Use `set` rather than `list` to ensure there are no duplicates in the rpms or arches lists. Sort the rpms when calling rpmlint for consistent ordering across lint runs. Thanks to Lubomír Sedlář for providing the tests. Helped-by: Lubomír Sedlář Signed-off-by: Todd Zullinger --- diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py index 527133e..318863b 100644 --- a/pyrpkg/__init__.py +++ b/pyrpkg/__init__.py @@ -2165,16 +2165,13 @@ class Commands(object): log.warning('No srpm found') # Get the possible built arches - arches = self._get_build_arches_from_spec() - rpms = [] + arches = set(self._get_build_arches_from_spec()) + rpms = set() for arch in arches: if os.path.exists(os.path.join(self.path, arch)): # For each available arch folder, lists file and keep # those ending with .rpm - rpms.extend([os.path.join(self.path, arch, file) - for file in os.listdir(os.path.join(self.path, - arch)) - if file.endswith('.rpm')]) + rpms.update(glob.glob(os.path.join(self.path, arch, '*.rpm'))) if not rpms: log.warning('No rpm found') cmd = ['rpmlint'] @@ -2187,7 +2184,7 @@ class Commands(object): cmd.append(os.path.join(self.path, self.spec)) if os.path.exists(os.path.join(self.path, srpm)): cmd.append(os.path.join(self.path, srpm)) - cmd.extend(rpms) + cmd.extend(sorted(rpms)) # Run the command self._run_command(cmd, shell=True) diff --git a/tests/test_commands.py b/tests/test_commands.py index 2641b90..85e967e 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -893,3 +893,38 @@ class TestConfigMockConfigDirWithNecessaryFiles(CommandTestCase): m.side_effect = IOError self.assertRaises(rpkgError, cmd._config_dir_other, '/path/to/config-dir') + + +class TestLint(CommandTestCase): + @patch('glob.glob') + @patch('os.path.exists') + @patch('pyrpkg.Commands._run_command') + @patch('pyrpkg.Commands.load_rpmdefines', new=mock_load_rpmdefines) + def test_lint_each_file_once(self, run, exists, glob): + cmd = self.make_commands() + srpm_path = os.path.join(cmd.path, 'docpkg-1.2-2.fc26.src.rpm') + bin_path = os.path.join(cmd.path, 'x86_64', 'docpkg-1.2-2.fc26.x86_64.rpm') + + def _mock_exists(path): + return path in [ + srpm_path, + os.path.join(cmd.path, 'x86_64'), + ] + + def _mock_glob(g): + return { + os.path.join(cmd.path, 'x86_64', '*.rpm'): [bin_path], + }[g] + exists.side_effect = _mock_exists + glob.side_effect = _mock_glob + cmd._get_build_arches_from_spec = Mock(return_value=['x86_64', 'x86_64']) + + cmd.lint() + + self.assertEqual( + run.call_args_list, + [call(['rpmlint', + os.path.join(cmd.path, 'docpkg.spec'), + srpm_path, + bin_path, + ], shell=True)])