Blame SOURCES/README.md

7ef706
pyproject RPM macros
7ef706
====================
7ef706
7ef706
These macros allow projects that follow the Python [packaging specifications]
7ef706
to be packaged as RPMs.
7ef706
7ef706
They work for:
7ef706
7ef706
* traditional Setuptools-based projects that use the `setup.py` file,
7ef706
* newer Setuptools-based projects that have a `setup.cfg` file,
7ef706
* general Python projects that use the [PEP 517] `pyproject.toml` file (which allows using any build system, such as setuptools, flit or poetry).
7ef706
7ef706
These macros replace `%py3_build` and `%py3_install`, which only work with `setup.py`.
7ef706
7ef706
[packaging specifications]: https://packaging.python.org/specifications/
7ef706
7ef706
7ef706
Usage
7ef706
-----
7ef706
7ef706
To use these macros, first BuildRequire the devel package for the Python you
7ef706
are building against. In Fedora, that's `python3-devel`.
7ef706
7ef706
    BuildRequires: python3-devel
7ef706
7ef706
The macros will be pulled in as a dependency on Fedora and EPEL 9+.  
7ef706
In other distributions you need to BuildRequire the macros as well:
7ef706
7ef706
    BuildRequires: python3-devel
7ef706
    BuildRequires: pyproject-rpm-macros
7ef706
7ef706
Next, you need to generate more build dependencies (of your projects and
7ef706
the macros themselves) by running `%pyproject_buildrequires` in the
7ef706
`%generate_buildrequires` section:
7ef706
7ef706
    %generate_buildrequires
7ef706
    %pyproject_buildrequires
7ef706
7ef706
This will add build dependencies according to [PEP 517] and [PEP 518].
7ef706
This also adds run-time dependencies by default and
7ef706
can add test-time dependencies, see the section below.
7ef706
If you need more dependencies, such as non-Python libraries, BuildRequire
7ef706
them manually.
7ef706
7ef706
Note that `%generate_buildrequires` may produce error messages `(exit 11)` in
7ef706
the build log. This is expected behavior of BuildRequires generators; see
7ef706
[the Fedora change] for details.
7ef706
7ef706
[the Fedora change]: https://fedoraproject.org/wiki/Changes/DynamicBuildRequires
7ef706
7ef706
Then, build a wheel in `%build` with `%pyproject_wheel`:
7ef706
7ef706
    %build
7ef706
    %pyproject_wheel
7ef706
7ef706
And install the wheel in `%install` with `%pyproject_install`:
7ef706
7ef706
    %install
7ef706
    %pyproject_install
