diff --git a/rust2rpm/__main__.py b/rust2rpm/__main__.py index a002fc6..3e46b96 100644 --- a/rust2rpm/__main__.py +++ b/rust2rpm/__main__.py @@ -46,7 +46,7 @@ def main(): parser.error("crate/path argument missing and autodetection failed") try: - project, diffs, metadata, doc_files, license_files = process_project( + project, version, diffs, metadata, doc_files, license_files = process_project( args.crate, args.version, args.patch, args.patch_foreign, args.store_crate ) except NoVersionsError: @@ -132,6 +132,7 @@ def main(): spec_contents = spec_render_crate( metadata=metadata, + upstream_version=version, target=args.target, rpm_name=rpm_name, patch_file_automatic=patch_files[0], diff --git a/rust2rpm/crate.py b/rust2rpm/crate.py index 98ca6d9..cba8d55 100644 --- a/rust2rpm/crate.py +++ b/rust2rpm/crate.py @@ -140,13 +140,14 @@ def project_is_path(path: str) -> bool: return "/" in path or path in {".", ".."} -def guess_local_project_name_from_path(project: str) -> str: +def guess_local_project_version_from_path(project: str) -> tuple[str, str]: if os.path.isdir(project): dir_name = os.path.split(os.path.abspath(project))[1] else: dir_name = os.path.split(os.path.dirname(os.path.abspath(project)))[1] - name = dir_name.rstrip("0123456789.").removesuffix("-") - return name + project = dir_name.rstrip("0123456789.").removesuffix("-") + version = dir_name.removeprefix(f"{project}-") + return project, version @contextlib.contextmanager @@ -161,7 +162,7 @@ def toml_temp_copy(toml_path: str): def process_project_local( project: str, patch: bool, patch_foreign: bool -) -> tuple[str, tuple[Optional[list[str]], Optional[list[str]]], Metadata, list[str], list[str]]: +) -> tuple[str, str, tuple[Optional[list[str]], Optional[list[str]]], Metadata, list[str], list[str]]: if os.path.isdir(project): toml_path, doc_files, license_files = local_cargo_dir(project) else: @@ -175,7 +176,7 @@ def process_project_local( # fall back to the directory name for determining the name / version # of the project heuristically - name = guess_local_project_name_from_path(project) + name, version = guess_local_project_version_from_path(project) log.warn(f"Falling back to {name!r} as the name of the project (based on the name of the containing folder).") diffs = (None, None) @@ -183,6 +184,7 @@ def process_project_local( else: package = metadata.packages[0] name = package.name + version = package.version features = package.get_feature_names() with toml_temp_copy(toml_path) as temp_toml: @@ -191,7 +193,7 @@ def process_project_local( # ensure metadata is up-to-date with changes from patches metadata = Metadata.from_cargo(toml_path) - return name, diffs, metadata, doc_files, license_files + return name, version, diffs, metadata, doc_files, license_files def process_project( @@ -200,7 +202,7 @@ def process_project( patch: bool, patch_foreign: bool, store_crate: bool, -) -> tuple[str, tuple[Optional[list[str]], Optional[list[str]]], Metadata, list[str], list[str]]: +) -> tuple[str, str, tuple[Optional[list[str]], Optional[list[str]]], Metadata, list[str], list[str]]: if project_is_path(project) and not project.endswith(".crate"): # project points into unpacked sources: if store_crate: @@ -241,10 +243,11 @@ def process_project( raise ValueError("Failed to process invalid .crate file (cargo workspace)") package = metadata.packages[0] + version = package.version features = package.get_feature_names() diffs = make_patches(name, version, patch, patch_foreign, toml_path, features) # ensure metadata is up-to-date with changes from patches metadata = Metadata.from_cargo(toml_path) - return name, diffs, metadata, doc_files, license_files + return name, version, diffs, metadata, doc_files, license_files diff --git a/rust2rpm/generator.py b/rust2rpm/generator.py index 0363bb2..38fab51 100644 --- a/rust2rpm/generator.py +++ b/rust2rpm/generator.py @@ -115,6 +115,7 @@ def template_args_plain(date: Optional[time.struct_time], packager: Optional[str def spec_render_crate( *, metadata: Metadata, + upstream_version: str, target: str, rpm_name: str, patch_file_automatic: Optional[str], @@ -239,6 +240,7 @@ def spec_render_crate( "crate_name": package.name, "crate_version": package.version, "crate_license": package.license, + "upstream_version": upstream_version, # Parameters derived from rust2rpm.conf "conf_buildrequires": distconf.buildrequires, "conf_test_requires": distconf.testrequires, diff --git a/rust2rpm/templates/crate.spec b/rust2rpm/templates/crate.spec index 89d86f2..fa1f0ad 100644 --- a/rust2rpm/templates/crate.spec +++ b/rust2rpm/templates/crate.spec @@ -9,6 +9,9 @@ {% 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 @@ -35,10 +38,12 @@ License: {{ rpm_license|default("# FIXME") }} {{ rpm_license_comments }} {% endif %} URL: https://crates.io/crates/{{ crate_name }} -{% if crate_version == rpm_version %} -Source: %{crates_source} -{% else %} +{% if crate_version != rpm_version %} Source: %{crates_source %{crate} %{crate_version}} +{% elif crate_version != upstream_version %} +Source: %{crates_source %{crate} %{upstream_version}} +{% else %} +Source: %{crates_source} {% endif %} {% if rpm_patch_file_automatic is not none %} # Automatically generated patch to strip dependencies and normalize metadata @@ -181,10 +186,12 @@ use {% if feature is not none %}the "{{ feature }}" feature of {% endif %}the "% {% endif -%} %prep -{% if crate_version == rpm_version %} -%autosetup -n %{crate}-%{version} -p1 -{% else %} +{% 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 diff --git a/rust2rpm/tests/test_generator.py b/rust2rpm/tests/test_generator.py index 29fb79f..4e0dbf6 100644 --- a/rust2rpm/tests/test_generator.py +++ b/rust2rpm/tests/test_generator.py @@ -34,6 +34,7 @@ FIXED_DATE = time.gmtime(12345) def test_spec_file_render_crate(filename: str, target: str): crate_name_version = filename.removesuffix(".json") crate = crate_name_version.rsplit("-", 1)[0] + version = crate_name_version.rsplit("-", 1)[1] args = get_parser().parse_args(["foobar", f"--target={target}", "-a" if target == "fedora" else "--no-rpmautospec"]) rpm_name = package_name_suffixed(crate, args.suffix) @@ -43,6 +44,7 @@ def test_spec_file_render_crate(filename: str, target: str): rendered = spec_render_crate( target=target, + upstream_version=version, metadata=metadata, rpm_name=rpm_name, patch_file_automatic=f"{crate}-patch1.diff",