diff --git a/requirements.txt b/requirements.txt index 5ae47d3..d443463 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -cargo2rpm>=0.1.11 +cargo2rpm>=0.1.12 jinja2 jsonschema pyparsing diff --git a/rust2rpm/generator.py b/rust2rpm/generator.py index 89dfadf..bc108d4 100644 --- a/rust2rpm/generator.py +++ b/rust2rpm/generator.py @@ -130,7 +130,7 @@ def spec_render_crate( auto_changelog_entry: bool, date: Optional[time.struct_time] = None, packager: Optional[str], -): +) -> str: template = spec_file_template("crate.spec") # enforce consistent ordering of binaries @@ -290,6 +290,154 @@ def spec_render_crate( return spec_contents +def spec_render_project( + *, + metadata: Metadata, + upstream_version: str, + target: str, + rpm_name: str, + patch_file_automatic: Optional[str], + patch_file_manual: Optional[str], + license_files: list[str], + doc_files: list[str], + tomlconf: TomlConf, + feature_flags: FeatureFlags, + relative_license_paths: bool, + rpmautospec: bool, + auto_changelog_entry: bool, + date: Optional[time.struct_time] = None, + packager: Optional[str], +) -> str: + template = spec_file_template("project.spec") + + # enforce consistent ordering of binaries + binaries = [*metadata.get_binaries()] + binaries.sort() + + is_bin = metadata.is_bin() + is_lib = metadata.is_lib() + is_cdylib = metadata.is_cdylib() + + package = metadata.packages[0] + description = package.get_description() + summary = package.get_summary() + + generator_version = __version__.split(".")[0] + + buildrequires = rpm.buildrequires(package, feature_flags, False) + test_requires = set.difference( + rpm.buildrequires(package, feature_flags, True), rpm.buildrequires(package, feature_flags, False) + ) + + rpm_buildrequires = list(sorted(buildrequires)) + rpm_test_requires = list(sorted(test_requires)) + + if package_uses_rust_1_60_feature_syntax(package.features): + rust_packaging_dep = "cargo-rpm-macros >= 24" + elif is_bin or is_cdylib: + rust_packaging_dep = "rust-packaging >= 23" + else: + rust_packaging_dep = "rust-packaging >= 21" + + if feature_flags.all_features or tomlconf.features_enable_all: + cargo_args = " -a" + elif required_features := get_required_features_for_binaries(package): + # remove required features that are already part of the enabled feature set + enabled_by_default = package.get_enabled_features_transitive(feature_flags)[0] + for f in enabled_by_default: + if f in required_features: + required_features.remove(f) + + # merge, de-duplicate, and re-sort lists of enabled features + if features_enable := tomlconf.features_enable: + enabled_features = sorted(set.union(set(required_features), set(features_enable))) + else: + enabled_features = sorted(required_features) + + if len(enabled_features) > 0: + cargo_args = f" -f {','.join(enabled_features)}" + else: + cargo_args = "" + elif tomlconf.features_enable: + # list of features is already sorted when parsing the configuration file + cargo_args = f" -f {','.join(tomlconf.features_enable)}" + else: + cargo_args = "" + + if license_str := metadata.packages[0].license: + rpm_license, rpm_license_comments = translate_license(target, license_str) + else: + log.warn("No license information in crate metadata.") + rpm_license = None + rpm_license_comments = "# FIXME: No license information in crate metadata." + + if supported_arches := tomlconf.package_supported_arches: + conf_supported_arches = " ".join(supported_arches) + else: + conf_supported_arches = None + + template_args_common = { + # Parameters specific to rust2rpm + "rust2rpm_version": generator_version, + "rust2rpm_target": target, + "rust_packaging_dep": rust_packaging_dep, + # Parameters for RPM package metadata + "rpm_name": rpm_name, + "rpm_version": Version.parse(package.version).to_rpm(), + "rpm_summary": tomlconf.package_summary or summary, + "rpm_description": tomlconf.package_description or description, + "rpm_url": package.homepage or package.repository or "# FIXME", + "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_buildrequires": rpm_buildrequires, + "rpm_test_requires": rpm_test_requires, + "rpm_license_files": license_files, + "rpm_doc_files": doc_files, + # Parameters that control generation of subpackages + "rpm_binary_package": is_bin, + "rpm_cdylib_package": is_cdylib, + "rpm_binary_names": binaries, + # Parameters for crate metadata + "crate_name": package.name, + "crate_version": package.version, + "crate_license": package.license, + "upstream_version": upstream_version, + # Parameters derived from rust2rpm.conf + "conf_buildrequires": tomlconf.requires_build or list(), + "conf_test_requires": tomlconf.requires_test or list(), + "conf_bin_requires": tomlconf.requires_bin or list(), + "conf_supported_arches": conf_supported_arches, + # Parameters derived from command-line flags + "cargo_args": cargo_args, + "use_rpmautospec": rpmautospec, + "make_changelog_entry": auto_changelog_entry, + } + + match target: + case "fedora": + template_args_target = template_args_fedora(date, packager, rpmautospec) + case "mageia": + template_args_target = template_args_mageia(date, packager) + case "opensuse": + template_args_target = template_args_opensuse(date, packager) + case "plain": + template_args_target = template_args_plain(date, packager) + case _: + raise ValueError(f"Unknown target {target!r} (this should never happen)") + + 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_workspace( *, metadata: Metadata, diff --git a/rust2rpm/templates/README.md b/rust2rpm/templates/README.md index 6e77222..6bb3d22 100644 --- a/rust2rpm/templates/README.md +++ b/rust2rpm/templates/README.md @@ -41,11 +41,12 @@ ### Parameters for crate metadata -| parameter name | type | value | -| --------------- | --------------- | --------------------------------------------------------- | -| `crate_name` | `str` | crate name (from `Cargo.toml` metadata) | -| `crate_version` | `str` | crate version (from `Cargo.toml` metadata, SemVer format) | -| `crate_license` | `Optional[str]` | crate license (from `Cargo.toml` metadata) | +| parameter name | type | value | +| ------------------ | --------------- | --------------------------------------------------------- | +| `crate_name` | `str` | crate name (from `Cargo.toml` metadata) | +| `crate_version` | `str` | crate version (from `Cargo.toml` metadata, SemVer format) | +| `crate_license` | `Optional[str]` | crate license (from `Cargo.toml` metadata) | +| `upstream_version` | `str` | upstream crate version (from `crates.io`) | ### Parameters derived from rust2rpm.conf @@ -78,6 +79,78 @@ | `rpm_changelog_date` | `str` | date for automatically generated `%changelog` entry | | `rpm_changelog_packager` | `str` | packager for automatically generated `%changelog` entry | +## Template for non-crate projects (no cargo workspace) + +### Parameters specific to rust2rpm + +| parameter name | type | value | +| -------------------- | ----- | ---------------------------------------------- | +| `rust2rpm_version` | `str` | current major version of rust2rpm | +| `rust2rpm_target` | `str` | target OS (fedora, mageia, opensuse, plain) | +| `rust_packaging_dep` | `str` | dependency string for RPM Rust packaging tools | + +### Parameters for RPM package metadata + +| parameter name | type | value | +| -------------------------- | ---------------------- | ------------------------------------------------------------------------------------ | +| `rpm_name` | `str` | RPM source package Name (`rust-{crate}{suffix}`) | +| `rpm_version` | `str` | RPM package Version (translated to RPM format from SemVer) | +| `rpm_summary` | `Optional[str]` | RPM package summary (derived from `package.description` value from `Cargo.toml`) | +| `rpm_description` | `Optional[str]` | RPM package description (derived from `package.description` value from `Cargo.toml`) | +| `rpm_url` | `Optional[str]` | URL for the crate (either homepage or repository URL) | +| `rpm_license` | `Optional[str]` | RPM License tag (derived from `package.license` value from `Cargo.toml`) | +| `rpm_license_comments` | `Optional[str]` | additional information returned by license string translation | +| `rpm_patch_file_automatic` | `Optional[str]` | name of the automatically generated patch file | +| `rpm_patch_file_manual` | `Optional[str]` | name of the manually generated patch file | +| `rpm_buildrequires` | `list[str]` | list of RPM `BuildRequires` | +| `rpm_test_requires` | `list[str]` | list of RPM `BuildRequires` that are gated by an `%if %{with check}` conditional | +| `rpm_license_files` | `list[str]` | list of the license files which were detected in crate sources | +| `rpm_doc_files` | `list[str]` | list of the documentation files which were detected in crate sources | + +### Parameters that control generation of subpackages + +| parameter name | type | value | +| --------------------- | --------------------- | --------------------------------------------------------------------------- | +| `rpm_binary_package` | `bool` | `True` if package ships any binaries, `False` for source-only packages | +| `rpm_cdylib_package` | `bool` | `True` if package ships any shared libraries (`cdylib` targets) | +| `rpm_binary_names` | `list[str]` | list of the names of executables which are built from the crate | + +### Parameters for crate metadata + +| parameter name | type | value | +| ------------------ | --------------- | --------------------------------------------------------- | +| `crate_name` | `str` | crate name (from `Cargo.toml` metadata) | +| `crate_version` | `str` | crate version (from `Cargo.toml` metadata, SemVer format) | +| `crate_license` | `Optional[str]` | crate license (from `Cargo.toml` metadata) | +| `upstream_version` | `str` | upstream crate version (from `crates.io`) | + +### Parameters derived from rust2rpm.conf + +| parameter name | type | value | +| ----------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------ | +| `conf_buildrequires` | `list[str]` | list of additional RPM `BuildRequires` specified in `rust2rpm.conf` | +| `conf_test_requires` | `list[str]` | list of additional RPM `BuildRequires` specified in `rust2rpm.conf` that are gated by an `%if %{with check}` conditional | +| `conf_bin_requires` | `list[str]` | list of additional RPM `Requires` for the binary package specified in `rust2rpm.conf` | +| `conf_supported_arches` | `list[str]` | list of supported architectures (results in `%ifarch` conditionals around `%cargo_build` and `%cargo_test` macros) | + +### Parameters derived from command-line flags + +| parameter name | type | value | +| ---------------------------- | ------ | -------------------------------------------------------------------------------- | +| `cargo_args` | `str` | flags that are added to all `%cargo_foo` macro calls | +| `use_rpmautospec` | `bool` | toggle usage of RPMAutospec in generated spec files | +| `make_changelog_entry` | `bool` | toggle creation of changelog entry in generated spec files | + +### Target-specific parameters + +| parameter name | type | value | +| ------------------------ | ------ | --------------------------------------------------------------- | +| `rpm_release` | `str` | RPM package Release (exact value depends on the target OS) | +| `include_build_requires` | `bool` | toggle between dynamically generated and static `BuildRequires` | +| `rpm_group` | `str` | RPM Group tag (not defined on for all target OS) | +| `rpm_changelog_date` | `str` | date for automatically generated `%changelog` entry | +| `rpm_changelog_packager` | `str` | packager for automatically generated `%changelog` entry | + ## Template for non-crate projects (with cargo workspace) ### Parameters specific to rust2rpm diff --git a/rust2rpm/templates/project.spec b/rust2rpm/templates/project.spec new file mode 100644 index 0000000..26f059e --- /dev/null +++ b/rust2rpm/templates/project.spec @@ -0,0 +1,184 @@ +{% include rust2rpm_target ~ "-header.spec.inc" ignore missing %} +# Generated by rust2rpm {{ rust2rpm_version }} +%bcond_without check + +# prevent library files from being installed +%global __cargo_is_lib() 0 + +%global crate {{ crate_name }} +{% if crate_version != rpm_version %} +%global crate_version {{ crate_version }} +{% endif %} +{% if crate_version != upstream_version %} +%global upstream_version {{ upstream_version }} +{% endif %} +{% if conf_supported_arches %} + +# compile and run tests only on supported architectures +%global supported_arches {{ conf_supported_arches }} +{% endif %} + +Name: {{ rpm_name }} +Version: {{ rpm_version }} +Release: {{ rpm_release }} +{% if rpm_summary is none %} +Summary: # FIXME +{% else %} +Summary: {{ rpm_summary }} +{% endif %} +{% if rpm_group is defined %} +Group: {{ rpm_group }} +{% endif %} + +{% if crate_license != rpm_license %} +# Upstream license specification: {{ crate_license|default("(missing)") }} +{% endif %} +SourceLicense: {{ rpm_license|default("# FIXME") }} +# FIXME: paste output of %%cargo_license_summary here +License: # FIXME +# LICENSE.dependencies contains a full license breakdown +{% if rpm_license_comments is not none %} +{{ rpm_license_comments }} +{% endif %} + +{% if rpm_url %} +URL: {{ rpm_url }} +{% endif %} +Source: # FIXME +{% if rpm_patch_file_automatic is not none %} +# Automatically generated patch to strip dependencies and normalize metadata +Patch: {{ rpm_patch_file_automatic }} +{% endif %} +{% if rpm_patch_file_manual is not none %} +{% if rust2rpm_target == "opensuse" %} +# PATCH-FIX-OPENSUSE {{ rpm_patch_file_manual }} — Manually created patch for downstream crate metadata changes +{% else %} +# Manually created patch for downstream crate metadata changes +{% endif %} +Patch: {{ rpm_patch_file_manual }} +{% endif %} + +{% if rust2rpm_target != "fedora" %} +ExclusiveArch: %{rust_arches} + +{% endif %} +BuildRequires: {{ rust_packaging_dep }} +{% if include_build_requires %} + {% for req in rpm_buildrequires %} +BuildRequires: {{ req }} + {% endfor %} + {% if rpm_test_requires|length > 0 %} +%if %{with check} + {% for req in rpm_test_requires %} +BuildRequires: {{ req }} + {% endfor %} +%endif + {% endif %} + {% 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 %} +{% endif %} +{% for req in conf_bin_requires %} +Requires: {{ req }} +{% endfor %} + +%global _description %{expand: +{% if rpm_description is none %} +%{summary}. +{%- else %} +{{ rpm_description }} +{%- endif %} +} + +%description %{_description} + +%prep +{% if crate_version != rpm_version %} +%autosetup -n %{crate}-%{crate_version} -p1 +{% elif crate_version != upstream_version %} +%autosetup -n %{crate}-%{upstream_version} -p1 +{% else %} +%autosetup -n %{crate}-%{version} -p1 +{% endif %} +%cargo_prep + +{% if not include_build_requires %} +%generate_buildrequires +%cargo_generate_buildrequires{{ cargo_args }} + {% for req in conf_buildrequires %} +echo {{ "%r" | format(req) }} + {% endfor %} + {% if conf_test_requires %} +%if %{with check} + {% for req in conf_test_requires %} +echo {{ "%r" | format(req) }} + {% endfor %} +%endif + {% endif %} + +{% endif -%} + +%build +{% if conf_supported_arches %} +%ifarch %{supported_arches} +{% endif %} +%cargo_build{{ cargo_args }} +{% if conf_supported_arches %} +%endif +{% endif %} +%{cargo_license_summary{{ cargo_args }}} +%{cargo_license{{ cargo_args }}} > LICENSE.dependencies + +%install +{% if rpm_cdylib_package and rpm_binary_package %} +%cargo_install{{ cargo_args }} +# FIXME: install shared library +{% elif rpm_cdylib_package %} +# FIXME: install shared library +{% else %} +%cargo_install{{ cargo_args }} +{% endif %} + +%if %{with check} +{% if conf_supported_arches %} +%ifarch %{supported_arches} +{% endif %} +%check +%cargo_test{{ cargo_args }} +{% if conf_supported_arches %} +%endif +{% endif %} +%endif + +%files + {% if rpm_license_files|length > 0 %} + {% for file in rpm_license_files %} +%license {{ file }} + {% endfor %} +%license LICENSE.dependencies + {% else %} +# FIXME: no license files detected + {% endif %} + {% for file in rpm_doc_files %} +%doc {{ file }} + {% endfor %} + {% for bin in rpm_binary_names %} +%{_bindir}/{{ bin }} + {% endfor %} + +%changelog +{% if use_rpmautospec %} +%autochangelog +{%- else %} +{%- if make_changelog_entry -%} + + {% include rust2rpm_target ~ "-changelog.spec.inc" %} +{% endif %} +{% endif %} diff --git a/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.fedora.spec b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.fedora.spec new file mode 100644 index 0000000..f511810 --- /dev/null +++ b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.fedora.spec @@ -0,0 +1,62 @@ +# Generated by rust2rpm NNN +%bcond_without check + +# prevent library files from being installed +%global __cargo_is_lib() 0 + +%global crate rust2rpm-helper + +Name: rust2rpm-helper +Version: 0.1.3 +Release: %autorelease +Summary: Helper program for rust2rpm + +SourceLicense: MIT +# FIXME: paste output of %%cargo_license_summary here +License: # FIXME +# LICENSE.dependencies contains a full license breakdown + +URL: https://pagure.io/fedora-rust/rust2rpm-helper +Source: # FIXME +# Automatically generated patch to strip dependencies and normalize metadata +Patch: rust2rpm-helper-patch1.diff +# Manually created patch for downstream crate metadata changes +Patch: rust2rpm-helper-patch2.diff + +BuildRequires: rust-packaging >= 23 + +%global _description %{expand: +Helper program for rust2rpm.} + +%description %{_description} + +%prep +%autosetup -n %{crate}-%{version} -p1 +%cargo_prep + +%generate_buildrequires +%cargo_generate_buildrequires + +%build +%cargo_build +%{cargo_license_summary} +%{cargo_license} > LICENSE.dependencies + +%install +%cargo_install + +%if %{with check} +%check +%cargo_test +%endif + +%files +%license LIC1 +%license LIC2 +%license LICENSE.dependencies +%doc DOC1 +%doc DOC2 +%{_bindir}/rust2rpm-helper + +%changelog +%autochangelog diff --git a/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.json b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.json new file mode 100644 index 0000000..42a04d8 --- /dev/null +++ b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.json @@ -0,0 +1 @@ +{"packages":[{"name":"rust2rpm-helper","version":"0.1.3","id":"rust2rpm-helper 0.1.3 (path+file:///home/deca/Projects/rust/rust2rpm-helper)","license":"MIT","license_file":null,"description":"Helper program for rust2rpm","source":null,"dependencies":[{"name":"anyhow","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},{"name":"cfg-expr","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^0.15","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"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":"env_logger","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^0.10","kind":null,"rename":null,"optional":false,"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":false,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"similar","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^2","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"toml_edit","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^0.19","kind":null,"rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null},{"name":"pretty_assertions","source":"registry+https://github.com/rust-lang/crates.io-index","req":"^1","kind":"dev","rename":null,"optional":false,"uses_default_features":true,"features":[],"target":null,"registry":null}],"targets":[{"kind":["lib"],"crate_types":["lib"],"name":"rust2rpm-helper","src_path":"/home/deca/Projects/rust/rust2rpm-helper/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},{"kind":["bin"],"crate_types":["bin"],"name":"rust2rpm-helper","src_path":"/home/deca/Projects/rust/rust2rpm-helper/src/main.rs","edition":"2021","doc":true,"doctest":false,"test":true},{"kind":["test"],"crate_types":["bin"],"name":"tests","src_path":"/home/deca/Projects/rust/rust2rpm-helper/tests/tests.rs","edition":"2021","doc":false,"doctest":false,"test":true}],"features":{},"manifest_path":"/home/deca/Projects/rust/rust2rpm-helper/Cargo.toml","metadata":null,"publish":[],"authors":["Fabio Valentini "],"categories":["command-line-utilities"],"keywords":["rust2rpm","patch"],"readme":"README.md","repository":"https://pagure.io/fedora-rust/rust2rpm-helper","homepage":null,"documentation":null,"edition":"2021","links":null,"default_run":null,"rust_version":"1.65.0"}],"workspace_members":["rust2rpm-helper 0.1.3 (path+file:///home/deca/Projects/rust/rust2rpm-helper)"],"workspace_default_members":["rust2rpm-helper 0.1.3 (path+file:///home/deca/Projects/rust/rust2rpm-helper)"],"resolve":null,"target_directory":"/home/deca/Projects/rust/rust2rpm-helper/target","version":1,"workspace_root":"/home/deca/Projects/rust/rust2rpm-helper","metadata":null} diff --git a/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.mageia.spec b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.mageia.spec new file mode 100644 index 0000000..473bfd8 --- /dev/null +++ b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.mageia.spec @@ -0,0 +1,75 @@ +# Generated by rust2rpm NNN +%bcond_without check + +# prevent library files from being installed +%global __cargo_is_lib() 0 + +%global crate rust2rpm-helper + +Name: rust2rpm-helper +Version: 0.1.3 +Release: %mkrel 1 +Summary: Helper program for rust2rpm +Group: Development/Rust + +SourceLicense: MIT +# FIXME: paste output of %%cargo_license_summary here +License: # FIXME +# LICENSE.dependencies contains a full license breakdown + +URL: https://pagure.io/fedora-rust/rust2rpm-helper +Source: # FIXME +# Automatically generated patch to strip dependencies and normalize metadata +Patch: rust2rpm-helper-patch1.diff +# Manually created patch for downstream crate metadata changes +Patch: rust2rpm-helper-patch2.diff + +ExclusiveArch: %{rust_arches} + +BuildRequires: rust-packaging >= 23 +BuildRequires: (crate(anyhow/default) >= 1.0.0 with crate(anyhow/default) < 2.0.0~) +BuildRequires: (crate(cfg-expr/default) >= 0.15.0 with crate(cfg-expr/default) < 0.16.0~) +BuildRequires: (crate(clap/default) >= 4.0.0 with crate(clap/default) < 5.0.0~) +BuildRequires: (crate(clap/derive) >= 4.0.0 with crate(clap/derive) < 5.0.0~) +BuildRequires: (crate(env_logger/default) >= 0.10.0 with crate(env_logger/default) < 0.11.0~) +BuildRequires: (crate(log/default) >= 0.4.0 with crate(log/default) < 0.5.0~) +BuildRequires: (crate(similar/default) >= 2.0.0 with crate(similar/default) < 3.0.0~) +BuildRequires: (crate(toml_edit/default) >= 0.19.0 with crate(toml_edit/default) < 0.20.0~) +BuildRequires: rust >= 1.65.0 +%if %{with check} +BuildRequires: (crate(pretty_assertions/default) >= 1.0.0 with crate(pretty_assertions/default) < 2.0.0~) +%endif + +%global _description %{expand: +Helper program for rust2rpm.} + +%description %{_description} + +%prep +%autosetup -n %{crate}-%{version} -p1 +%cargo_prep + +%build +%cargo_build +%{cargo_license_summary} +%{cargo_license} > LICENSE.dependencies + +%install +%cargo_install + +%if %{with check} +%check +%cargo_test +%endif + +%files +%license LIC1 +%license LIC2 +%license LICENSE.dependencies +%doc DOC1 +%doc DOC2 +%{_bindir}/rust2rpm-helper + +%changelog +* Thu Jan 01 1970 Jane Jane - 0.1.3-1 +- Initial package diff --git a/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.opensuse.spec b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.opensuse.spec new file mode 100644 index 0000000..d67762d --- /dev/null +++ b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.opensuse.spec @@ -0,0 +1,93 @@ +# +# spec file for package rust2rpm-helper +# +# Copyright (c) XXXX Jane Jane . +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + +# Generated by rust2rpm NNN +%bcond_without check + +# prevent library files from being installed +%global __cargo_is_lib() 0 + +%global crate rust2rpm-helper + +Name: rust2rpm-helper +Version: 0.1.3 +Release: 0 +Summary: Helper program for rust2rpm +Group: Development/Libraries/Rust + +SourceLicense: MIT +# FIXME: paste output of %%cargo_license_summary here +License: # FIXME +# LICENSE.dependencies contains a full license breakdown + +URL: https://pagure.io/fedora-rust/rust2rpm-helper +Source: # FIXME +# Automatically generated patch to strip dependencies and normalize metadata +Patch: rust2rpm-helper-patch1.diff +# PATCH-FIX-OPENSUSE rust2rpm-helper-patch2.diff — Manually created patch for downstream crate metadata changes +Patch: rust2rpm-helper-patch2.diff + +ExclusiveArch: %{rust_arches} + +BuildRequires: rust-packaging >= 23 +BuildRequires: (crate(anyhow/default) >= 1.0.0 with crate(anyhow/default) < 2.0.0~) +BuildRequires: (crate(cfg-expr/default) >= 0.15.0 with crate(cfg-expr/default) < 0.16.0~) +BuildRequires: (crate(clap/default) >= 4.0.0 with crate(clap/default) < 5.0.0~) +BuildRequires: (crate(clap/derive) >= 4.0.0 with crate(clap/derive) < 5.0.0~) +BuildRequires: (crate(env_logger/default) >= 0.10.0 with crate(env_logger/default) < 0.11.0~) +BuildRequires: (crate(log/default) >= 0.4.0 with crate(log/default) < 0.5.0~) +BuildRequires: (crate(similar/default) >= 2.0.0 with crate(similar/default) < 3.0.0~) +BuildRequires: (crate(toml_edit/default) >= 0.19.0 with crate(toml_edit/default) < 0.20.0~) +BuildRequires: rust >= 1.65.0 +%if %{with check} +BuildRequires: (crate(pretty_assertions/default) >= 1.0.0 with crate(pretty_assertions/default) < 2.0.0~) +%endif + +%global _description %{expand: +Helper program for rust2rpm.} + +%description %{_description} + +%prep +%autosetup -n %{crate}-%{version} -p1 +%cargo_prep + +%build +%cargo_build +%{cargo_license_summary} +%{cargo_license} > LICENSE.dependencies + +%install +%cargo_install + +%if %{with check} +%check +%cargo_test +%endif + +%files +%license LIC1 +%license LIC2 +%license LICENSE.dependencies +%doc DOC1 +%doc DOC2 +%{_bindir}/rust2rpm-helper + +%changelog +* Thu Jan 01 03:25:45 GMT 1970 Jane Jane +- Version 0.1.3 +- Initial package diff --git a/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.plain.spec b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.plain.spec new file mode 100644 index 0000000..47b289b --- /dev/null +++ b/rust2rpm/tests/samples/rust2rpm-helper-0.1.3.plain.spec @@ -0,0 +1,74 @@ +# Generated by rust2rpm NNN +%bcond_without check + +# prevent library files from being installed +%global __cargo_is_lib() 0 + +%global crate rust2rpm-helper + +Name: rust2rpm-helper +Version: 0.1.3 +Release: 1%{?dist} +Summary: Helper program for rust2rpm + +SourceLicense: MIT +# FIXME: paste output of %%cargo_license_summary here +License: # FIXME +# LICENSE.dependencies contains a full license breakdown + +URL: https://pagure.io/fedora-rust/rust2rpm-helper +Source: # FIXME +# Automatically generated patch to strip dependencies and normalize metadata +Patch: rust2rpm-helper-patch1.diff +# Manually created patch for downstream crate metadata changes +Patch: rust2rpm-helper-patch2.diff + +ExclusiveArch: %{rust_arches} + +BuildRequires: rust-packaging >= 23 +BuildRequires: (crate(anyhow/default) >= 1.0.0 with crate(anyhow/default) < 2.0.0~) +BuildRequires: (crate(cfg-expr/default) >= 0.15.0 with crate(cfg-expr/default) < 0.16.0~) +BuildRequires: (crate(clap/default) >= 4.0.0 with crate(clap/default) < 5.0.0~) +BuildRequires: (crate(clap/derive) >= 4.0.0 with crate(clap/derive) < 5.0.0~) +BuildRequires: (crate(env_logger/default) >= 0.10.0 with crate(env_logger/default) < 0.11.0~) +BuildRequires: (crate(log/default) >= 0.4.0 with crate(log/default) < 0.5.0~) +BuildRequires: (crate(similar/default) >= 2.0.0 with crate(similar/default) < 3.0.0~) +BuildRequires: (crate(toml_edit/default) >= 0.19.0 with crate(toml_edit/default) < 0.20.0~) +BuildRequires: rust >= 1.65.0 +%if %{with check} +BuildRequires: (crate(pretty_assertions/default) >= 1.0.0 with crate(pretty_assertions/default) < 2.0.0~) +%endif + +%global _description %{expand: +Helper program for rust2rpm.} + +%description %{_description} + +%prep +%autosetup -n %{crate}-%{version} -p1 +%cargo_prep + +%build +%cargo_build +%{cargo_license_summary} +%{cargo_license} > LICENSE.dependencies + +%install +%cargo_install + +%if %{with check} +%check +%cargo_test +%endif + +%files +%license LIC1 +%license LIC2 +%license LICENSE.dependencies +%doc DOC1 +%doc DOC2 +%{_bindir}/rust2rpm-helper + +%changelog +* Thu Jan 01 1970 Jane Jane - 0.1.3-1 +- Initial package diff --git a/rust2rpm/tests/test_generator.py b/rust2rpm/tests/test_generator.py index 9bf5f0c..7542b42 100644 --- a/rust2rpm/tests/test_generator.py +++ b/rust2rpm/tests/test_generator.py @@ -10,7 +10,7 @@ import pytest from rust2rpm.cli import get_parser from rust2rpm.conf import TomlConf -from rust2rpm.generator import spec_render_crate, spec_render_workspace +from rust2rpm.generator import spec_render_crate, spec_render_project, spec_render_workspace from rust2rpm.metadata import guess_main_package from rust2rpm.patching import preprocess_cargo_toml from rust2rpm.utils import package_name_suffixed @@ -78,6 +78,52 @@ def test_spec_file_render_crate(filename: str, target: str): assert rendered == expected +@pytest.mark.parametrize("filename", ["rust2rpm-helper-0.1.3.json"]) +@pytest.mark.parametrize("target", ["plain", "fedora", "mageia", "opensuse"]) +def test_spec_file_render_project(filename: str, target: str): + crate_name_version = filename.removesuffix(".json") + crate = crate_name_version.rsplit("-", 1)[0] + version = crate_name_version.rsplit("-", 1)[1] + + real_path = resources.files("rust2rpm.tests.samples").joinpath(filename) + metadata = Metadata.from_json(real_path.read_text()) + + rendered = spec_render_project( + target=target, + upstream_version=version, + metadata=metadata, + rpm_name=crate, + patch_file_automatic=f"{crate}-patch1.diff", + patch_file_manual=f"{crate}-patch2.diff", + license_files=["LIC1", "LIC2"], + doc_files=["DOC1", "DOC2"], + tomlconf=TomlConf(), + feature_flags=FeatureFlags(), + relative_license_paths=False, + rpmautospec=target == "fedora", + auto_changelog_entry=True, + date=FIXED_DATE, + packager="Jane Jane ", + ) + + rendered = re.sub("(# Generated by rust2rpm) .*", r"\1 NNN", rendered) + + if target == "opensuse": + spec_copyright_year = time.strftime("%Y") + rendered = re.sub(rf"(Copyright \(c\)) {spec_copyright_year}", r"\1 XXXX", rendered) + + fixture_path = resources.files("rust2rpm.tests.samples").joinpath(f"{crate_name_version}.{target}.spec") + fixture_path = typing.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", ["zola-0.16.1.json"]) @pytest.mark.parametrize("target", ["plain", "fedora", "mageia", "opensuse"]) def test_spec_file_render_workspace(filename: str, target: str): diff --git a/setup.cfg b/setup.cfg index 34863eb..29977d0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,7 +24,7 @@ classifiers = include_package_data = True packages = rust2rpm install_requires = - cargo2rpm>=0.1.11 + cargo2rpm>=0.1.12 jinja2 jsonschema pyparsing