7ef706
7ef706
`%pyproject_install` installs all wheels in `pyproject-wheeldir/` located in the root of the source tree.
7ef706
7ef706
7ef706
Adding run-time and test-time dependencies
7ef706
------------------------------------------
7ef706
7ef706
To run tests or import checks in the `%check` section,
7ef706
the package's runtime dependencies need to also be included as build requirements.
7ef706
7ef706
Hence, `%pyproject_buildrequires` also generates runtime dependencies by default.
7ef706
20b2b6
For this to work, the project's build system must support the [prepare-metadata-for-build-wheel hook].
7ef706
The popular buildsystems (setuptools, flit, poetry) do support it.
7ef706
7ef706
This behavior can be disabled
7ef706
(e.g. when the project's build system does not support it)
7ef706
using the `-R` flag:
7ef706
7ef706
    %generate_buildrequires
7ef706
    %pyproject_buildrequires -R
7ef706
20b2b6
Alternatively, the runtime dependencies can be obtained by building the wheel and reading the metadata from the built wheel.
20b2b6
This can be enabled by using the `-w` flag.
20b2b6
Support for building wheels with `%pyproject_buildrequires -w` is **provisional** and the behavior might change.
20b2b6
Please subscribe to Fedora's [python-devel list] if you use the option.
20b2b6
20b2b6
    %generate_buildrequires
20b2b6
    %pyproject_buildrequires -w
20b2b6
20b2b6
When this is used, the wheel is going to be built at least twice,
20b2b6
becasue the `%generate_buildrequires` section runs repeatedly.
20b2b6
To avoid accidentally reusing a wheel leaking from a previous (different) build,
20b2b6
it cannot be reused between `%generate_buildrequires` rounds.
20b2b6
Contrarily to that, rebuilding the wheel again in the `%build` section is redundant
20b2b6
and the packager can omit the `%build` section entirely
20b2b6
to reuse the wheel built from the last round of `%generate_buildrequires`.
20b2b6
Be extra careful when attempting to modify the sources after `%pyproject_buildrequires`,
20b2b6
e.g. when running extra commands in the `%build` section:
20b2b6
20b2b6
    %build
20b2b6
    cython src/wrong.pyx  # this is too late with %%pyproject_buildrequires -w
20b2b6
    %pyproject_wheel
20b2b6
7ef706
For projects that specify test requirements using an [`extra`
7ef706
provide](https://packaging.python.org/specifications/core-metadata/#provides-extra-multiple-use),
7ef706
these can be added using the `-x` flag.
7ef706
Multiple extras can be supplied by repeating the flag or as a comma separated list.
7ef706
For example, if upstream suggests installing test dependencies with
7ef706
`pip install mypackage[testing]`, the test deps would be generated by:
7ef706
7ef706
    %generate_buildrequires
7ef706
    %pyproject_buildrequires -x testing
7ef706
7ef706
For projects that specify test requirements in their [tox] configuration,
7ef706
these can be added using the `-t` flag (default tox environment)
7ef706
or the `-e` flag followed by the tox environment.
7ef706
The default tox environment (such as `py37` assuming the Fedora's Python version is 3.7)
7ef706
is available in the `%{toxenv}` macro.
7ef706
For example, if upstream suggests running the tests on Python 3.7 with `tox -e py37`,
7ef706
the test deps would be generated by:
7ef706
7ef706
    %generate_buildrequires
7ef706
    %pyproject_buildrequires -t
7ef706
7ef706
If upstream uses a custom derived environment, such as `py37-unit`, use:
7ef706
7ef706
    %pyproject_buildrequires -e %{toxenv}-unit
7ef706
7ef706
Or specify more environments if needed:
7ef706
7ef706
    %pyproject_buildrequires -e %{toxenv}-unit,%{toxenv}-integration
7ef706
7ef706
The `-e` option redefines `%{toxenv}` for further reuse.
7ef706
Use `%{default_toxenv}` to get the default value.
7ef706
7ef706
The `-t`/`-e` option uses [tox-current-env]'s `--print-deps-to-file` behind the scenes.
7ef706
7ef706
If your package specifies some tox plugins in `tox.requires`,
7ef706
such plugins will be BuildRequired as well.
7ef706
Not all plugins are guaranteed to play well with [tox-current-env],
7ef706
in worst case, patch/sed the requirement out from the tox configuration.
7ef706
5d3ed2
Note that neither `-x` or `-t` can be used with `-R`,
7ef706
because runtime dependencies are always required for testing.
20b2b6
You can only use those options if the build backend  supports the [prepare-metadata-for-build-wheel hook],
20b2b6
or together with `-w`.
7ef706
7ef706
[tox]: https://tox.readthedocs.io/
7ef706
[tox-current-env]: https://github.com/fedora-python/tox-current-env/
20b2b6
[prepare-metadata-for-build-wheel hook]: https://www.python.org/dev/peps/pep-0517/#prepare-metadata-for-build-wheel
7ef706
7ef706
Additionally to generated requirements you can supply multiple file names to `%pyproject_buildrequires` macro.
7ef706
Dependencies will be loaded from them:
7ef706
5d3ed2
    %pyproject_buildrequires requirements/tests.in requirements/docs.in requirements/dev.in
7ef706
7ef706
For packages not using build system you can use `-N` to entirely skip automatical
7ef706
generation of requirements and install requirements only from manually specified files.
5d3ed2
`-N` option implies `-R` and cannot be used in combination with other options mentioned above
5d3ed2
(`-w`, `-e`, `-t`, `-x`).
5d3ed2
5d3ed2
The `%pyproject_buildrequires` macro also accepts the `-r` flag for backward compatibility;
5d3ed2
it means "include runtime dependencies" which has been the default since version 0-53.
5d3ed2
7ef706
7ef706
Running tox based tests
7ef706
-----------------------
7ef706
7ef706
In case you want to run the tests as specified in [tox] configuration,
7ef706
you must use `%pyproject_buildrequires` with `-t` or `-e` as explained above.
7ef706
Then, use the `%tox` macro in `%check`:
7ef706
7ef706
    %check
7ef706
    %tox
7ef706
7ef706
The macro:
7ef706
5d3ed2
 - Sets environment variables via `%{py3_test_envvars}`, namely:
5d3ed2
     - Always prepends `$PATH` with `%{buildroot}%{_bindir}`
5d3ed2
     - If not defined, sets `$PYTHONPATH` to `%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}`
7ef706
 - If not defined, sets `$TOX_TESTENV_PASSENV` to `*`
7ef706
 - Runs `tox` with `-q` (quiet), `--recreate` and `--current-env` (from [tox-current-env]) flags
7ef706
 - Implicitly uses the tox environment name stored in `%{toxenv}` - as overridden by `%pyproject_buildrequires -e`
7ef706
7ef706
By using the `-e` flag, you can use a different tox environment(s):
7ef706
7ef706
    %check
7ef706
    %tox
7ef706
    %if %{with integration_test}
7ef706
    %tox -e %{default_toxenv}-integration
7ef706
    %endif
7ef706
7ef706
If you wish to provide custom `tox` flags or arguments, add them after `--`:
7ef706
7ef706
    %tox -- --flag-for-tox
7ef706
7ef706
If you wish to pass custom `posargs` to tox, use another `--`:
7ef706
7ef706
    %tox -- --flag-for-tox -- --flag-for-posargs
7ef706
7ef706
Or (note the two sequential `--`s):
7ef706
7ef706
    %tox -- -- --flag-for-posargs
7ef706
7ef706
7ef706
7ef706
Generating the %files section
7ef706
-----------------------------
7ef706
7ef706
To generate the list of files in the `%files` section, you can use `%pyproject_save_files` after the `%pyproject_install` macro.
7ef706
It takes toplevel module names (i.e. the names used with `import` in Python) and stores paths for those modules and metadata for the package (dist-info directory) to a file stored at `%{pyproject_files}`.
7ef706
For example, if a package provides the modules `requests` and `_requests`, write:
7ef706
7ef706
    %install
7ef706
    %pyproject_install
7ef706
    %pyproject_save_files requests _requests
7ef706
7ef706
To add listed files to the `%files` section, use `%files -f %{pyproject_files}`.
7ef706
Note that you still need to add any documentation manually (for now).
7ef706
7ef706
    %files -n python3-requests -f %{pyproject_files}
7ef706
    %doc README.rst
7ef706
7ef706
You can use globs in the module names if listing them explicitly would be too tedious:
7ef706
7ef706
    %install
7ef706
    %pyproject_install
7ef706
    %pyproject_save_files '*requests'
7ef706
7ef706
In fully automated environments, you can use the `*` glob to include all modules (put it in single quotes to prevent Shell from expanding it). In Fedora however, you should always use a more specific glob to avoid accidentally packaging unwanted files (for example, a top level module named `test`).
7ef706
7ef706
Speaking about automated environments, some files cannot be classified with `%pyproject_save_files`, but it is possible to list all unclassified files by adding a special `+auto` argument.
7ef706
7ef706
    %install
7ef706
    %pyproject_install
7ef706
    %pyproject_save_files '*' +auto
7ef706
    
7ef706
    %files -n python3-requests -f %{pyproject_files}
7ef706
7ef706
However, in Fedora packages, always list executables explicitly to avoid unintended collisions with other packages or accidental missing executables:
7ef706
7ef706
    %install
7ef706
    %pyproject_install
7ef706
    %pyproject_save_files requests _requests
7ef706
    
7ef706
    %files -n python3-requests -f %{pyproject_files}
7ef706
    %doc README.rst
7ef706
    %{_bindir}/downloader
7ef706
7ef706
`%pyproject_save_files` can automatically mark license files with `%license` macro
7ef706
and  language (`*.mo`) files with `%lang` macro and appropriate language code.
20b2b6
Only license files declared via [PEP 639] `License-File` field are detected.
7ef706
[PEP 639] is still a draft and can be changed in the future.
7ef706
7ef706
Note that `%pyproject_save_files` uses data from the [RECORD file](https://www.python.org/dev/peps/pep-0627/).
7ef706
If you wish to rename, remove or otherwise change the installed files of a package
7ef706
*after* `%pyproject_install`, `%pyproject_save_files` might break.
7ef706
If possible, remove/rename such files in `%prep`.
7ef706
If not possible, avoid using `%pyproject_save_files` or edit/replace `%{pyproject_files}`.
7ef706
7ef706
7ef706
Performing an import check on all importable modules
7ef706
----------------------------------------------------
7ef706
7ef706
If the upstream test suite cannot be used during the package build
7ef706
and you use `%pyproject_save_files`,
7ef706
you can benefit from the `%pyproject_check_import` macro.
7ef706
If `%pyproject_save_files` is not used, calling `%pyproject_check_import` will fail.
7ef706
7ef706
When `%pyproject_save_files` is invoked,
7ef706
it creates a list of all valid and public (i.e. not starting with `_`)
7ef706
importable module names found in the package.
5d3ed2
Each top-level module name matches at least one of the globs provided as an argument to `%pyproject_save_files`.
7ef706
This list is then usable by `%pyproject_check_import` which performs an import check for each listed module.
7ef706
When a module fails to import, the build fails.
7ef706
7ef706
The modules are imported from both installed and buildroot's `%{python3_sitearch}`
7ef706
and `%{python3_sitelib}`, not from the current directory.
7ef706
7ef706
Use the macro in `%check`:
7ef706
7ef706
    %check
7ef706
    %pyproject_check_import
7ef706
7ef706
By using the `-e` flag, you can exclude module names matching the given glob(s) from the import check
7ef706
(put it in single quotes to prevent Shell from expanding it).
7ef706
The flag can be used repeatedly.
7ef706
For example, to exclude all submodules ending with `config` and all submodules starting with `test`, you can use:
7ef706
7ef706
    %pyproject_check_import -e '*.config' -e '*.test*'
7ef706
7ef706
There must be at least one module left for the import check;
7ef706
if, as a result of greedy excluding, no modules are left to check, the check fails.
7ef706
7ef706
When the `-t` flag is used, only top-level modules are checked,
7ef706
qualified module names with a dot (`.`) are excluded.
7ef706
If the modules detected by `%pyproject_save_files` are `requests`, `requests.models`, and `requests.packages`, this will only perform an import of `requests`:
7ef706
7ef706
    %pyproject_check_import -t
7ef706
7ef706
The modifying flags should only be used when there is a valid reason for not checking all available modules.
7ef706
The reason should be documented in a comment.
7ef706
7ef706
The `%pyproject_check_import` macro also accepts positional arguments with
7ef706
additional qualified module names to check, useful for example if some modules are installed manually.
7ef706
Note that filtering by `-t`/`-e` also applies to the positional arguments.
7ef706
7ef706
7ef706
Generating Extras subpackages
7ef706
-----------------------------
7ef706
7ef706
The `%pyproject_extras_subpkg` macro generates simple subpackage(s)
7ef706
for Python extras.
7ef706
7ef706
The macro should be placed after the base package's `%description` to avoid
7ef706
issues in building the SRPM.
7ef706
7ef706
For example, if the `requests` project's metadata defines the extras
7ef706
`security` and `socks`, the following invocation will generate the subpackage
7ef706
`python3-requests+security` that provides `python3dist(requests[security])`,
7ef706
and a similar one for `socks`.
7ef706
7ef706
    %pyproject_extras_subpkg -n python3-requests security socks
7ef706
7ef706
The macro works like `%python_extras_subpkg`,
7ef706
except the `-i`/`-f`/`-F` arguments are optional and discouraged.
7ef706
A filelist written by `%pyproject_install` is used by default.
7ef706
For more information on `%python_extras_subpkg`, see the [Fedora change].
7ef706
7ef706
[Fedora change]: https://fedoraproject.org/wiki/Changes/PythonExtras
7ef706
7ef706
These arguments are still required:
7ef706
7ef706
* -n: name of the “base” package (e.g. python3-requests)
7ef706
* Positional arguments: the extra name(s).
7ef706
  Multiple subpackages are generated when multiple names are provided.
7ef706
7ef706
7ef706
PROVISIONAL: Importing just-built (extension) modules in %build
7ef706
---------------------------------------------------------------
7ef706
7ef706
Sometimes, it is desired to be able to import the *just-built* extension modules
7ef706
in the `%build` section, e.g. to build the documentation with Sphinx.
7ef706
7ef706
    %build
7ef706
    %pyproject_wheel
7ef706
    ... build the docs here ...
7ef706
7ef706
With pure Python packages, it might be possible to set `PYTHONPATH=${PWD}` or `PYTHONPATH=${PWD}/src`.
7ef706
However, it is a bit more complicated with extension modules.
7ef706
20b2b6
The location of just-built modules might differ depending on Python version, architecture, pip version, etc.
7ef706
Hence, the macro `%{pyproject_build_lib}` exists to be used like this:
7ef706
7ef706
    %build
7ef706
    %pyproject_wheel
7ef706
    PYTHONPATH=%{pyproject_build_lib} ... build the docs here ...
7ef706
7ef706
This macro is currently **provisional** and the behavior might change.
7ef706
Please subscribe to Fedora's [python-devel list] if you use the macro.
7ef706
7ef706
The `%{pyproject_build_lib}` macro expands to an Shell `$(...)` expression and does not work when put into single quotes (`'`).
7ef706
7ef706
Depending on the pip version, the expanded value will differ:
7ef706
7ef706
[python-devel list]: https://lists.fedoraproject.org/archives/list/python-devel@lists.fedoraproject.org/
7ef706
20b2b6
### New pip 21.3+ with in-tree-build and setuptools 62.1+ (Fedora 37+)
20b2b6
20b2b6
Always use the macro from the same directory where you called `%pyproject_wheel` from.
20b2b6
The value will expand to something like:
20b2b6
20b2b6
* `/builddir/build/BUILD/%{name}-%{version}/build/lib.linux-x86_64-cpython-311` for wheels with extension modules
20b2b6
* `/builddir/build/BUILD/%{name}-%{version}/build/lib` for pure Python wheels
20b2b6
20b2b6
If multiple wheels were built from the same directory,
20b2b6
some pure Python and some with extension modules,
20b2b6
the expanded value will be combined with `:`:
20b2b6
20b2b6
* `/builddir/build/BUILD/%{name}-%{version}/build/lib.linux-x86_64-cypthon-311:/builddir/build/BUILD/%{name}-%{version}/build/lib`
20b2b6
20b2b6
If multiple wheels were built from different directories,
20b2b6
the value will differ depending on the current directory.
20b2b6
20b2b6
20b2b6
### New pip 21.3+ with in-tree-build and older setuptools (Fedora 36)
7ef706
7ef706
Always use the macro from the same directory where you called `%pyproject_wheel` from.
7ef706
The value will expand to something like:
7ef706
7ef706
* `/builddir/build/BUILD/%{name}-%{version}/build/lib.linux-x86_64-3.10` for wheels with extension modules
7ef706
* `/builddir/build/BUILD/%{name}-%{version}/build/lib` for pure Python wheels
7ef706
7ef706
If multiple wheels were built from the same directory,
7ef706
some pure Python and some with extension modules,
7ef706
the expanded value will be combined with `:`:
7ef706
7ef706
* `/builddir/build/BUILD/%{name}-%{version}/build/lib.linux-x86_64-3.10:/builddir/build/BUILD/%{name}-%{version}/build/lib`
7ef706
7ef706
If multiple wheels were built from different directories,
7ef706
the value will differ depending on the current directory.
7ef706
7ef706
20b2b6
### Older pip with out-of-tree-build (Fedora 35 and EL 9)
7ef706
7ef706
The value will expand to something like:
7ef706
7ef706
* `/builddir/build/BUILD/%{name}-%{version}/.pyproject-builddir/pip-req-build-xxxxxxxx/build/lib.linux-x86_64-3.10` for wheels with extension modules
7ef706
* `/builddir/build/BUILD/%{name}-%{version}/.pyproject-builddir/pip-req-build-xxxxxxxx/build/lib` for pure Python wheels
7ef706
7ef706
Note that the exact value is **not stable** between builds
7ef706
(the `xxxxxxxx` part is randomly generated,
7ef706
neither you should consider the `.pyproject-builddir` directory to remain stable).
7ef706
7ef706
If multiple wheels are built,
7ef706
the expanded value will always be combined with `:` regardless of the current directory, e.g.:
7ef706
7ef706
* `/builddir/build/BUILD/%{name}-%{version}/.pyproject-builddir/pip-req-build-xxxxxxxx/build/lib.linux-x86_64-3.10:/builddir/build/BUILD/%{name}-%{version}/.pyproject-builddir/pip-req-build-yyyyyyyy/build/lib.linux-x86_64-3.10:/builddir/build/BUILD/%{name}-%{version}/.pyproject-builddir/pip-req-build-zzzzzzzz/build/lib`
7ef706
7ef706
**Note:** If you manage to build some wheels with in-tree-build and some with out-of-tree-build option,
7ef706
the expanded value will contain all relevant directories.
7ef706
7ef706
7ef706
Limitations
7ef706
-----------
7ef706
7ef706
`%pyproject_install` changes shebang lines of every Python script in `%{buildroot}%{_bindir}` to `#!%{__python3} %{py3_shbang_opt}` (`#!/usr/bin/python3 -s`).
7ef706
Existing Python flags in shebangs are preserved.
7ef706
For example `#!/usr/bin/python3 -Ru` will be updated to `#!/usr/bin/python3 -sRu`.
7ef706
Sometimes, this can interfere with tests that run such scripts directly by name,
7ef706
because in tests we usually rely on `PYTHONPATH` (and `-s` ignores that).
7ef706
Would this behavior be undesired for any reason,
7ef706
undefine `%{py3_shbang_opt}` to turn it off.
7ef706
7ef706
Some valid Python version specifiers are not supported.
7ef706
7ef706
When a dependency is specified via an URL or local path, for example as:
7ef706
7ef706
    https://github.com/ActiveState/appdirs/archive/8eacfa312d77aba28d483fbfb6f6fc54099622be.zip
7ef706
    /some/path/foo-1.2.3.tar.gz
7ef706
    git+https://github.com/sphinx-doc/sphinx.git@96dbe5e3
7ef706
7ef706
The `%pyproject_buildrequires` macro is unable to convert it to an appropriate RPM requirement and will fail.
7ef706
If the URL contains the `packageName @` prefix as specified in [PEP 508],
7ef706
the requirement will be generated without a version constraint:
7ef706
7ef706
    appdirs@https://github.com/ActiveState/appdirs/archive/8eacfa312d77aba28d483fbfb6f6fc54099622be.zip
7ef706
    foo@file:///some/path/foo-1.2.3.tar.gz
7ef706
7ef706
Will be converted to:
7ef706
7ef706
    python3dist(appdirs)
7ef706
    python3dist(foo)
7ef706
7ef706
Alternatively, when an URL requirement parsed from a text file
7ef706
given as positional argument to `%pyproject_buildrequires`
7ef706
contains the `#egg=packageName` fragment,
7ef706
as documented in [pip's documentation]:
7ef706
7ef706
    git+https://github.com/sphinx-doc/sphinx.git@96dbe5e3#egg=sphinx
7ef706
7ef706
The requirements will be converted to package names without versions, e.g.:
7ef706
7ef706
    python3dist(sphinx)
7ef706
7ef706
However upstreams usually only use direct URLs for their requirements as workarounds,
7ef706
so be prepared for problems.
7ef706
7ef706
[PEP 508]: https://www.python.org/dev/peps/pep-0508/
7ef706
[PEP 517]: https://www.python.org/dev/peps/pep-0517/
7ef706
[PEP 518]: https://www.python.org/dev/peps/pep-0518/
7ef706
[PEP 639]: https://www.python.org/dev/peps/pep-0639/
7ef706
[pip's documentation]: https://pip.pypa.io/en/stable/cli/pip_install/#vcs-support
7ef706
7ef706
7ef706
Testing the macros
7ef706
------------------
7ef706
7ef706
This repository has two kinds of tests.
7ef706
First, there is RPM `%check` section, run when building the `python-rpm-macros`
7ef706
package.
7ef706
7ef706
Then there are CI tests.
7ef706
There is currently [no way to run Fedora CI tests locally][ci-rfe],
7ef706
but you can do what the tests do manually using mock.
7ef706
For each `$PKG.spec` in `tests/`:
7ef706
7ef706
  - clean your mock environment:
7ef706
7ef706
        mock -r fedora-rawhide-x86_64 clean
7ef706
7ef706
  - install the version of `python-rpm-macros` you're testing, e.g.:
7ef706
7ef706
        mock -r fedora-rawhide-x86_64 install .../python-rpm-macros-*.noarch.rpm
7ef706
7ef706
  - download the sources:
7ef706
7ef706
        spectool -g -R $PKG.spec
7ef706
7ef706
  - build a SRPM:
7ef706
7ef706
        rpmbuild -bs $PKG.spec
7ef706
7ef706
  - build in mock, using the path from the command above as `$SRPM`:
7ef706
7ef706
        mock -r fedora-rawhide-x86_64 -n -N $SRPM
7ef706
7ef706
[ci-rfe]: https://pagure.io/fedora-ci/general/issue/4