diff --git a/docs/rust2rpm.toml.5.asciidoc b/docs/rust2rpm.toml.5.asciidoc index 18ea842..328fcb2 100644 --- a/docs/rust2rpm.toml.5.asciidoc +++ b/docs/rust2rpm.toml.5.asciidoc @@ -58,12 +58,39 @@ This table contains settings that affect RPM metadata. to be installed to %{_bindir} even if a "bin" target is auto-detected or the crate defines any "bin" target explicitly. The default value is "true". -*bin-name-map*:: +*extra-sources*:: + This setting can be used to specify additional Sources to be included in the + generated spec file. The expected value for this key is an array of objects + with three properties - "number", "file", and "comments". The integer "number" + is used to set a predictable number of the Source file in the spec, the "file" + is expected to be a string that contains an URL or a plain file name, and + "comments" is an array of strings which are prepended to the Source line as + comment lines. + +*extra-files*:: + This setting allows injecting additional files into the "%files" section of + the "binary" subpackage in the generated spec file (if it exists). The value + is expected to be an array of strings, where each element of the array will + end up on a separate line in the "%files" list. Specifying "extra-files" for + a library-only Rust crate has no effect. + +*bin-renames*:: This nested table can be used to specify a re-mapping of executable names to avoid conflicts with other packages. To cause a rename of an existing "bin" target with name "foo" to a new name "bar", add a key-value pair like foo = "bar" to this table. +=== [scripts] table + +This table contains settings which allow injecting additional commands into the +"%prep", "%build", "%install", and "%check" scriptlets, both before and after +the respective "%cargo_*" macro. + +There is a corresponding nested table for each of these scriptlets ("prep", +"build", "install", "check"), with two properties each ("pre" and "post") - both +of which accept an array of strings as value. Each element of these arrays is +injected as a separate line into the spec file. + === [tests] table This table contains settings that control which tests are run. If any settings diff --git a/rust2rpm/conf.py b/rust2rpm/conf.py index 341787d..4d0fb7b 100644 --- a/rust2rpm/conf.py +++ b/rust2rpm/conf.py @@ -45,6 +45,35 @@ TOML_SCHEMA = { "cargo-install-lib": { "type": "boolean", }, + # additional source files + "extra-sources": { + "type": "array", + "items": { + "type": "object", + "properties": { + "file": { + "type": "string", + }, + "number": { + "type": "integer", + }, + "comments": { + "type": "array", + "items": { + "type": "string", + }, + }, + }, + "additionalProperties": False, + }, + }, + # additional packaged files + "extra-files": { + "type": "array", + "items": { + "type": "string", + }, + }, # rename binaries to avoid conflicts "bin-renames": { "type": "object", @@ -58,6 +87,85 @@ TOML_SCHEMA = { }, "additionalProperties": False, }, + # additional commands for scriptlets + "scripts": { + "type": "object", + "properties": { + "prep": { + "type": "object", + "properties": { + "pre": { + "type": "array", + "items": { + "type": "string", + }, + }, + "post": { + "type": "array", + "items": { + "type": "string", + }, + }, + }, + "additionalProperties": False, + }, + "build": { + "type": "object", + "properties": { + "pre": { + "type": "array", + "items": { + "type": "string", + }, + }, + "post": { + "type": "array", + "items": { + "type": "string", + }, + }, + }, + "additionalProperties": False, + }, + "install": { + "type": "object", + "properties": { + "pre": { + "type": "array", + "items": { + "type": "string", + }, + }, + "post": { + "type": "array", + "items": { + "type": "string", + }, + }, + }, + "additionalProperties": False, + }, + "check": { + "type": "object", + "properties": { + "pre": { + "type": "array", + "items": { + "type": "string", + }, + }, + "post": { + "type": "array", + "items": { + "type": "string", + }, + }, + }, + "additionalProperties": False, + }, + }, + "additionalProperties": False, + }, # configure which tests are run "tests": { "type": "object", @@ -335,6 +443,27 @@ class IniConf: return IniConf(**settings) # type: ignore +class Source: + def __init__(self, data: dict): + self._data = data + + @property + def file(self) -> str: + return self._data["file"] + + @property + def number(self) -> int: + return self._data["number"] + + @property + def comments(self) -> list[str]: + return self._data["comments"] + + @property + def whitespace(self) -> str: + return " " * (16 - (len("Source") + len(str(self.number)) + 1)) + + class TomlConf: def __init__(self, data: Optional[dict] = None): self._data = data or dict() @@ -394,6 +523,23 @@ class TomlConf: else: return None + @property + def package_extra_sources(self) -> Optional[list[Source]]: + if package := self._package: + if sources := package.get("extra-sources"): + return [Source(source) for source in sources] + else: + return None + else: + return None + + @property + def package_extra_files(self) -> Optional[list[str]]: + if package := self._package: + return package.get("extra-files") + else: + return None + @property def package_bin_renames(self) -> Optional[dict[str, str]]: if package := self._package: @@ -401,6 +547,94 @@ class TomlConf: else: return None + @property + def _scripts(self) -> Optional[dict[str, dict[str, list[str]]]]: + return self._data.get("scripts") + + @property + def _scripts_prep(self) -> Optional[dict[str, list[str]]]: + if scripts := self._scripts: + return scripts.get("prep") + else: + return None + + @property + def scripts_prep_pre(self) -> Optional[list[str]]: + if scripts_prep := self._scripts_prep: + return scripts_prep.get("pre") + else: + return None + + @property + def scripts_prep_post(self) -> Optional[list[str]]: + if scripts_prep := self._scripts_prep: + return scripts_prep.get("post") + else: + return None + + @property + def _scripts_build(self) -> Optional[dict[str, list[str]]]: + if scripts := self._scripts: + return scripts.get("build") + else: + return None + + @property + def scripts_build_pre(self) -> Optional[list[str]]: + if scripts_build := self._scripts_build: + return scripts_build.get("pre") + else: + return None + + @property + def scripts_build_post(self) -> Optional[list[str]]: + if scripts_build := self._scripts_build: + return scripts_build.get("post") + else: + return None + + @property + def _scripts_install(self) -> Optional[dict[str, list[str]]]: + if scripts := self._scripts: + return scripts.get("install") + else: + return None + + @property + def scripts_install_pre(self) -> Optional[list[str]]: + if scripts_install := self._scripts_install: + return scripts_install.get("pre") + else: + return None + + @property + def scripts_install_post(self) -> Optional[list[str]]: + if scripts_install := self._scripts_install: + return scripts_install.get("post") + else: + return None + + @property + def _scripts_check(self) -> Optional[dict[str, list[str]]]: + if scripts := self._scripts: + return scripts.get("check") + else: + return None + + @property + def scripts_check_pre(self) -> Optional[list[str]]: + if scripts_check := self._scripts_check: + return scripts_check.get("pre") + else: + return None + + @property + def scripts_check_post(self) -> Optional[list[str]]: + if scripts_check := self._scripts_check: + return scripts_check.get("post") + else: + return None + @property def _tests(self) -> Optional[dict[str, Any]]: return self._data.get("tests") diff --git a/rust2rpm/generator.py b/rust2rpm/generator.py index 212d366..6fd72b6 100644 --- a/rust2rpm/generator.py +++ b/rust2rpm/generator.py @@ -351,6 +351,8 @@ def spec_render_crate( "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_files": tomlconf.package_extra_files or list(), # Parameters that control generation of subpackages "rpm_binary_package": is_bin, "rpm_binary_package_name": bin_name, @@ -360,6 +362,15 @@ def spec_render_crate( "crate_features": features, "cargo_install_lib": cargo_install_lib, "cargo_install_bin": cargo_install_bin, + # 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_version": package.version, @@ -535,10 +546,21 @@ def spec_render_project( "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_files": tomlconf.package_extra_files or list(), # Parameters that control generation of subpackages "rpm_binary_package": is_bin, "rpm_cdylib_package": is_cdylib, "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_version": package.version, @@ -710,6 +732,17 @@ def spec_render_workspace( "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_files": tomlconf.package_extra_files or list(), + # 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 RPM macros "rpm_autosetup_args": " -a1" if vendor_tarball else "", "cargo_args": cargo_args, diff --git a/rust2rpm/templates/README.md b/rust2rpm/templates/README.md index 17ba5dc..6566167 100644 --- a/rust2rpm/templates/README.md +++ b/rust2rpm/templates/README.md @@ -30,6 +30,9 @@ | `rpm_doc_files` | `list[str]` | list of the documentation files which were detected in crate sources | | `rpm_bcond_check` | `bool` | flag to switch default value of the `check` bcond | | `rpm_test_comments` | `list[str]` | comments that document why (specific) tests are disabled | +| `rpm_vendor_source` | `Optional[str]` | name of the vendor tarball in case vendored sources are used | +| `rpm_extra_sources` | `list[Source]` | additional source files with number and comments | +| `rpm_extra_files` | `list[str]` | additional files to be included (only applies if there is a non-devel package) | ### Parameters that control generation of subpackages @@ -44,6 +47,19 @@ | `cargo_install_lib` | `bool` | prevent installation of library sources if `False` (default: `True`) | | `cargo_install_bin` | `bool` | prevent installation of binary targets if `False` (default: `True`) | +### Parameters that allow injecting additional commands into scriptlets + +| parameter name | type | value | +| ------------------------- | --------------------- | ------------------------------------------------------------- | +| `rpm_prep_pre` | `list[str]` | additional commands that are injected before `%cargo_prep` | +| `rpm_prep_post` | `list[str]` | additional commands that are injected after `%cargo_prep` | +| `rpm_build_pre` | `list[str]` | additional commands that are injected before `%cargo_build` | +| `rpm_build_post` | `list[str]` | additional commands that are injected after `%cargo_build` | +| `rpm_install_pre` | `list[str]` | additional commands that are injected before `%cargo_install` | +| `rpm_install_post` | `list[str]` | additional commands that are injected after `%cargo_install` | +| `rpm_check_pre` | `list[str]` | additional commands that are injected before `%cargo_check` | +| `rpm_check_post` | `list[str]` | additional commands that are injected after `%cargo_check` | + ### Parameters for crate metadata | parameter name | type | value | @@ -115,6 +131,9 @@ | `rpm_doc_files` | `list[str]` | list of the documentation files which were detected in crate sources | | `rpm_bcond_check` | `bool` | flag to switch default value of the `check` bcond | | `rpm_test_comments` | `list[str]` | comments that document why (specific) tests are disabled | +| `rpm_vendor_source` | `Optional[str]` | name of the vendor tarball in case vendored sources are used | +| `rpm_extra_sources` | `list[Source]` | additional source files with number and comments | +| `rpm_extra_files` | `list[str]` | additional files to be included (only applies if there is a non-devel package) | ### Parameters that control generation of subpackages @@ -124,6 +143,19 @@ | `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 that allow injecting additional commands into scriptlets + +| parameter name | type | value | +| ------------------------- | --------------------- | ------------------------------------------------------------- | +| `rpm_prep_pre` | `list[str]` | additional commands that are injected before `%cargo_prep` | +| `rpm_prep_post` | `list[str]` | additional commands that are injected after `%cargo_prep` | +| `rpm_build_pre` | `list[str]` | additional commands that are injected before `%cargo_build` | +| `rpm_build_post` | `list[str]` | additional commands that are injected after `%cargo_build` | +| `rpm_install_pre` | `list[str]` | additional commands that are injected before `%cargo_install` | +| `rpm_install_post` | `list[str]` | additional commands that are injected after `%cargo_install` | +| `rpm_check_pre` | `list[str]` | additional commands that are injected before `%cargo_check` | +| `rpm_check_post` | `list[str]` | additional commands that are injected after `%cargo_check` | + ### Parameters for crate metadata | parameter name | type | value | @@ -190,6 +222,22 @@ | `rpm_cdylib_package` | `bool` | `True` if package ships any shared libraries (`cdylib` targets) | | `rpm_bcond_check` | `bool` | flag to switch default value of the `check` bcond | | `rpm_test_comments` | `list[str]` | comments that document why (specific) tests are disabled | +| `rpm_vendor_source` | `Optional[str]` | name of the vendor tarball in case vendored sources are used | +| `rpm_extra_sources` | `list[Source]` | additional source files with number and comments | +| `rpm_extra_files` | `list[str]` | additional files to be included (only applies if there is a non-devel package) | + +### Parameters that allow injecting additional commands into scriptlets + +| parameter name | type | value | +| ------------------------- | --------------------- | ------------------------------------------------------------- | +| `rpm_prep_pre` | `list[str]` | additional commands that are injected before `%cargo_prep` | +| `rpm_prep_post` | `list[str]` | additional commands that are injected after `%cargo_prep` | +| `rpm_build_pre` | `list[str]` | additional commands that are injected before `%cargo_build` | +| `rpm_build_post` | `list[str]` | additional commands that are injected after `%cargo_build` | +| `rpm_install_pre` | `list[str]` | additional commands that are injected before `%cargo_install` | +| `rpm_install_post` | `list[str]` | additional commands that are injected after `%cargo_install` | +| `rpm_check_pre` | `list[str]` | additional commands that are injected before `%cargo_check` | +| `rpm_check_post` | `list[str]` | additional commands that are injected after `%cargo_check` | ### Other parameters derived from rust2rpm configuration diff --git a/rust2rpm/templates/crate.spec b/rust2rpm/templates/crate.spec index dd15c11..9d37004 100644 --- a/rust2rpm/templates/crate.spec +++ b/rust2rpm/templates/crate.spec @@ -67,6 +67,12 @@ Source: %{crates_source} {% if use_vendor_tarball %} Source: {{ rpm_vendor_source }} {% endif %} +{% for source in rpm_extra_sources %} +{% for comment in source.comments %} +# {{ comment }} +{% 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 Patch: {{ rpm_patch_file_automatic }} @@ -151,6 +157,9 @@ Requires: {{ req }} {% for bin in rpm_binary_names %} %{_bindir}/{{ bin }} {% endfor %} + {% for file in rpm_extra_files %} +{{ file }} + {% endfor %} {% endif -%} @@ -218,7 +227,13 @@ use {% if feature is not none %}the "{{ feature }}" feature of {% endif %}the "% {% else %} %autosetup -n %{crate}-%{version} -p1{{ rpm_autosetup_args}} {% endif %} +{% for command in rpm_prep_pre %} +{{ command }} +{% endfor %} %cargo_prep{{ cargo_prep_args }} +{% for command in rpm_prep_post %} +{{ command }} +{% endfor %} {% if not include_build_requires and not use_vendor_tarball %} %generate_buildrequires @@ -237,6 +252,9 @@ echo {{ "%r" | format(req) }} {% endif -%} %build +{% for command in rpm_build_pre %} +{{ command }} +{% endfor %} {% if conf_supported_arches %} %ifarch %{supported_arches} {% endif %} @@ -251,8 +269,14 @@ echo {{ "%r" | format(req) }} {% if use_vendor_tarball %} %{cargo_vendor_manifest} {% endif %} +{% for command in rpm_build_post %} +{{ command }} +{% endfor %} %install +{% for command in rpm_install_pre %} +{{ command }} +{% endfor %} {% if rpm_cdylib_package and (rpm_library_package or rpm_binary_package) %} %cargo_install{{ cargo_args }} # FIXME: install shared library @@ -264,12 +288,18 @@ echo {{ "%r" | format(req) }} {{ rpm_bin_rename }} {% endfor %} {% endif %} +{% for command in rpm_install_post %} +{{ command }} +{% endfor %} %if %{with check} {% if conf_supported_arches %} %ifarch %{supported_arches} {% endif %} %check +{% for command in rpm_check_pre %} +{{ command }} +{% endfor %} {% if cargo_test_args %} {% if rpm_test_comments %} {% for comment in rpm_test_comments %} @@ -285,6 +315,9 @@ echo {{ "%r" | format(req) }} {% if conf_supported_arches %} %endif {% endif %} +{% for command in rpm_check_post %} +{{ command }} +{% endfor %} %endif %changelog diff --git a/rust2rpm/templates/project.spec b/rust2rpm/templates/project.spec index 927692f..81278ad 100644 --- a/rust2rpm/templates/project.spec +++ b/rust2rpm/templates/project.spec @@ -52,6 +52,12 @@ Source: # FIXME {% if use_vendor_tarball %} Source: {{ rpm_vendor_source }} {% endif %} +{% for source in rpm_extra_sources %} +{% for comment in source.comments %} +# {{ comment }} +{% 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 Patch: {{ rpm_patch_file_automatic }} @@ -116,7 +122,13 @@ Requires: {{ req }} {% else %} %autosetup -n %{crate}-%{version} -p1{{ rpm_autosetup_args}} {% endif %} +{% for command in rpm_prep_pre %} +{{ command }} +{% endfor %} %cargo_prep{{ cargo_prep_args }} +{% for command in rpm_prep_post %} +{{ command }} +{% endfor %} {% if not include_build_requires and not use_vendor_tarball %} %generate_buildrequires @@ -135,14 +147,23 @@ echo {{ "%r" | format(req) }} {% endif -%} %build +{% for command in rpm_build_pre %} +{{ command }} +{% endfor %} %cargo_build{{ cargo_args }} %{cargo_license_summary{{ cargo_args }}} %{cargo_license{{ cargo_args }}} > LICENSE.dependencies {% if use_vendor_tarball %} %{cargo_vendor_manifest} {% endif %} +{% for command in rpm_build_post %} +{{ command }} +{% endfor %} %install +{% for command in rpm_install_pre %} +{{ command }} +{% endfor %} {% if rpm_cdylib_package and rpm_binary_package %} %cargo_install{{ cargo_args }} # FIXME: install shared library @@ -154,9 +175,15 @@ echo {{ "%r" | format(req) }} {{ rpm_bin_rename }} {% endfor %} {% endif %} +{% 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 %} @@ -169,6 +196,9 @@ echo {{ "%r" | format(req) }} {% else %} %cargo_test{{ cargo_args }} {% endif %} +{% for command in rpm_check_post %} +{{ command }} +{% endfor %} %endif %files @@ -189,6 +219,9 @@ echo {{ "%r" | format(req) }} {% for bin in rpm_binary_names %} %{_bindir}/{{ bin }} {% endfor %} + {% for file in rpm_extra_files %} +{{ file }} + {% endfor %} %changelog {% if use_rpmautospec %} diff --git a/rust2rpm/templates/workspace.spec b/rust2rpm/templates/workspace.spec index dcaf908..13f41aa 100644 --- a/rust2rpm/templates/workspace.spec +++ b/rust2rpm/templates/workspace.spec @@ -39,6 +39,12 @@ Source: # FIXME {% if use_vendor_tarball %} Source: {{ rpm_vendor_source }} {% endif %} +{% for source in rpm_extra_sources %} +{% for comment in source.comments %} +# {{ comment }} +{% endfor %} +Source{{ source.number }}:{{ source.whitespace }}{{ source.file }} +{% endfor %} {% if conf_supported_arches %} ExclusiveArch: {{ conf_supported_arches }} @@ -89,7 +95,13 @@ Requires: {{ req }} {% else %} %autosetup -n {{ rpm_name }}-%{version} -p1{{ rpm_autosetup_args}} {% endif %} +{% for command in rpm_prep_pre %} +{{ command }} +{% endfor %} %cargo_prep{{ cargo_prep_args }} +{% for command in rpm_prep_post %} +{{ command }} +{% endfor %} {% if not include_build_requires and not use_vendor_tarball %} %generate_buildrequires @@ -108,14 +120,23 @@ echo {{ "%r" | format(req) }} {% endif -%} %build +{% for command in rpm_build_pre %} +{{ command }} +{% endfor %} %cargo_build{{ cargo_args }} %{cargo_license_summary{{ cargo_args }}} %{cargo_license{{ cargo_args }}} > LICENSE.dependencies {% if use_vendor_tarball %} %{cargo_vendor_manifest} {% endif %} +{% for command in rpm_build_post %} +{{ command }} +{% endfor %} %install +{% for command in rpm_install_pre %} +{{ command }} +{% endfor %} {% if rpm_cdylib_package and rpm_binary_names|length >= 1 %} %cargo_install{{ cargo_args }} # FIXME: install shared library @@ -127,9 +148,15 @@ echo {{ "%r" | format(req) }} {{ rpm_bin_rename }} {% endfor %} {% endif %} +{% 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 %} @@ -142,6 +169,9 @@ echo {{ "%r" | format(req) }} {% else %} %cargo_test{{ cargo_args }} {% endif %} +{% for command in rpm_check_post %} +{{ command }} +{% endfor %} %endif %files @@ -162,6 +192,9 @@ echo {{ "%r" | format(req) }} {% for bin in rpm_binary_names %} %{_bindir}/{{ bin }} {% endfor %} + {% for file in rpm_extra_files %} +{{ file }} + {% endfor %} %changelog {% if use_rpmautospec %}