(→Usage) |
No edit summary |
||
(19 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{old}} | |||
{{Admon/note | Accepted proposal | | |||
This proposal has been accepted and is now part of Packaging Guidelines, section [https://docs.fedoraproject.org/en-US/packaging-guidelines/SourceURL/#_using_forges_hosted_revision_control Referencing Source]}} | |||
Projects published on a “forge” can be packaged using the '''forgemeta''' macro. | Projects published on a “forge” can be packaged using the '''forgemeta''' macro. | ||
This proposal is a requisite for the [[More_Go_packaging|More Go packaging draft]]. | |||
{{Admon/note | What is a “forge”? | | {{Admon/note | What is a “forge”? | | ||
Line 6: | Line 12: | ||
== Links == | == Links == | ||
* [https://docs.fedoraproject.org/en-US/packaging-guidelines/SourceURL/#_using_forges_hosted_revision_control Accepted guidelines] | |||
* [https://pagure.io/packaging-committee/issue/719 FPC ticket] | * [https://pagure.io/packaging-committee/issue/719 FPC ticket] | ||
* [https://bugzilla.redhat.com/show_bug.cgi?id=1523779 | * [https://bugzilla.redhat.com/show_bug.cgi?id=1523779 redhat-rpm-macros RFE] with the macro file → '''DONE''' | ||
* [https://bugzilla.redhat.com/show_bug.cgi?id=1524192 fedora-release RFE] to make dist munging safe | |||
* [https://lists.fedoraproject.org/archives/list/packaging@lists.fedoraproject.org/thread/5K4CED5IBVTS567QJEYGUWLPBFYONDLN/ packaging@lists.fedoraproject.org discussion] | * [https://lists.fedoraproject.org/archives/list/packaging@lists.fedoraproject.org/thread/5K4CED5IBVTS567QJEYGUWLPBFYONDLN/ packaging@lists.fedoraproject.org discussion] | ||
* [https://pagure.io/pagure/issue/861 pagure.io RFE to make pagure.io compatible with forgemeta | * [https://pagure.io/pagure/issue/861 pagure.io RFE] to make pagure.io compatible with forgemeta | ||
* [https://gitlab.com/gitlab-org/gitlab-ce/issues/38830 GitLab CE RFE to remove GitLab quirks] | * [https://gitlab.com/gitlab-org/gitlab-ce/issues/38830 GitLab CE RFE] to remove GitLab quirks | ||
* | * [[More_Go_packaging|More Go packaging draft]] that depends on this proposal. | ||
==Benefits and limitations== | |||
* Benefits: | |||
# Fedora packagers no longer need to know about the URL structure of well-known forges. | |||
# Spec files are simpler, less error-prone, easier to maintain and audit. | |||
# Forge URLs can be defined and fixed in a single place, without waiting for guidelines to percolate. | |||
# The macros are mostly written in Lua, making them more verbose but easier to adjust and extend. | |||
# The macros are written in Lua and can perform error handling. | |||
# It is very easy to switch from commit to tag to version (or any combination of those). | |||
# ''spectool'' just works©. | |||
# scm snapshot date is exact and does not rely on a variable which may or may not have been updated. | |||
# Almost all the computations are done in optional rpm variables that can be ignored by the packager if he does not need or does not like the result. | |||
# Fedora forge know-how can be capitalized over time. | |||
# The macro normalizes common spec constructs such as ''archivename''. | |||
* Limitations: | |||
# The macro is not intended to be used in spec files that package multiple forge archives (it could probably be extended, is the added flexibility worth the complexity?). | |||
# The macro needs to be updated when a forge changes its structure (but better changing one place than lots of spec files). | |||
# New forges need to be added to the macro before it can be used with them. | |||
# ''dist'' munging can not be easily reverted once ''forgemeta'' has been called. The solution would be to change fedora-release to define ''dist'' as ''%{?distprefix}.fcxx'' | |||
# ''dist'' commit date computation relies on source files with the correct modification time (incorrect source file modification time → incorrect ''dist'' date). | |||
# The macro highlights some historical rpm design mistakes: bad separation of upstream and package metadata, special magic variables. This is why ''version'' declaration occurs in an unusual (for rpm) order and requires a specific syntax. | |||
== Usage == | == Usage == | ||
Line 24: | Line 54: | ||
* '''forgesource''': an URL that can be used as ''SourceX:'' value | * '''forgesource''': an URL that can be used as ''SourceX:'' value | ||
* '''forgesetupargs''': the correct arguments to pass to %setup for this source; used by ''%forgesetup'' and ''%forgeautosetup'' | * '''forgesetupargs''': the correct arguments to pass to ''%setup'' for this source; used by ''%forgesetup'' and ''%forgeautosetup'' | ||
* '''archivename''': the source archive filename, without extentions | * '''archivename''': the source archive filename, without extentions | ||
* '''archiveext''': the source archive filename extensions, without leading dot | * '''archiveext''': the source archive filename extensions, without leading dot | ||
Line 33: | Line 63: | ||
The macro also accepts the following optional parameters: | The macro also accepts the following optional parameters: | ||
* ''-u <url>'': ignore ''%{forgeurl}'' even if it exists and use <url> instead; note that the macro will still end up setting <url> as ''%{forgeurl}'' if it manages to parse it | * '''-u''' ''<url>'': ignore ''%{forgeurl}'' even if it exists and use <url> instead; note that the macro will still end up setting <url> as ''%{forgeurl}'' if it manages to parse it | ||
* ''-s'': silently ignore problems in ''%{forgeurl}'', use it if it can be parsed, ignore it otherwise | * '''-s''': silently ignore problems in ''%{forgeurl}'', use it if it can be parsed, ignore it otherwise | ||
* ''-v'' : be verbose and print every variable the macro sets | * '''-p ''': restore problem handling, override ''-s'' | ||
* ''-i'': Print some info about the state of variables the macro may use or set at the end of the processing | * '''-v''' : be verbose and print every variable the macro sets | ||
* '''-i''': Print some info about the state of variables the macro may use or set at the end of the processing | |||
C. The packager uses the computed metadata as needed. | C. The packager uses the computed metadata as needed. | ||
Line 47: | Line 78: | ||
The root cause is that Fedora [https://bugzilla.redhat.com/show_bug.cgi?id=1524192 does not provide currently provide] a placeholder prefix macro inside ''%{dist}'' that could be adjusted without redefining ''%{dist}'' as a whole. | The root cause is that Fedora [https://bugzilla.redhat.com/show_bug.cgi?id=1524192 does not provide currently provide] a placeholder prefix macro inside ''%{dist}'' that could be adjusted without redefining ''%{dist}'' as a whole. | ||
==Extending the macro== | ==Extending the macro== | ||
Line 205: | Line 87: | ||
* copy the definition block closest to your needs after the other definition blocks. It should look like : | * copy the definition block closest to your needs after the other definition blocks. It should look like : | ||
if (forge == "'''vvv'''") then | if (forge == "'''vvv'''") then | ||
… | […] | ||
end | end | ||
or | or | ||
if (string.match(forge, "'''vvv'''")) then | if (string.match(forge, "'''vvv'''")) then | ||
… | […] | ||
end | end | ||
* change the '''"vvv"''' value | * change the '''"vvv"''' value | ||
Line 218: | Line 100: | ||
forgeurl = string.match(forgeurl, "'''www'''") | forgeurl = string.match(forgeurl, "'''www'''") | ||
* adapt the initial error message | * adapt the initial error message | ||
rpm.expand("%{error:"'''xxx''' URLs must match '''yyy'''!\\n}") | |||
* set the hosting service defaults | * set the hosting service defaults | ||
safeset("archiveext", "'''tar.bz2'''") | safeset("archiveext", "'''tar.bz2'''") | ||
Line 229: | Line 111: | ||
* use your variables to define '''archivename''' and '''archiveurl''' in the following if ''tag''/''commit''/''version'' block | * use your variables to define '''archivename''' and '''archiveurl''' in the following if ''tag''/''commit''/''version'' block | ||
* install the result in ''/usr/lib/rpm/macros.d/macros.forge-srpm'' | * install the result in ''/usr/lib/rpm/macros.d/macros.forge-srpm'' | ||
* test with ''' | * test with '''forgemeta -i''' or '''forgemeta -v''' and '''rpmbuild -bs''' ''myspecfile.spec'' | ||
* submit the enhancement for inclusion in [https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component= | * submit the enhancement for inclusion in [https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=redhat-rpm-macros redhat-rpm-macros] once it works satisfactorily. | ||
[[Category:Packaging guidelines drafts]] | [[Category:Packaging guidelines drafts]] |
Latest revision as of 16:43, 24 February 2021
Projects published on a “forge” can be packaged using the forgemeta macro.
This proposal is a requisite for the More Go packaging draft.
Links
- Accepted guidelines
- FPC ticket
- redhat-rpm-macros RFE with the macro file → DONE
- fedora-release RFE to make dist munging safe
- packaging@lists.fedoraproject.org discussion
- pagure.io RFE to make pagure.io compatible with forgemeta
- GitLab CE RFE to remove GitLab quirks
- More Go packaging draft that depends on this proposal.
Benefits and limitations
- Benefits:
- Fedora packagers no longer need to know about the URL structure of well-known forges.
- Spec files are simpler, less error-prone, easier to maintain and audit.
- Forge URLs can be defined and fixed in a single place, without waiting for guidelines to percolate.
- The macros are mostly written in Lua, making them more verbose but easier to adjust and extend.
- The macros are written in Lua and can perform error handling.
- It is very easy to switch from commit to tag to version (or any combination of those).
- spectool just works©.
- scm snapshot date is exact and does not rely on a variable which may or may not have been updated.
- Almost all the computations are done in optional rpm variables that can be ignored by the packager if he does not need or does not like the result.
- Fedora forge know-how can be capitalized over time.
- The macro normalizes common spec constructs such as archivename.
- Limitations:
- The macro is not intended to be used in spec files that package multiple forge archives (it could probably be extended, is the added flexibility worth the complexity?).
- The macro needs to be updated when a forge changes its structure (but better changing one place than lots of spec files).
- New forges need to be added to the macro before it can be used with them.
- dist munging can not be easily reverted once forgemeta has been called. The solution would be to change fedora-release to define dist as %{?distprefix}.fcxx
- dist commit date computation relies on source files with the correct modification time (incorrect source file modification time → incorrect dist date).
- The macro highlights some historical rpm design mistakes: bad separation of upstream and package metadata, special magic variables. This is why version declaration occurs in an unusual (for rpm) order and requires a specific syntax.
Usage
A. The packager declares upstream-dependent metadata :
- forgeurl: the project URL on the target software hosting service
- version: the project release to package, if non nil (as Version: xxx)
- commit: the commit hash to package, if any
- tag: the project tag to package, if any
B. The packager calls %forgemeta. This macro will attempt to compute and set the following variables if they are not already set by the packager:
- forgesource: an URL that can be used as SourceX: value
- forgesetupargs: the correct arguments to pass to %setup for this source; used by %forgesetup and %forgeautosetup
- archivename: the source archive filename, without extentions
- archiveext: the source archive filename extensions, without leading dot
- archiveurl: the url that can be used to download the source archive, without renaming
- scm: the scm type, when packaging code snapshots (commits or tags)
If the macro is unable to parse the %{forgeurl} value the packager should set at least %{archivename} and %{archiveurl} before calling it.
The macro also accepts the following optional parameters:
- -u <url>: ignore %{forgeurl} even if it exists and use <url> instead; note that the macro will still end up setting <url> as %{forgeurl} if it manages to parse it
- -s: silently ignore problems in %{forgeurl}, use it if it can be parsed, ignore it otherwise
- -p : restore problem handling, override -s
- -v : be verbose and print every variable the macro sets
- -i: Print some info about the state of variables the macro may use or set at the end of the processing
C. The packager uses the computed metadata as needed.
%{dist} modification for code snapshots
Most of the macro behavior is optional and safe. You can override the computed rpm variables values before or after the %forgemeta call, or ignore those variables altogether and don't use them in the rest of the spec file. There is one exception:
The macro will change the value of %{dist} in a non-reversible way, when packaging a code snapshot (commit or tag). Redefine %{dist} manually after the %forgemeta call if you don't like the result. Alternatively, don't use %forgemeta.
The root cause is that Fedora does not provide currently provide a placeholder prefix macro inside %{dist} that could be adjusted without redefining %{dist} as a whole.
Extending the macro
If the project you're packaging is published on a software publishing service forgemeta has no knowledge of, don't be sad, that's pretty easy to fix.
- note down the archive URLs you want to generate for versions, tags and commits
- locate the latest version of the forgemeta macro (it should be installed in /usr/lib/rpm/macros.d/macros.forge-srpm by fedora-rpm-macros)
- copy the definition block closest to your needs after the other definition blocks. It should look like :
if (forge == "vvv") then […] end
or
if (string.match(forge, "vvv")) then […] end
- change the "vvv" value
- adapt the initial normalization rule
forgeurl = string.match(forgeurl, "www")
- adapt the initial error message
rpm.expand("%{error:"xxx URLs must match yyy!\\n}")
- set the hosting service defaults
safeset("archiveext", "tar.bz2") safeset("forgesetupargs", "-n %%{archivename}") if (commit ~= "") or (tag ~= "") then safeset("scm", "git") end
- scrap the variables you need from forgeurl using:
local myvariable = string.match(forgeurl, "zzz")
- use your variables to define archivename and archiveurl in the following if tag/commit/version block
- install the result in /usr/lib/rpm/macros.d/macros.forge-srpm
- test with forgemeta -i or forgemeta -v and rpmbuild -bs myspecfile.spec
- submit the enhancement for inclusion in redhat-rpm-macros once it works satisfactorily.