diff --git a/pyp2rpm/bin.py b/pyp2rpm/bin.py index 1940c766..e502f80e 100644 --- a/pyp2rpm/bin.py +++ b/pyp2rpm/bin.py @@ -131,6 +131,10 @@ def get_scl_help_record(self, ctx): help='Enable / disable metadata extraction from virtualenv ' '(default: enabled).', default=True) +@click.option('--include-extras / --no-include-extras', + help='Enable / disable including extras_require as dependencies ' + '(default: enabled).', + default=True) @click.option('--autonc/ --no-autonc', help='Enable / disable using automatic provides with ' 'a standardized name in dependencies declaration (' @@ -171,7 +175,7 @@ def get_scl_help_record(self, ctx): default=None, metavar='FILE_NAME') @click.argument('package', nargs=1) -def main(package, v, prerelease, d, s, r, proxy, srpm, p, b, o, t, venv, autonc, +def main(package, v, prerelease, d, s, r, proxy, srpm, p, b, o, t, venv, include_extras, autonc, sclize, **scl_kwargs): """Convert PyPI package to RPM specfile or SRPM. @@ -208,7 +212,8 @@ def main(package, v, prerelease, d, s, r, proxy, srpm, p, b, o, t, venv, autonc, rpm_name=r, proxy=proxy, venv=venv, - autonc=autonc) + autonc=autonc, + include_extras=include_extras) logger.debug( 'Convertor: {0} created. Trying to convert.'.format(convertor)) diff --git a/pyp2rpm/command/extract_dist.py b/pyp2rpm/command/extract_dist.py index cdfb693c..4b7cd10e 100644 --- a/pyp2rpm/command/extract_dist.py +++ b/pyp2rpm/command/extract_dist.py @@ -25,12 +25,14 @@ def __init__(self, *args, **kwargs): self.metadata[attr] = to_list(getattr(self.distribution, attr, [])) try: + self.metadata['setup_requires_extras'] = [] + self.metadata['install_requires_extras'] = [] for k, v in getattr( self.distribution, 'extras_require', {}).items(): if k in ['test, docs', 'doc', 'dev']: - attr = 'setup_requires' + attr = 'setup_requires_extras' else: - attr = 'install_requires' + attr = 'install_requires_extras' self.metadata[attr] += to_list(v) except (AttributeError, ValueError): # extras require are skipped in case of wrong data format diff --git a/pyp2rpm/convertor.py b/pyp2rpm/convertor.py index d00fdfd9..3b8a3fef 100644 --- a/pyp2rpm/convertor.py +++ b/pyp2rpm/convertor.py @@ -45,7 +45,8 @@ def __init__(self, package=None, version=None, prerelease=False, distro=settings.DEFAULT_DISTRO, base_python_version=settings.DEFAULT_PYTHON_VERSION, python_versions=[], - rpm_name=None, proxy=None, venv=True, autonc=False): + rpm_name=None, proxy=None, venv=True, autonc=False, + include_extras=True): self.package = package self.version = version self.prerelease = prerelease @@ -60,6 +61,7 @@ def __init__(self, package=None, version=None, prerelease=False, self.proxy = proxy self.venv = venv self.autonc = autonc + self.include_extras = include_extras self.pypi = True suffix = os.path.splitext(self.package)[1] if (os.path.exists(self.package) @@ -275,6 +277,7 @@ def metadata_extractor(self): self.rpm_name, self.venv, self.distro, + self.include_extras, base_python_version) return self._metadata_extractor diff --git a/pyp2rpm/metadata_extractors.py b/pyp2rpm/metadata_extractors.py index aa0892e4..21072ebf 100644 --- a/pyp2rpm/metadata_extractors.py +++ b/pyp2rpm/metadata_extractors.py @@ -179,6 +179,7 @@ class LocalMetadataExtractor(object): def __init__(self, local_file, name, name_convertor, version, rpm_name=None, venv=True, distro=None, + include_extras_require=True, base_python_version=None, metadata_extension=False): self.local_file = local_file @@ -189,6 +190,7 @@ def __init__(self, local_file, name, name_convertor, version, self.rpm_name = rpm_name self.venv = venv self.distro = distro + self.include_extras_require = include_extras_require self.base_python_version = base_python_version self.metadata_extension = metadata_extension self.unsupported_version = None @@ -385,6 +387,10 @@ def runtime_deps(self): # install_requires """ use_rich_deps = self.distro not in settings.RPM_RICH_DEP_BLACKLIST install_requires = self.metadata['install_requires'] + + if self.include_extras_require: + install_requires += self.metadata['install_requires_extras'] + if self.metadata[ 'entry_points'] and 'setuptools' not in install_requires: install_requires.append('setuptools') # entrypoints @@ -410,6 +416,10 @@ def build_deps(self): # setup_requires [tests_require, install_requires] if 'setuptools' not in build_requires: build_requires.append('setuptools') + + if self.include_extras_require: + build_requires += self.metadata['setup_requires_extras'] + return sorted(self.name_convert_deps_list(deps_from_pyp_format( build_requires, runtime=False, use_rich_deps=use_rich_deps))) diff --git a/tests/test_data/djangorestframework-queryfields-1.0.0.tar.gz b/tests/test_data/djangorestframework-queryfields-1.0.0.tar.gz new file mode 100644 index 00000000..442036aa Binary files /dev/null and b/tests/test_data/djangorestframework-queryfields-1.0.0.tar.gz differ diff --git a/tests/test_data/obal-0.5.1.tar.gz b/tests/test_data/obal-0.5.1.tar.gz new file mode 100644 index 00000000..28cdf2fa Binary files /dev/null and b/tests/test_data/obal-0.5.1.tar.gz differ diff --git a/tests/test_metadata_extractors.py b/tests/test_metadata_extractors.py index 151d3cae..97654eaf 100644 --- a/tests/test_metadata_extractors.py +++ b/tests/test_metadata_extractors.py @@ -355,6 +355,31 @@ def test_doc_files(self, doc_files, license, other): assert data.data['doc_license'] == license assert data.data['doc_files'] == other + @pytest.mark.parametrize(('archive', 'include_extras', 'expected_build', 'expected_runtime'), [ + ('obal-0.5.1.tar.gz', True, + [['BuildRequires', 'python2-devel'], ['BuildRequires', 'python-setuptools']], + [['Requires', 'python-ansible', '>=', '2.5'], ['Requires', 'python-argcomplete'], ['Requires', 'python-setuptools']]), + ('obal-0.5.1.tar.gz', False, + [['BuildRequires', 'python2-devel'], ['BuildRequires', 'python-setuptools']], + [['Requires', 'python-ansible', '>=', '2.5'], ['Requires', 'python-setuptools']]), + ('djangorestframework-queryfields-1.0.0.tar.gz', True, + [['BuildRequires', 'python2-devel'], ['BuildRequires', 'python-django'], ['BuildRequires', 'python-djangorestframework'], + ['BuildRequires', 'python-mock-django'], ['BuildRequires', 'python-pytest-django'], ['BuildRequires', 'python-setuptools'], + ['BuildRequires', 'python-setuptools'], ['BuildRequires', 'python-wheel']], + []), + ('djangorestframework-queryfields-1.0.0.tar.gz', False, + [['BuildRequires', 'python2-devel'], ['BuildRequires', 'python-setuptools']], + []), + ]) + def test_extras_require(self, archive, include_extras, expected_build, expected_runtime): + name, version = archive.rsplit('-', 1) + extractor = me.SetupPyMetadataExtractor('{0}{1}'.format( + self.td_dir, archive), name, self.nc, version[:5], + include_extras_require=include_extras) + data = extractor.extract_data() + assert data.build_deps == expected_build + assert data.runtime_deps == expected_runtime + class TestWheelMetadataExtractor(object): td_dir = '{0}/test_data/'.format(tests_dir)