From ee593f6f4e4b97a6098f6842aba518bc75878c67 Mon Sep 17 00:00:00 2001 From: clime Date: Sep 18 2018 04:50:30 +0000 Subject: [rpmbuild] EPEL6 fixes --- diff --git a/rpmbuild/copr-rpmbuild.spec b/rpmbuild/copr-rpmbuild.spec index a9f8840..ed161f9 100644 --- a/rpmbuild/copr-rpmbuild.spec +++ b/rpmbuild/copr-rpmbuild.spec @@ -35,6 +35,8 @@ BuildRequires: %python-requests BuildRequires: %python_pfx-jinja2 BuildRequires: %python-configparser +BuildRequires: python-rpm-macros + %if %{?python} == "python2" BuildRequires: python2-mock %endif @@ -44,17 +46,20 @@ Requires: %python_pfx-jinja2 Requires: %python_pfx-munch Requires: %python-configparser Requires: %python-requests -Requires: %python-simplejson +Requires: %python_pfx-simplejson Requires: mock Requires: git Requires: git-svn -Requires: expect -Requires: rubygem-gem2rpm -Requires: pyp2rpm Requires: rpkg +Requires: expect Requires: tito +%if 0%{?fedora} || 0%{?rhel} > 7 +Suggests: rubygem-gem2rpm +Suggests: pyp2rpm +%endif + %description Provides command capable of running COPR build-tasks. Example: copr-rpmbuild 12345-epel-7-x86_64 will locally @@ -90,6 +95,7 @@ install -p -m 755 bin/copr-sources-custom %buildroot%_bindir name="%{name}" version="%{version}" summary="%{summary}" %py_install %files +%{!?_licensedir:%global license %doc} %license LICENSE %{expand:%%%{python}_sitelib}/* diff --git a/rpmbuild/copr_rpmbuild/builders/mock.py b/rpmbuild/copr_rpmbuild/builders/mock.py index 0a81d6b..ae599b9 100644 --- a/rpmbuild/copr_rpmbuild/builders/mock.py +++ b/rpmbuild/copr_rpmbuild/builders/mock.py @@ -93,7 +93,7 @@ class MockBuilder(object): if not self.logfile: return filter_continuing_lines = r"sed 's/.*\x0D\([^\x0a]\)/\1/g' --unbuffered" - tee_output = "tee -a {}".format(self.logfile) + tee_output = "tee -a {0}".format(self.logfile) cmd = filter_continuing_lines + "|" + tee_output tee = subprocess.Popen(cmd, stdin=subprocess.PIPE, shell=True) os.dup2(tee.stdin.fileno(), sys.stdout.fileno()) @@ -117,7 +117,7 @@ class MockBuilder(object): for without_opt in self.without_opts: cmd += ["--without", without_opt] - log.info('Running: {}'.format(' '.join(cmd))) + log.info('Running: {0}'.format(' '.join(cmd))) process = GentlyTimeoutedPopen(cmd, stdin=subprocess.PIPE, preexec_fn=self.preexec_fn_build_stream, timeout=self.timeout) @@ -146,7 +146,7 @@ class MockBuilder(object): for without_opt in self.without_opts: cmd += ["--without", without_opt] - log.info('Running: {}'.format(' '.join(cmd))) + log.info('Running: {0}'.format(' '.join(cmd))) process = GentlyTimeoutedPopen(cmd, stdin=subprocess.PIPE, preexec_fn=self.preexec_fn_build_stream, timeout=self.timeout) diff --git a/rpmbuild/copr_rpmbuild/helpers.py b/rpmbuild/copr_rpmbuild/helpers.py index 3a0b52d..722070a 100644 --- a/rpmbuild/copr_rpmbuild/helpers.py +++ b/rpmbuild/copr_rpmbuild/helpers.py @@ -33,11 +33,11 @@ class SourceType: def cmd_debug(result): log.debug("") - log.debug("cmd: {}".format(result.cmd)) - log.debug("cwd: {}".format(result.cwd)) - log.debug("rc: {}".format(result.returncode)) - log.debug("stdout: {}".format(result.stdout)) - log.debug("stderr: {}".format(result.stderr)) + log.debug("cmd: {0}".format(result.cmd)) + log.debug("cwd: {0}".format(result.cwd)) + log.debug("rc: {0}".format(result.returncode)) + log.debug("stdout: {0}".format(result.stdout)) + log.debug("stderr: {0}".format(result.stderr)) log.debug("") @@ -62,8 +62,8 @@ def run_cmd(cmd, cwd=".", preexec_fn=None): result = munch.Munch( cmd=cmd, - stdout=stdout.decode(encoding='utf-8').strip(), - stderr=stderr.decode(encoding='utf-8').strip(), + stdout=stdout.decode('utf-8').strip(), + stderr=stderr.decode('utf-8').strip(), returncode=process.returncode, cwd=cwd ) @@ -83,7 +83,7 @@ def locate_spec(dirpath): spec_path = path_match break if not spec_path: - raise RuntimeError('No .spec found at {}'.format(dirpath)) + raise RuntimeError('No .spec found at {0}'.format(dirpath)) return spec_path @@ -95,7 +95,7 @@ def locate_srpm(dirpath): srpm_path = path_match break if not srpm_path: - raise RuntimeError('No .src.rpm found at {}'.format(dirpath)) + raise RuntimeError('No .src.rpm found at {0}'.format(dirpath)) return srpm_path @@ -115,7 +115,7 @@ def get_package_name(spec_path): try: rpm_spec = ts.parseSpec(spec_path) except ValueError as e: - log.debug("Could not parse {} with error {}. Trying manual parsing." + log.debug("Could not parse {0} with error {1}. Trying manual parsing." .format(spec_path, str(e))) with open(spec_path, 'r') as spec_file: @@ -139,7 +139,7 @@ def get_package_name(spec_path): if not re.match(r'[a-zA-Z0-9-._+]+', package_name): raise PackageNameCouldNotBeObtainedException( - "Got invalid package package name '{}' from {}.".format(package_name, spec_path)) + "Got invalid package package name '{0}' from {1}.".format(package_name, spec_path)) return package_name @@ -159,7 +159,7 @@ def read_config(config_path=None): config_paths = [os.path.join(path, "main.ini") for path in CONF_DIRS] config.read(config_path or reversed(config_paths)) if not config.sections(): - log.error("No configuration file main.ini in: {}".format(" ".join(CONF_DIRS))) + log.error("No configuration file main.ini in: {0}".format(" ".join(CONF_DIRS))) sys.exit(1) return config @@ -189,10 +189,10 @@ def extract_srpm(srpm_path, destination): """ cwd = os.getcwd() os.chdir(destination) - log.debug('Extracting srpm {} to {}'.format(srpm_path, destination)) + log.debug('Extracting srpm {0} to {1}'.format(srpm_path, destination)) try: cmd = "rpm2cpio {path} | cpio -idmv".format(path=pipes.quote(srpm_path)) - subprocess.check_output(cmd, shell=True) + subprocess.check_call(cmd, shell=True) finally: os.chdir(cwd) @@ -268,7 +268,7 @@ def get_additional_repo_configs(repo_urls, chroot, backend_base_url): repo_config = { "id": repo_name, "url": preprocess_repo_url(repo_url, chroot, backend_base_url), - "name": "Additional repo {}".format(repo_name), + "name": "Additional repo {0}".format(repo_name), } repo_configs.append(repo_config) diff --git a/rpmbuild/copr_rpmbuild/providers/base.py b/rpmbuild/copr_rpmbuild/providers/base.py index 8efa288..47a45f2 100644 --- a/rpmbuild/copr_rpmbuild/providers/base.py +++ b/rpmbuild/copr_rpmbuild/providers/base.py @@ -22,7 +22,7 @@ class Provider(object): with open(path, "w") as rpmmacros: rpmmacros.write("%_disable_source_fetch 0\n") enabled_protocols = string2list(self.config.get("main", "enabled_source_protocols")) - rpmmacros.write("%__urlhelper_localopts --proto -all,{}\n" + rpmmacros.write("%__urlhelper_localopts --proto -all,{0}\n" .format(','.join(["+"+protocol for protocol in enabled_protocols]))) def __exit__(self, exc_type, exc_value, traceback): diff --git a/rpmbuild/copr_rpmbuild/providers/pypi.py b/rpmbuild/copr_rpmbuild/providers/pypi.py index ab7d01e..f95eec6 100644 --- a/rpmbuild/copr_rpmbuild/providers/pypi.py +++ b/rpmbuild/copr_rpmbuild/providers/pypi.py @@ -13,7 +13,16 @@ class PyPIProvider(Provider): self.spec_template = source_json["spec_template"] self.python_versions = source_json["python_versions"] or [] + def tool_presence_check(self): + try: + run_cmd(["which", "pyp2rpm"]) + except RuntimeError as err: + log.error("Please, install pyp2rpm.") + raise err + def produce_srpm(self): + self.tool_presence_check() + cmd = ["pyp2rpm", self.pypi_package_name, "-t", self.spec_template, "--srpm", "-d", self.outdir] diff --git a/rpmbuild/copr_rpmbuild/providers/rubygems.py b/rpmbuild/copr_rpmbuild/providers/rubygems.py index 2a18605..3498f56 100644 --- a/rpmbuild/copr_rpmbuild/providers/rubygems.py +++ b/rpmbuild/copr_rpmbuild/providers/rubygems.py @@ -10,13 +10,24 @@ class RubyGemsProvider(Provider): super(RubyGemsProvider, self).__init__(source_json, outdir, config) self.gem_name = source_json["gem_name"] + def tool_presence_check(self): + try: + run_cmd(["which", "gem2rpm"]) + except RuntimeError as err: + log.error("Please, install gem2rpm.") + raise err + def produce_srpm(self): + self.tool_presence_check() + cmd = ["gem2rpm", self.gem_name, "--srpm", "-C", self.outdir, "--fetch"] result = run_cmd(cmd) + if "Empty tag: License" in result.stderr: raise RuntimeError("\n".join([ result.stderr, "Not specifying a license means all rights are reserved;" "others have no rights to use the code for any purpose.", "See http://guides.rubygems.org/specification-reference/#license="])) + return result diff --git a/rpmbuild/copr_rpmbuild/providers/scm.py b/rpmbuild/copr_rpmbuild/providers/scm.py index 00f6670..04f8b7d 100644 --- a/rpmbuild/copr_rpmbuild/providers/scm.py +++ b/rpmbuild/copr_rpmbuild/providers/scm.py @@ -149,8 +149,7 @@ class ScmProvider(Provider): helpers.run_cmd(clone_cmd) except RuntimeError as e: log.error(str(e)) - if self.scm_type == 'git' and \ - 'fatal: dumb http transport' in str(e): + if self.scm_type == 'git': helpers.run_cmd(['git', 'clone', self.clone_url, self.repo_path]) else: raise e diff --git a/rpmbuild/main.py b/rpmbuild/main.py index eaab207..33f3606 100755 --- a/rpmbuild/main.py +++ b/rpmbuild/main.py @@ -16,7 +16,10 @@ import stat import pipes import pkg_resources -from simplejson.scanner import JSONDecodeError +try: + from simplejson.scanner import JSONDecodeError +except ImportError: + JSONDecodeError = Exception from copr_rpmbuild import providers from copr_rpmbuild.builders.mock import MockBuilder @@ -238,7 +241,7 @@ def build_srpm(args, config): resultdir = config.get("main", "resultdir") produce_srpm(task, config, resultdir) - log.info("Output: {}".format( + log.info("Output: {0}".format( os.listdir(resultdir))) with open(os.path.join(resultdir, 'success'), "w") as success: @@ -326,12 +329,12 @@ def get_vanilla_build_config(build_config_url_path, config): build_config = response.json() if not build_config: - raise RuntimeError("No valid build_config at {}".format(url)) + raise RuntimeError("No valid build_config at {0}".format(url)) if build_config.get("source_json"): build_config["source_json"] = json.loads(build_config["source_json"]) except JSONDecodeError: - raise RuntimeError("No valid build_config at {}".format(url)) + raise RuntimeError("No valid build_config at {0}".format(url)) return build_config diff --git a/rpmbuild/setup.py b/rpmbuild/setup.py index c729c31..468cbc5 100755 --- a/rpmbuild/setup.py +++ b/rpmbuild/setup.py @@ -5,7 +5,7 @@ import os from setuptools import setup, find_packages setup( - name=os.getenv('name'), + name='copr-rpmbuild', version=os.getenv('version'), description=os.getenv('summary'), author='clime', diff --git a/rpmbuild/tests/test_base.py b/rpmbuild/tests/test_base.py index 19aa446..92ad9a7 100644 --- a/rpmbuild/tests/test_base.py +++ b/rpmbuild/tests/test_base.py @@ -15,13 +15,13 @@ class TestProvider(TestCase): self.source_json = {} self.resultdir = "/path/to/resultdir" - @mock.patch('{}.open'.format(builtins), new_callable=mock.mock_open()) + @mock.patch('{0}.open'.format(builtins), new_callable=mock.mock_open()) def test_create_rpmmacros(self, mock_open): provider = Provider(self.source_json, self.resultdir, self.config) rpmmacros = mock.MagicMock() mock_open.return_value = rpmmacros provider.create_rpmmacros() - mock_open.assert_called_with("{}/.rpmmacros".format(provider.workdir), "w") + mock_open.assert_called_with("{0}/.rpmmacros".format(provider.workdir), "w") calls = [ mock.call.__enter__().write('%_disable_source_fetch 0\n'), mock.call.__enter__().write('%__urlhelper_localopts --proto -all,+https,+ftps\n'), diff --git a/rpmbuild/tests/test_mock.py b/rpmbuild/tests/test_mock.py index 6daae4f..c18c135 100644 --- a/rpmbuild/tests/test_mock.py +++ b/rpmbuild/tests/test_mock.py @@ -97,7 +97,7 @@ class TestMockBuilder(unittest.TestCase): preexec_fn=builder.preexec_fn_build_stream, timeout=21600) - @mock.patch('{}.open'.format(builtins), new_callable=mock.mock_open()) + @mock.patch('{0}.open'.format(builtins), new_callable=mock.mock_open()) def test_touch_success_file(self, mock_open): builder = MockBuilder(self.task, self.sourcedir, self.resultdir, self.config) builder.touch_success_file() diff --git a/rpmbuild/tests/test_providers.py b/rpmbuild/tests/test_providers.py index cec5166..2de00df 100644 --- a/rpmbuild/tests/test_providers.py +++ b/rpmbuild/tests/test_providers.py @@ -1,4 +1,6 @@ import unittest +import pytest + from copr_rpmbuild.providers import (factory, RubyGemsProvider, PyPIProvider, SpecUrlProvider) @@ -13,5 +15,5 @@ class TestProvidersFactory(unittest.TestCase): self.assertEqual(factory(SourceType.RUBYGEMS), RubyGemsProvider) self.assertEqual(factory(SourceType.PYPI), PyPIProvider) self.assertEqual(factory(SourceType.LINK), SpecUrlProvider) - with self.assertRaises(RuntimeError): + with pytest.raises(RuntimeError): factory(self.not_existing_source_type) diff --git a/rpmbuild/tests/test_pypi.py b/rpmbuild/tests/test_pypi.py index 258a0f0..3d435bc 100644 --- a/rpmbuild/tests/test_pypi.py +++ b/rpmbuild/tests/test_pypi.py @@ -27,7 +27,7 @@ class TestPyPIProvider(TestCase): self.assertEqual(provider.python_versions, [2, 3]) @mock.patch("copr_rpmbuild.providers.pypi.run_cmd") - @mock.patch("{}.open".format(builtins)) + @mock.patch("{0}.open".format(builtins)) def test_produce_srpm(self, mock_open, run_cmd): provider = PyPIProvider(self.source_json, "/some/tmp/directory", self.config) provider.produce_srpm() diff --git a/rpmbuild/tests/test_rubygems.py b/rpmbuild/tests/test_rubygems.py index 1b50907..2a408f0 100644 --- a/rpmbuild/tests/test_rubygems.py +++ b/rpmbuild/tests/test_rubygems.py @@ -1,3 +1,5 @@ +import pytest + from munch import Munch from copr_rpmbuild.providers.rubygems import RubyGemsProvider from . import TestCase @@ -22,7 +24,7 @@ class TestRubyGemsProvider(TestCase): self.assertEqual(provider.gem_name, "A_123") @mock.patch("copr_rpmbuild.providers.rubygems.run_cmd") - @mock.patch("{}.open".format(builtins)) + @mock.patch("{0}.open".format(builtins)) def test_produce_srpm(self, mock_open, run_cmd): provider = RubyGemsProvider(self.source_json, self.resultdir, self.config) provider.produce_srpm() @@ -30,13 +32,13 @@ class TestRubyGemsProvider(TestCase): run_cmd.assert_called_with(assert_cmd) @mock.patch("copr_rpmbuild.providers.rubygems.run_cmd") - @mock.patch("{}.open".format(builtins)) + @mock.patch("{0}.open".format(builtins)) def test_empty_license(self, mock_open, run_cmd): stderr = ("error: line 8: Empty tag: License:" "Command failed: rpmbuild -bs --nodeps --define '_sourcedir /tmp/gem2rpm-foo-20170905-3367-c2flks'" "--define '_srcrpmdir .' /tmp/gem2rpm-foo-20170905-3367-c2flks/rubygem-foo.spec") run_cmd.return_value = Munch({"stderr": stderr}) provider = RubyGemsProvider(self.source_json, self.resultdir, self.config) - with self.assertRaises(RuntimeError) as ex: + with pytest.raises(RuntimeError) as ex: provider.produce_srpm() - self.assertIn("Not specifying a license means all rights are reserved", str(ex.exception)) + assert "Not specifying a license means all rights are reserved" in str(ex.exception) diff --git a/rpmbuild/tests/test_scm.py b/rpmbuild/tests/test_scm.py index 7c0c536..1b2a9ee 100644 --- a/rpmbuild/tests/test_scm.py +++ b/rpmbuild/tests/test_scm.py @@ -95,7 +95,9 @@ class TestScmProvider(TestCase): assert_cmd = ["tito", "build", "--srpm", "--output", self.resultdir] self.assertEqual(provider.get_tito_command(), assert_cmd) - def test_get_tito_test_command(self): + + @mock.patch("copr_rpmbuild.helpers.run_cmd") + def test_get_tito_test_command(self, run_cmd_mock): provider = ScmProvider(self.source_json, self.resultdir, self.config) assert_cmd = ["tito", "build", "--test", "--srpm", "--output", self.resultdir] self.assertEqual(provider.get_tito_test_command(), assert_cmd) diff --git a/rpmbuild/tests/test_spec.py b/rpmbuild/tests/test_spec.py index 088f3e5..7e00baf 100644 --- a/rpmbuild/tests/test_spec.py +++ b/rpmbuild/tests/test_spec.py @@ -24,17 +24,17 @@ class TestSpecUrlProvider(TestCase): @mock.patch('requests.get') @mock.patch("copr_rpmbuild.providers.spec.run_cmd") - @mock.patch('{}.open'.format(builtins), new_callable=mock.mock_open()) + @mock.patch('{0}.open'.format(builtins), new_callable=mock.mock_open()) def test_produce_srpm(self, mock_open, run_cmd, mock_get): provider = SpecUrlProvider(self.source_json, self.resultdir, self.config) provider.produce_srpm() run_cmd.assert_called_with(["rpkg", "srpm", "--outdir", self.resultdir, - "--spec", '{}/somepackage.spec'.format(provider.workdir)], + "--spec", '{0}/somepackage.spec'.format(provider.workdir)], cwd=provider.workdir) @mock.patch('requests.get') - @mock.patch('{}.open'.format(builtins), new_callable=mock.mock_open()) + @mock.patch('{0}.open'.format(builtins), new_callable=mock.mock_open()) def test_save_spec(self, mock_open, mock_get): provider = SpecUrlProvider(self.source_json, self.resultdir, self.config) provider.save_spec() - mock_open.assert_called_with("{}/somepackage.spec".format(provider.workdir), "w") + mock_open.assert_called_with("{0}/somepackage.spec".format(provider.workdir), "w")