diff --git a/rust2rpm/__main__.py b/rust2rpm/__main__.py index 40957ba..77189bf 100644 --- a/rust2rpm/__main__.py +++ b/rust2rpm/__main__.py @@ -11,7 +11,7 @@ from rust2rpm.conf import load_config, TomlConf from rust2rpm.crate import InvalidProjectError, InvalidVersionError, process_project from rust2rpm.cratesio import NoVersionsError from rust2rpm.distgit import get_package_info -from rust2rpm.generator import spec_render_crate, spec_render_project, spec_render_workspace +from rust2rpm.generator import spec_render_crate, spec_render_epel8, spec_render_project, spec_render_workspace from rust2rpm.licensing import dump_sdpx_to_fedora_map, translate_license from rust2rpm.metadata import guess_main_package, warn_if_package_uses_restrictive_dependencies from rust2rpm.utils import ( @@ -112,10 +112,11 @@ def main(): tomlconf = load_config(None, args.target) do_patch = args.patch or tomlconf.package_cargo_toml_patch_comments is not None do_patch_foreign = args.patch_foreign + do_vendor = args.vendor or args.target == "epel8" try: project, version, diffs, metadata, doc_files, license_files, is_local, vendor_tarball = process_project( - args.crate, args.version, do_patch, do_patch_foreign, args.store_crate, args.vendor + args.crate, args.version, do_patch, do_patch_foreign, args.store_crate, do_vendor ) except NoVersionsError: log.error(f"No versions are available for crate {args.crate!r}.") @@ -193,8 +194,70 @@ def main(): # basic validation for extra sources and patches validate_extra_sources_patches(tomlconf, vendor_tarball, patch_files) + # special handling for epel8 target + if args.target == "epel8": + if metadata.is_workspace(): + try: + package = guess_main_package(metadata, hint=project, interactive=args.interactive) + except ValueError: + sys.exit(1) + else: + package = metadata.packages[0] + + if build_meta := Version.parse(package.version).build: + log.error(f"Crate version {package.version!r} contains build metadata: '+{build_meta}'") + log.error(f"This is not supported by rust2rpm; remove the '+{build_meta}' suffix.") + sys.exit(1) + + if vendor_tarball and not (package.is_bin() or package.is_cdylib()): + log.error("Building library-only crates with vendored dependencies is not supported.") + sys.exit(1) + + if tomlconf.package_cargo_toml_patch_comments and patch_files[1] is None: + log.error( + "The rust2rpm.toml configuration file specifies comments for a Cargo.toml patch, " + "but Cargo.toml was not patched." + ) + sys.exit(1) + + if tomlconf.package_url: + log.error( + "The rust2rpm.toml configuration file specifies an override for the package URL, " + "but this is not valid for crates packaged from crates.io." + ) + sys.exit(1) + + if tomlconf.package_source_url: + log.error( + "The rust2rpm.toml configuration file specifies an override for the Source URL, " + "but this is not valid for crates packaged from crates.io." + ) + sys.exit(1) + + warn_if_package_uses_restrictive_dependencies(package) + + try: + spec_contents = spec_render_epel8( + metadata=metadata, + rpm_name=rpm_name, + patch_file_automatic=patch_files[0], + patch_file_manual=patch_files[1], + license_files=license_files, + doc_files=doc_files, + vendor_tarball=vendor_tarball, + tomlconf=tomlconf, + rpmautospec=args.rpmautospec, + auto_changelog_entry=args.auto_changelog_entry, + packager=packager, + ) + except ValueError as exc: + # this can happen for weird version requirements in ancient crates + # that cannot be translated correctly into RPM dependencies + log.error(f"Could not generate spec file due to invalid version requirement: {str(exc)}") + sys.exit(1) + # package for a workspace project - if metadata.is_workspace(): + elif metadata.is_workspace(): try: main_package = guess_main_package(metadata, hint=project, interactive=args.interactive) except ValueError: diff --git a/rust2rpm/cli.py b/rust2rpm/cli.py index e6e1cb0..7a3dc4c 100644 --- a/rust2rpm/cli.py +++ b/rust2rpm/cli.py @@ -35,7 +35,7 @@ def get_parser() -> argparse.ArgumentParser: "-t", "--target", action="store", - choices=("plain", "fedora", "mageia", "opensuse"), + choices=("plain", "fedora", "epel8", "mageia", "opensuse"), default=default_target, help="Distribution target", ) diff --git a/rust2rpm/conf.py b/rust2rpm/conf.py index 9b2877a..9c9ff7c 100644 --- a/rust2rpm/conf.py +++ b/rust2rpm/conf.py @@ -407,7 +407,7 @@ class IniConf: merged = conf[target] # validate configuration file - valid_targets = ["fedora", "mageia", "opensuse", "plain"] + valid_targets = ["fedora", "epel8", "mageia", "opensuse", "plain"] valid_keys = [ "summary", "supported-arches", diff --git a/rust2rpm/generator.py b/rust2rpm/generator.py index 600bad2..48c382b 100644 --- a/rust2rpm/generator.py +++ b/rust2rpm/generator.py @@ -17,6 +17,7 @@ from rust2rpm.metadata import package_uses_rust_1_60_feature_syntax, get_require RUST_PACKAGING_DEPS: dict[int, str] = { + 0: "rust-toolset", 21: "rust-packaging >= 21", 23: "rust-packaging >= 23", 24: "cargo-rpm-macros >= 24", @@ -160,6 +161,27 @@ def template_args_fedora(date: Optional[time.struct_time], packager: Optional[st return kwargs +def template_args_epel8(date: Optional[time.struct_time], packager: Optional[str], rpmautospec: bool) -> dict: + kwargs: dict[str, str | bool] = dict() + + kwargs["include_build_requires"] = False + + if rpmautospec: + kwargs["rpm_release"] = "%autorelease" + else: + kwargs["rpm_release"] = "1%{?dist}" + + rpm_changelog_date_format = "%a %b %d %Y" + if date: + kwargs["rpm_changelog_date"] = time.strftime(rpm_changelog_date_format, date) + else: + kwargs["rpm_changelog_date"] = time.strftime(rpm_changelog_date_format) + + kwargs["rpm_changelog_packager"] = packager or "rust2rpm " + + return kwargs + + def template_args_mageia(date: Optional[time.struct_time], packager: Optional[str]) -> dict: kwargs: dict[str, str | bool] = dict() @@ -447,6 +469,165 @@ def spec_render_crate( return spec_contents +def spec_render_epel8( + *, + metadata: Metadata, + rpm_name: str, + patch_file_automatic: Optional[str], + patch_file_manual: Optional[str], + license_files: list[str], + doc_files: list[str], + vendor_tarball: Optional[str], + tomlconf: TomlConf, + rpmautospec: bool, + auto_changelog_entry: bool, + date: Optional[time.struct_time] = None, + packager: Optional[str], +) -> str: + template = spec_file_template("epel8.spec") + + # enforce consistent ordering of binaries + if bin_renames := tomlconf.package_bin_renames: + binaries = [] + for old_name in metadata.get_binaries(): + if new_name := bin_renames.get(old_name): + binaries.append(new_name) + else: + binaries.append(old_name) + else: + binaries = [*metadata.get_binaries()] + binaries.sort() + + if tomlconf.package_bin_package_name is None: + bin_name = "%{crate}" + else: + bin_name = tomlconf.package_bin_package_name + + package = metadata.packages[0] + + if rpm_summary := tomlconf.package_summary: + if len(rpm_summary) > 80: + log.warn("The package Summary specified in rust2rpm.toml is too long (>80 characters).") + elif rpm_summary := package.get_summary(): + if len(rpm_summary) > 80: + log.warn( + "Heuristics for generating a short Summary failed. " + "The generated Summary string is too long (>80 characters) and needs to be shortened manually. " + "This setting can be persisted with a 'package.summary' setting in 'rust2rpm.toml'." + ) + else: + rpm_summary = "# FIXME" + + rpm_description = tomlconf.package_description or package.get_description() + + # enforce consistent ordering of feature subpackages + features: list[Optional[str]] = list(sorted(package.get_feature_names())) + if "default" in features: + features.remove("default") + features.insert(0, None) + features.insert(1, "default") + + generator_version = __version__.split(".")[0] + feature_flags = tomlconf.to_feature_flags() + + conf_lib_requires = dict() + for feature in features: + if feature is None: + conf_key = "lib" + conf_lib_requires[conf_key] = tomlconf.requires_lib or list() + else: + conf_key = f"lib+{feature}" + if requires_features := tomlconf.requires_features: + conf_lib_requires[conf_key] = requires_features.get(feature) or list() + else: + conf_lib_requires[conf_key] = list() + + if features_hide := tomlconf.features_hide: + for feature in features_hide: + features.remove(feature) + + rust_packaging_dep = RUST_PACKAGING_DEPS[0] + + required_features = get_required_features_for_binaries(package) + features_enabled_by_default = package.get_enabled_features_transitive(feature_flags)[0] + cargo_args = cargo_args_from_flags(feature_flags, required_features, features_enabled_by_default) + + if license_str := metadata.packages[0].license: + rpm_license, rpm_license_comments = translate_license("fedora", license_str) + else: + log.warn("No license information in crate metadata.") + rpm_license = None + rpm_license_comments = "# FIXME: No license information in crate metadata." + + rpm_bcond_check = tomlconf.to_bcond_check() + rpm_test_comments = tomlconf.tests_comment_lines + cargo_test_args = tomlconf.to_cargo_test_args() + + template_args_common = { + # Parameters specific to rust2rpm + "rust2rpm_version": generator_version, + "rust_packaging_dep": rust_packaging_dep, + # Paramters that control compiler flags + "build_rustflags_debuginfo": tomlconf.package_debuginfo_level, + # Parameters for RPM package metadata + "rpm_name": rpm_name, + "rpm_version": Version.parse(package.version).to_rpm(), + "rpm_summary": rpm_summary, + "rpm_description": rpm_description, + "rpm_license": rpm_license, + "rpm_license_comments": rpm_license_comments, + "rpm_patch_file_automatic": patch_file_automatic, + "rpm_patch_file_manual": patch_file_manual, + "rpm_patch_file_comments": tomlconf.package_cargo_toml_patch_comment_lines, + "rpm_license_files": license_files, + "rpm_doc_files": doc_files, + "rpm_bcond_check": rpm_bcond_check, + "rpm_test_comments": rpm_test_comments, + "rpm_vendor_source": vendor_tarball, + "rpm_extra_sources": tomlconf.package_extra_sources or list(), + "rpm_extra_patches": tomlconf.package_extra_patches or list(), + "rpm_extra_files": tomlconf.package_extra_files or list(), + # Parameters that control generation of subpackages + "rpm_binary_package_name": bin_name, + "rpm_binary_names": binaries, + # Parameters that allow injecting additional commands into scriptlets + "rpm_prep_pre": tomlconf.scripts_prep_pre or list(), + "rpm_prep_post": tomlconf.scripts_prep_post or list(), + "rpm_build_pre": tomlconf.scripts_build_pre or list(), + "rpm_build_post": tomlconf.scripts_build_post or list(), + "rpm_install_pre": tomlconf.scripts_install_pre or list(), + "rpm_install_post": tomlconf.scripts_install_post or list(), + "rpm_check_pre": tomlconf.scripts_check_pre or list(), + "rpm_check_post": tomlconf.scripts_check_post or list(), + # Parameters for crate metadata + "crate_name": package.name, + "crate_license": package.license, + # Parameters for RPM macros + "cargo_args": cargo_args, + "cargo_test_args": cargo_test_args, + # Parameters derived from rust2rpm.toml + "conf_buildrequires": tomlconf.requires_build or list(), + "conf_test_requires": tomlconf.requires_test or list(), + "conf_bin_requires": tomlconf.requires_bin or list(), + "rpm_bin_renames": renames_from_bin_name_map(tomlconf.package_bin_renames), + # Parameters derived from command-line flags + "use_rpmautospec": rpmautospec, + "make_changelog_entry": auto_changelog_entry, + } + + template_args_target = template_args_epel8(date, packager, rpmautospec) + + spec_contents = template.render( + **template_args_common, + **template_args_target, + ) + + if not spec_contents.endswith("\n"): + spec_contents += "\n" + + return spec_contents + + def spec_render_project( *, metadata: Metadata, diff --git a/rust2rpm/templates/epel8.spec b/rust2rpm/templates/epel8.spec new file mode 100644 index 0000000..a36d176 --- /dev/null +++ b/rust2rpm/templates/epel8.spec @@ -0,0 +1,184 @@ +# Generated by rust2rpm {{ rust2rpm_version }} +{% if rpm_bcond_check %} +%bcond_without check +{% else %} +{% if rpm_test_comments %} +{% for comment in rpm_test_comments %} +{{ comment }} +{% endfor %} +{% endif %} +%bcond_with check +{% endif %} +{% if build_rustflags_debuginfo %} + +# build with reduced debuginfo to work around memory limits +%global rustflags_debuginfo {{ build_rustflags_debuginfo }} +{% endif %} + +%global crate {{ crate_name }} +%global crates_source https://crates.io/api/v1/crates/%{crate}/%{version}/download#/%{crate}-%{version}.crate + +Name: {{ rpm_name }} +Version: {{ rpm_version }} +Release: {{ rpm_release }} +Summary: {{ rpm_summary }} + +{% if crate_license != rpm_license %} +# Upstream license specification: {{ crate_license|default("(missing)") }} +{% endif %} +License: {{ rpm_license|default("# FIXME") }} +{% if rpm_license_comments is not none %} +{{ rpm_license_comments }} +{% endif %} +URL: https://crates.io/crates/{{ crate_name }} +Source0: %{crates_source} +Source1: {{ rpm_vendor_source }} +Source2: LICENSE.dependencies +{% for source in rpm_extra_sources %} +{% for comment_line in source.comment_lines %} +{{ comment_line }} +{% endfor %} +Source{{ source.number }}:{{ source.whitespace }}{{ source.file }} +{% endfor %} +{% if rpm_patch_file_automatic is not none %} +# Automatically generated patch to strip dependencies and normalize metadata +Patch0: {{ rpm_patch_file_automatic }} +{% endif %} +{% if rpm_patch_file_manual is not none %} +# Manually created patch for downstream crate metadata changes +{% for comment_line in rpm_patch_file_comments %} +{{ comment_line }} +{% endfor %} +Patch1: {{ rpm_patch_file_manual }} +{% endif %} +{% for patch in rpm_extra_patches %} +{% for comment_line in patch.comment_lines %} +{{ comment_line }} +{% endfor %} +Patch{{ patch.number }}:{{ patch.whitespace }}{{ patch.file }} +{% endfor %} +{% if conf_supported_arches %} + +ExclusiveArch: {{ conf_supported_arches }} +{% endif %} + +BuildRequires: {{ rust_packaging_dep }} + {% for req in conf_buildrequires %} +BuildRequires: {{ req }} + {% endfor %} + {% if conf_test_requires %} +%if %{with check} + {% for req in conf_test_requires %} +BuildRequires: {{ req }} + {% endfor %} +%endif + {% endif %} + +%global _description %{expand: +{% if rpm_description is none %} +%{summary}. +{%- else %} +{{ rpm_description }} +{%- endif %} +} + +%description %{_description} + +%package -n {{ rpm_binary_package_name }} +Summary: %{summary} + {% if rpm_group is defined %} +Group: # FIXME + {% endif %} +License: # FIXME +# LICENSE.dependencies contains a full license breakdown +{% if conf_bin_requires %} + + {% for req in conf_bin_requires %} +Requires: {{ req }} + {% endfor %} +{% endif %} + +%description -n {{ rpm_binary_package_name }} %{_description} + +%files -n {{ rpm_binary_package_name }} + {% if rpm_license_files|length > 0 %} + {% for file in rpm_license_files %} +%license {{ file }} + {% endfor %} + {% else %} +# FIXME: no license files detected + {% endif %} +%license LICENSE.dependencies + {% for file in rpm_doc_files %} +%doc {{ file }} + {% endfor %} + {% for bin in rpm_binary_names %} +%{_bindir}/{{ bin }} + {% endfor %} + {% for file in rpm_extra_files %} +{{ file }} + {% endfor %} + +%prep +%autosetup -n %{crate}-%{version} -p1 +{% for command in rpm_prep_pre %} +{{ command }} +{% endfor %} +%cargo_prep -V 1 +cp -pav %{SOURCE2} . +{% for command in rpm_prep_post %} +{{ command }} +{% endfor %} + +%build +{% for command in rpm_build_pre %} +{{ command }} +{% endfor %} +%cargo_build{{ cargo_args }} +{% for command in rpm_build_post %} +{{ command }} +{% endfor %} + +%install +{% for command in rpm_install_pre %} +{{ command }} +{% endfor %} +%cargo_install{{ cargo_args }} +{% for rpm_bin_rename in rpm_bin_renames %} +{{ rpm_bin_rename }} +{% endfor %} +{% for command in rpm_install_post %} +{{ command }} +{% endfor %} + +%if %{with check} +%check +{% for command in rpm_check_pre %} +{{ command }} +{% endfor %} +{% if cargo_test_args %} +{% if rpm_test_comments %} +{% for comment in rpm_test_comments %} +{{ comment }} +{% endfor %} +{% endif %} +{% for args in cargo_test_args %} +%cargo_test{{ cargo_args }}{{ args }} +{% endfor %} +{% else %} +%cargo_test{{ cargo_args }} +{% endif %} +{% for command in rpm_check_post %} +{{ command }} +{% endfor %} +%endif + +%changelog +{% if use_rpmautospec %} +%autochangelog +{%- else %} +{%- if make_changelog_entry -%} + + {% include "fedora" ~ "-changelog.spec.inc" %} +{% endif %} +{% endif %} diff --git a/rust2rpm/tests/samples/bindgen-cli-0.69.4.json b/rust2rpm/tests/samples/bindgen-cli-0.69.4.json new file mode 100644 index 0000000..5f2a8e6 --- /dev/null +++ b/rust2rpm/tests/samples/bindgen-cli-0.69.4.json @@ -0,0 +1 @@ +{"packages":[{"name":"bindgen-cli","version":"0.69.4","id":"path+file:///home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4#bindgen-cli@0.69.4","license":"BSD-3-Clause","license_file":null,"description":"Automatically generates Rust FFI bindings to C and C++ libraries.","source":null,"dependencies":[{"name":"bindgen","source":"registry+https://github.com/rust-lang/crates.io-index","req":"=0.69.4","kind":null,"rename":null,"optional":false,"uses_default_features":false,"features":["__cli","experimental"],"target":null,"registry":null},{"name":"clap","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^4","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":["derive"],"target":null,"registry":null},{"name":"clap_complete","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^4","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"env_logger","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^0.10.0","kind":null,"rename":null,"optional":true,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"log","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^0.4","kind":null,"rename":null,"optional":true,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"shlex","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^1","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null}],"targets":[{"kind":["bin"],"crate_types":["bin"],"name":"bindgen","src_path":"/home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4/main.rs","edition":"2018","doc":true,"doctest":false,"test":true}],"features":{"__testing_only_extra_assertions":["bindgen/__testing_only_extra_assertions"],"__testing_only_libclang_16":["bindgen/__testing_only_libclang_16"],"__testing_only_libclang_9":["bindgen/__testing_only_libclang_9"],"default":["logging","runtime","which-rustfmt"],"logging":["bindgen/logging","dep:env_logger","dep:log"],"runtime":["bindgen/runtime"],"static":["bindgen/static"],"which-rustfmt":["bindgen/which-rustfmt"]},"manifest_path":"/home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4/Cargo.toml","metadata":{"dist":{"dist":true},"release":{"release":true}},"publish":null,"authors":["The rust-bindgen project contributors"],"categories":["external-ffi-bindings","development-tools::ffi"],"keywords":["bindings","ffi","code-generation"],"readme":"README.md","repository":"https://github.com/rust-lang/rust-bindgen","homepage":"https://rust-lang.github.io/rust-bindgen/","documentation":"https://docs.rs/bindgen","edition":"2018","links":null,"default_run":null,"rust_version":"1.64.0"}],"workspace_members":["path+file:///home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4#bindgen-cli@0.69.4"],"workspace_default_members":["path+file:///home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4#bindgen-cli@0.69.4"],"resolve":null,"target_directory":"/home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4/target","version":1,"workspace_root":"/home/deca/Workspace/rust2rpm-epel-8/rust-bindgen-cli/bindgen-cli-0.69.4","metadata":null} diff --git a/rust2rpm/tests/samples/bindgen-cli-0.69.4.rust2rpm.toml b/rust2rpm/tests/samples/bindgen-cli-0.69.4.rust2rpm.toml new file mode 100644 index 0000000..9018a30 --- /dev/null +++ b/rust2rpm/tests/samples/bindgen-cli-0.69.4.rust2rpm.toml @@ -0,0 +1,4 @@ +[requires] +build = ["clang-devel"] +bin = ["clang-libs"] + diff --git a/rust2rpm/tests/samples/bindgen-cli-0.69.4.spec b/rust2rpm/tests/samples/bindgen-cli-0.69.4.spec new file mode 100644 index 0000000..4523c21 --- /dev/null +++ b/rust2rpm/tests/samples/bindgen-cli-0.69.4.spec @@ -0,0 +1,64 @@ +# Generated by rust2rpm NNN +%bcond_without check + +%global crate bindgen-cli +%global crates_source https://crates.io/api/v1/crates/%{crate}/%{version}/download#/%{crate}-%{version}.crate + +Name: rust-bindgen-cli +Version: 0.69.4 +Release: %autorelease +Summary: Automatically generates Rust FFI bindings to C and C++ libraries + +License: BSD-3-Clause +URL: https://crates.io/crates/bindgen-cli +Source0: %{crates_source} +Source1: %{crate}-%{version}-vendor.tar.xz +Source2: LICENSE.dependencies +# Automatically generated patch to strip dependencies and normalize metadata +Patch0: bindgen-cli-patch1.diff +# Manually created patch for downstream crate metadata changes +Patch1: bindgen-cli-patch2.diff + +BuildRequires: rust-toolset +BuildRequires: clang-devel + +%global _description %{expand: +Automatically generates Rust FFI bindings to C and C++ libraries.} + +%description %{_description} + +%package -n %{crate} +Summary: %{summary} +License: # FIXME +# LICENSE.dependencies contains a full license breakdown + +Requires: clang-libs + +%description -n %{crate} %{_description} + +%files -n %{crate} +%license LIC1 +%license LIC2 +%license LICENSE.dependencies +%doc DOC1 +%doc DOC2 +%{_bindir}/bindgen + +%prep +%autosetup -n %{crate}-%{version} -p1 +%cargo_prep -V 1 +cp -pav %{SOURCE2} . + +%build +%cargo_build + +%install +%cargo_install + +%if %{with check} +%check +%cargo_test +%endif + +%changelog +%autochangelog diff --git a/rust2rpm/tests/test_generator.py b/rust2rpm/tests/test_generator.py index 48f9eb4..472d02b 100644 --- a/rust2rpm/tests/test_generator.py +++ b/rust2rpm/tests/test_generator.py @@ -9,7 +9,13 @@ from cargo2rpm.metadata import Metadata, FeatureFlags import pytest from rust2rpm.conf import TomlConf -from rust2rpm.generator import spec_render_crate, spec_render_project, spec_render_workspace, cargo_args_from_flags +from rust2rpm.generator import ( + spec_render_crate, + spec_render_epel8, + spec_render_project, + spec_render_workspace, + cargo_args_from_flags, +) from rust2rpm.metadata import guess_main_package from rust2rpm.patching import preprocess_cargo_toml from rust2rpm.utils import package_name_suffixed @@ -90,6 +96,55 @@ def test_spec_file_render_crate(filename: str, conf: Optional[str], target: str) assert rendered == expected +@pytest.mark.parametrize( + "filename,conf", + [ + ("bindgen-cli-0.69.4.json", "bindgen-cli-0.69.4.rust2rpm.toml"), + ], +) +def test_spec_file_render_epel8(filename: str, conf: Optional[str]): + crate_name_version = filename.removesuffix(".json") + crate = crate_name_version.rsplit("-", 1)[0] + + rpm_name = package_name_suffixed(crate, None) + real_path = resources.files("rust2rpm.tests.samples").joinpath(filename) + metadata = Metadata.from_json(real_path.read_text()) + + if conf: + toml_path = resources.files("rust2rpm.tests.samples").joinpath(conf) + tomlconf = TomlConf.load(str(toml_path), metadata.packages[0].get_feature_names()) + else: + tomlconf = TomlConf() + + rendered = spec_render_epel8( + metadata=metadata, + rpm_name=rpm_name, + patch_file_automatic=f"{crate}-patch1.diff", + patch_file_manual=f"{crate}-patch2.diff", + license_files=["LIC1", "LIC2"], + doc_files=["DOC1", "DOC2"], + vendor_tarball="%{crate}-%{version}-vendor.tar.xz", + tomlconf=tomlconf, + rpmautospec=True, + auto_changelog_entry=True, + date=FIXED_DATE, + packager="Jane Jane ", + ) + + rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered) + + fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.spec") + fixture_path = cast(Path, fixture_path) + + if os.getenv("UPDATE_FIXTURES") == "1": # pragma nocover + # helper mode to create test data + fixture_path.write_text(rendered) + + else: + expected = fixture_path.read_text() + assert rendered == expected + + @pytest.mark.parametrize( "filename,vendor_tarball", [ diff --git a/rust2rpm/utils.py b/rust2rpm/utils.py index b85f278..8afdb81 100644 --- a/rust2rpm/utils.py +++ b/rust2rpm/utils.py @@ -152,7 +152,7 @@ def detect_rpmautospec(default_target: str, spec_file: Path): """ # We default to on only for selected distros for now… - if default_target not in {"fedora"}: + if default_target not in {"fedora", "epel8"}: return False try: