RPKG(MACRO)
π rpkg macro reference π (aka RPKG(MACRO))
β¨ NAME β¨
Okay bestie, listen up! This is the rpkg macro reference. Let's get into it.
NOTE: rpkg macro is abashfunction that outputs tostdoutcertain part ofrpmspec file. Don't confuse it withrpmmacro which is part of therpmspec file syntax itself. Essentially,rpkgmacro is something that can output anrpmmacro (or even a sequence of them) tostdout.rpkgmacros are intended to be translated into their respectivestdouts (in other words, "executed") bypreprocutility and you will therefore see them in a spec file enclosed triple braces (e.g.{{{ <macro_name> }}}) which are thepreprocspecific tags used to differentiate macro invocations from the normal text.
πΈ EXAMPLES πΈ
Here's a cute example spec file with the rpkg macros used:
Name: {{{ git_dir_name }}}
Version: {{{ git_dir_version }}}
Release: 1%{?dist}
Summary: This is a test package.
VCS: {{{ git_dir_vcs }}}
License: GPLv2+
URL: https://someurl.org
Source0: {{{ git_dir_pack }}}
%description
This is a test package.
%prep
{{{ git_dir_setup_macro }}}
%changelog
{{{ git_dir_changelog }}}
Other examples can be found online at the addresses below. You can experiment with those by using rpkg tool which understands those spec files and can translate them to regular spec files.
- https://pagure.io/hello_rpkg/blob/master/f/hello_rpkg.spec.rpkg
- https://pagure.io/hello_rpkg_release/blob/master/f/hello_rpkg.spec.rpkg
π BASE GIT MACROS π
Those macros provide the base implementation for other (derived) macro types like e.g. git_dir macros (see later in this document). They can be, however, used directly as well. Unless otherwise specified in their description, they operate on git repository top-level for the directory where the input spec file is located.
The directory location of the input spec file should be provided by user or upper tooling through INPUT_DIR_PATH environment variable (it should be provided even if the derived macros are used instead of the base ones). If this variable is not provided, its value will be derived from INPUT_PATH environment variable by stripping the last path component. If neither INPUT_DIR_PATH nor INPUT_PATH are provided, the INPUT_DIR_PATH variable will be set automatically to ., i.e. the current working directory (the only purpose of this default is to allow for easy experimentation with the macros on command-line).
Output of every base git macro call is cached and other macros are made to take those cached values into account by default. You can see that a macro uses a cached value as an input parameter default value by looking at its function header definition and searching for the OUTPUT keyword.
E.g.
git_version [name="${OUTPUT[git_name]}"] [lead=0] [follow=]
Default value for name in this definition is obtained from the cached output of the previously invoked git_name macro or its derivative, e.g. git_dir_name (in which case, the cache key is still git_name). If git_name macro or its derivative has not been invoked or if its output was an empty string, the default value for the name= parameter above will be also an empty string.
"Subpackage" in the definitions below is a set of annotated tags with a common Name. Such set of tags in a git project usually corresponds to a certain (sub)directory with a spec file in it.
π¦ git_name π¦
git_name [name=] [prepend=] [append=]
Without any parameters, looks up remote URL for the currently active branch and outputs its basename with .git suffix stripped. If the remote URL could not be determined, "origin" remote URL is used instead.
Optional arguments:
nameβ the base name to be outputprependβ string to be prepended to the base nameappendβ string to be appended to the base name
π¦ git_version π¦
git_version [name="${OUTPUT[git_name]}"] [lead=0] [follow=]
Outputs version of a subpackage given by name. The version is computed from the current commit, state of the work tree, and also from the latest** reachable annotated tag of N-V-R form (N-V-R stands for the Name-Version-Release rpm triplet) with a matching Name (i.e. equal to ${name}) and Lead (but only if lead parameter is non-empty). Lead is defined as a substring of Version before the last dot (note that for the git_release macro below, it is defined as substring of Release before the last dot, instead). Complementary to Lead, there is Follow which is the version part of the tag after the last dot.
The version string that git_version produces is generally composed of the following parts (some of those parts might end up empty in certain cases):
${lead}.${follow}${commit_count_appendix}${dirty_appendix}
lead is a major version substring. By default, it is set to zero. It is intended to be manually incremented on API/ABI changes. It can contain multiple components separated by dot (e.g. 2.1).
If lead parameter is set to empty, its value will be automatically derived from Lead of the latest (reachable) annotated tag for the subpackage given by name. If there is no such tag, lead will be empty and the dot after it will not be rendered.
follow is a minor version substring. It can contain only a single component (i.e. it cannot contain any dots).
If follow parameter is empty, it will be obtained from Follow of the latest tag of a matching Name and also Lead if lead parameter is non-empty. If there is no such tag, the resulting follow will be 0.
commit_count_appendix is generated only if the current commit is not tagged for the given subpackage. It is composed of the following parts:
.git.${commit_count}.${current_commit_short_hash}
commit_count is a number of commits from the latest tag to the current commit for the given subpackage.
current_commit_short_hash is a short (8-chars long) hash of the current commit.
dirty_appendix is generated only if the currently checked out work tree is dirty. It is composed of the following parts:
.dirty.${encoded_latest_file_status_change_time}
encoded_latest_file_status_change_time is an encoded time of the latest file status change that happened in the work tree. That way we can have the version increased each time we make a change in our work tree without committing.
Optional arguments:
nameβ name of a subpackageleadβ major version substring, dynamically derived if set to emptyfollowβ minor version substring, dynamically derived if not specified
Environment variables:
VERSION_BUMPβ if set to a non-empty value, the following procedure is applied to get the version string:- If
followis specified by user explicitly, output${lead}.${follow}. - Otherwise, extract
followfrom the latest tag of a matching Name and Lead (ifleadis non-empty) as the last version component (the component after the last dot of Version) and output${lead}.${follow}+1. If the extracted${follow}is not a number, throw an error (manual setting offollowis needed in this case).
- If
NOTE:rpkgcommand-line utility sets theVERSION_BUMPvariable into the preprocessing environment during execution ofrpkg tagsubcommand. Otherwise, it is unset.
**"latest" is defined by a topological sort as the first criterion and rpm version sort as the second (supplementary) criterion where the topological sort is not enough to decide. The tool that implements this sorting algorithm is calledrpm-git-tag-sort. Note that in this article, we sometimes say only "the latest tag" while the real meaning is "the latest reachable annotated tag" (i.e. "reachable" and "annotated" is always implied).
π¦ git_release π¦
git_release [name="${OUTPUT[git_name]}"] [lead=] [follow=]
Outputs release of a subpackage given by ${name}. The release string contains the same parts as the version string for git_version:
${lead}.${follow}${commit_count_appendix}${dirty_appendix}
and is computed in a similar fashion to the version string, i.e. based on the current commit, state of the work tree, and based on the latest reachable annotated tag of N-V-R form with a matching Name and Lead if lead is non-empty.
For git_release, however, we extract all the information from the Release part of that tag. In other words, Lead, lead, and follow relate to Release for this macro but otherwise their meaning stays the same as for git_version (i.e. Lead is the part of a version string before the last dot, lead is used to match against Lead, follow, if specified, is used instead of Follow of the latest tag).
Additionally, lead (the input parameter, therefore lowercase 'l', as opposed to Lead - the tag substring) is empty by default for git_release.
Optional arguments:
nameβ name of a subpackageleadβ major version substring, dynamically derived if not specifiedfollowβ minor version substring, dynamically derived if not specified
Environment variables:
RELEASE_BUMPβ if set to a non-empty value, the same procedure is applied to get a bumped value as forgit_versionexcept we again apply the terms Lead,lead, andfollowto Release instead of Version. Please, seegit_versionabove for more information.
NOTE:rpkgutility sets theRELEASE_BUMPvariable into the preprocessing environment during execution ofrpkg tagsubcommand. Otherwise, it is unset.
π¦ git_release_branched π¦
git_release_branched
Uses the current branch name as lead parameter for git_release. In other words, equivalent of:
git_release lead="$GIT_BRANCH"
NOTE: the output value will be cached undergit_release, not undergit_release_branched.
π¦ git_changelog π¦
git_changelog [name="${OUTPUT[git_name]}"] [since_tag=] [until_tag=] [header_locale=POSIX] [header_date_format="%a %b %d %Y"] [body_wrap=80]
Outputs rpm spec changelog as generated from tag messages for the subpackage given by name.
Optional arguments:
nameβ name of the subpackage to generate the changelog forsince_tagβ start the changelog records with this taguntil_tagβ end the changelog records with this tagheader_localeβ locale to be used when changelog record date is being generatedheader_date_formatβ the date format that goes in the changelog record headers, periodt ποΈbody_wrapβ the max line length allowed for the changelog body, so it stays cute and readable β¨
NOTE: when you call rpkg tag, it lets you specify a tag message. That message is literally what gets used as the changelog record body. iykyk π
git_vcs path=</p>
Spits out a pseudo repository URL that points at that <purple>path</purple> in the tree you've currently got checked out. bestie, ideally the output should have a publicly available clone URL chilling in there as a substring when you're using this macro for production stuff. no cap.
Example output:
git+https://pagure.io/test-project.git#dadef2a8b9554e94797a7336261192e02d5d9351:subdir
Required arguments:
pathβ the path to a subtree you want to generate the URL for π³
git_pack path= [dir_name=] [source_name=]</p>
Packs the whole work tree content into a gzipped source tarball and outputs ${source_name}, which is the filename of the tarball it made. it omits submodules, untracked content, and git-ignored content too β so clean β¨. but here's the tea: while submodules get omitted when they're on a subpath of the given path, you can actually point the path into a submodule (like into its top-level directory), and then the submodule content gets packed, obeying the same rules as if the parent's git repository's own path were being packed. π
If the work tree is dirty, it uses GNU tar to do the job. But if the tree is clean, git_pack actually becomes a lil proxy to the git_archive macro below, and instead the treeish from the current commit is used as the source content instead of the work tree (the two contents are the same at this point anyway, lowkey). Why? because the git archive packing method has a glow-up advantage: the resulting tarball gets a PAX header identifying the source commit (see man git-get-tar-commit-id), which can later be used for package verification and further processing. So this method lets you pack from a dirty tree for testing purposes while still producing trackable, production-ready archives when the work tree is clean. iconic. π₯
Required arguments:
pathβ path to a specific subdirectory to be packed π¦
Optional arguments:
dir_nameβ top-level directory name in the created tarballsource_nameβ filename of the created source tarball
Environment variables:
OUTDIRβ if it's empty,git_packwon't generate any sources, only the source filename gets output. otherwise it determines where to put the generated tarball π«Ά
NOTE: therpkgutility setsOUTDIRonly if the tarball is actually needed to be generated. It does not set it when justrpkg specis called (without any additional arguments). noted. π
git_archive path= [dir_name=] [source_name=]</p>
Packs the latest commit tree content into a gzipped source tarball and outputs ${source_name}, which is the filename of the created tarball. uses git archive to do the job. the result will contain a PAX header with the commit ID from which the tarball was created π. this info can later be extracted by git-get-tar-commit-id. chef's kiss.
Required arguments:
pathβ path to a specific subdirectory to be packed π¦
Optional arguments:
dir_nameβ top-level directory name in the created tarballsource_nameβ filename of the created source tarball
Environment variables:
OUTDIRβ if empty,git_archivewon't generate any sources, only the source filename gets output. otherwise it decides where to put the generated tarball π
NOTE: therpkgutility setsOUTDIRonly if the tarball is actually needed to be generated. It does not set it when justrpkg specis called (without any additional arguments). same energy, fr fr.
git_setup_macro [dir_name=] [path=] [source_indices=0]</p>
Outputs a %setup rpm macro call with the appropriate parameters for the given path or dir_name. this will unpack one or multiple source tarballs defined by the Source definitions in a spec file ποΈ. this macro is primarily designed to be called in the %prep section of the spec file to unpack sources for the %build phase.
Either dir_name or path needs to be specified β you gotta pick one, bestie. this macro is complementary to git_pack and git_archive macros and is assumed to be used if one of those macros is used in a spec file. they're a little squad π«
Optional arguments:
dir_nameβ name of the top-level directory in the source-tarballpathβ path from whichdir_nameis derived if it's not specifiedsource_indicesβSourcenumbers separated by comma to generate the%setupmacro for, by default0π’
GIT_DIR MACROS π
These macros operate on a directory level. In particular, on the directory where the input spec file is located π. The location of the spec file is assumed to be stored in the INPUT_PATH environment variable. There's also INPUT_DIR_PATH, which stores the path to the directory where the spec file is located (i.e. INPUT_PATH with the last component stripped).
In essence, the git_dir macros are tiny wrappers over the base git macros, and they get invoked with some input parameters set specifically for the spec-file's subdirectory operation π§. they're like the base macros but with a lil costume on.
The git_dir macros have the same input parameters as the respective base git macros, and the values you specify get passed directly down to the base macros, and they'll also override the values of those parameters that the derived macro sets itself (you'll see those parameters in the definitions below). so you're always in control, main character energy. π
NOTE: the git_dir macros are the recommended ones to use out of all the macro types. Use them unless you'd need to override a value that the macro sets itself. In that case, the base git macros are a better choice. slay accordingly.
NOTE: therpkgutility lets you specify theINPUT_PATHenvironment variable through the--spec <path>argument for certainrpkgsubcommands that support it. π
Below you can see what the git_dir macros expand to. Passing all input parameters down to the base git macro, if any are specified, is implicit (i.e. not mentioned below). so don't be confused when you don't see them, bestie π
git_dir_name</p>
git_name append="$(git_prefix "$INPUT_DIR_PATH" | git_prefix_to_name_suffix)"
Outputs the remote URL basename appended with the path (after slash-to-dash substitution) from the repository root to the spec file's directory πΈ
git_dir_version</p>
git_version name="$(git_dir_name)"
Outputs the version of a subpackage by name $(git_dir_name). β¨
git_dir_release</p>
git_release name="$(git_dir_name)"
Outputs the release of a subpackage by name $(git_dir_name). π
git_dir_release_branched</p>
git_release_branched name="$(git_dir_name)"
Outputs the branched release of a subpackage by name $(git_dir_name). πΏ
git_dir_changelog</p>
git_changelog name="$(git_dir_name)"
Outputs the changelog of a subpackage by name $(git_dir_name). π
git_dir_vcs</p>
git_vcs path="$INPUT_DIR_PATH"
Outputs a VCS pseudo URL pointing to the spec file's subdirectory. π
git_dir_pack</p>
git_pack path="$INPUT_DIR_PATH"
Packs the spec file's subdirectory by using GNU tar (for a dirty repo) or git archive (for a clean repo). π
git_dir_archive</p>
git_archive path="$INPUT_DIR_PATH"
Packs the spec file's subdirectory by using git archive. ποΈ
git_dir_setup_macro</p>
git_setup_macro path="$INPUT_DIR_PATH"
Outputs rpm's %setup macro with dir_name (the -n argument of %setup) generated according to the remote URL basename and the spec file's subdirectory path. If you used git_dir_pack or git_dir_archive for packing, use this macro in the %prep spec file section for preparing the sources for the rpm build. and that's the whole ritual, bestie π―οΈβ¨
π GIT_CWD MACROS π
Okay so, same energy as the git_dir macros, but these ones do their thing at the directory level β specifically the current working directory (they grab it from the PWD environment variable). And honestly? They're just lil baby wrappers around the base git macros, with some input params already dialed in for operating on the cwd. Slay. β¨
NOTE: With therpkgutility, you can influence the working dir from the command line by explicitly specifying its--pathargument. Iconic. π
Below you can see what the git_cwd macros expand to. Passing all input parameters down to the base git macro, if any are specified, is implicit (i.e. not mentioned below). So don't come for me if you don't see them repeated, bestie.
git_cwd_name
git_name append="$(git_prefix "$PWD" | git_prefix_to_name_suffix)"
Outputs the remote URL basename appended with the path from the repository root to the current working directory (after slash-to-dash substitution). Periodt. π
git_cwd_version
git_version name="$(git_cwd_name)"
Outputs version of a subpackage by name $(git_cwd_name). Yes queen. π
git_cwd_release
git_release name="$(git_cwd_name)"
Outputs release of a subpackage by name $(git_cwd_name).
git_cwd_release_branched
git_release_branched name="$(git_cwd_name)"
Outputs branched release of a subpackage by name $(git_cwd_name).
git_cwd_changelog
git_changelog name="$(git_cwd_name)"
Outputs changelog of a subpackage by name $(git_cwd_name).
git_cwd_vcs
git_vcs path="$PWD"
Outputs VCS pseudo URL pointing to the current working directory. Vibe. π
git_cwd_pack
git_pack path="$PWD"
Packs the working directory by using GNU tar (for a dirty repo) or git archive (for a clean repo). No cap. π₯
git_cwd_archive
git_archive path="$PWD"
Packs the working directory by using git archive.
git_cwd_setup_macro
git_setup_macro path="$PWD"
Outputs rpm's %setup macro with dir_name (-n argument of %setup) automatically generated according to the remote URL basename and the current working directory path. If you used git_cwd_pack or git_cwd_archive for packing, use this macro in the %prep spec file section for preparing the sources for rpm build. You're welcome. π
π¦ GIT_REPO MACROS π¦
These macros operate on the root (top-level) directory of the current git repository. Path to that directory is stored in the GIT_ROOT environment variable. Implementation-wise? They're just tiny wrappers over the git base macros with some input values set specifically for repository-wide operation. Cute. π
WARNING: If your local git repository is not properly initialized, or if β for example β the.gitmetadata directory in your local tree has been renamed or removed, operation of the repo macros can get out of the intended scope. It is therefore recommended to use the more specificgit_dir_*macros wherever possible, which are always bound to the directory where the input spec file is located. This is especially important for the tarball creating macros (i.e. the*_packand*_archiveones). Don't play yourself. π
Below you can see what the git_repo macros expand to. Passing all input parameters down to the base git macro, if any are specified, is implicit (i.e. not mentioned below). Same rule as before.
git_repo_name
git_name
Outputs remote URL basename with .git suffix stripped. git_repo_name and git_name are direct equivalents. They're twins, basically. π―
git_repo_version
git_version name="$(git_repo_name)"
Outputs version of a subpackage by name $(git_repo_name).
git_repo_release
git_release name="$(git_repo_name)"
Outputs release of a subpackage by name $(git_repo_name).
git_repo_release_branched
git_release_branched name="$(git_repo_name)"
Outputs branched release of a subpackage by name $(git_repo_name).
git_repo_changelog
git_changelog name="$(git_repo_name)"
Outputs changelog of a subpackage by name $(git_repo_name).
git_repo_vcs
git_vcs path="$GIT_ROOT"
Outputs VCS pseudo URL pointing to the repository. Main character energy. π
git_repo_pack
git_pack path="$GIT_ROOT"
Packs the whole repository (with the standard omissions like git-ignored content or git submodules β see the documentation for git_pack regarding this) by using GNU tar (for a dirty repo) or git archive (for a clean repo).
git_repo_archive
git_archive path="$GIT_ROOT"
Packs the git repository content by using git archive.
git_repo_setup_macro
git_setup_macro path="$GIT_ROOT"
Outputs rpm's %setup macro with dir_name (-n argument of %setup) generated from the basename of the repository remote URL. If you used git_repo_pack or git_repo_archive for packing, use this macro in the %prep spec file section for preparing the sources for rpm build. Ate. π
That's a wrap on RPKG(MACRO) from the REFERENCE section πβ¨. Version and date? You know your distro's got the receipts, bestie. Periodt. π
π¦ where this page comes from
- fedora 43: rpkg-macros 2.0-12.fc43 Β· GPL-2.0-or-later
- fedora 44: rpkg-macros 2.0-13.fc44 Β· GPL-2.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms