[Rpm-maint] [rpm-software-management/rpm] RFE Make variable sets a first-class rpm citizen (#573)

nim-nim notifications at github.com
Sun Oct 14 14:30:42 UTC 2018


rpm is routinelly used to iterate over sources, patches, subpackages, etc in spec files, but the original rpm design has no notion of lists of stuff.

This lack is workarounded by the `-n` flags in many original rpm clauses, helpers such as `%patches`/`%sources`, lots of manual packager conventions, lots of manual argument passing (for example macros that autogenerate file lists with a specific name, which is then expected by another macro, because they have no other way to sync).

All of which that had to be added because rpmbuild **needs** to process sets of similar objects, but the result does not work too well (where does a -n header declaration ends?), is inconsistent, difficult to use, probably difficult to maintain and accrues to a huge pile of complexity. A pile that is **still** growing organically year after years.

Therefore, I'd like rpm to grow a generic facility to handle sets of similar stuff, that could progressively be used to deprecate all this, with something more consistent, simpler to use and to maintain.

The generic design I came up with, from a packager point of view, is the following. Better designs can probably be though of, I have no emotional attachment to the actual syntax as long as something is added rpmbuild-side.

* rpm grows the notion of lists of sets of variables
* each list has an listid
* each set in a list has a setid
* there is one magic setid that defines default variable values for a set (for example, *default*,*all*,  or whatever rpm devs prefer)
* a generic clause allows defining the variables and values associated with a set:

```specfile
# define values for the setid set of the listid list of sets
# one probably wants something other than %global here, it's just there for example purposes
%{set,listid,setid:
%global name …
%global summary …
%global version …
%global filelistname … 
%global docfileglobs …
%global source  …
}
```

* if a variable is not defined in a setid, but exists in the default set, it takes the value set in this default set
 * a set can define a variable as empty (and one probably wants a way to set explicitly declare a variable as `%{nil}` ie undefine this variable when the set is loaded, do not substitute default value).
* references to a setid that does not exist are aliased to the default set
* sets can be defined incrementaly, a new call to set with the same listid and setid completes the previous definitions, and does not replace them (probably requires an unset clause to remove a setid)
* the resulting variables can be accessed directly in the rest of the specfile:

```specfile
# the value of the %{name} variable defined in the setid element of listid
%{name.listid.setid}
```
* or a specific variable in a specific set can be redefined directly without going through `%{set,setid,listid}`:

```specfile
# The following are equivalent
%global foo.listid.setid bar
%{set,listid,setid:
%global foo bar
}
```

* a clause allows loading a set in the current point of the code flow. That means other macros do not need to be aware of sets and can be used as-is 

```specfile
# Loads the variable values associated with the setid set of the listid list
# After the load %{varname} is set to %{varname.listid.setid} if 
# varname is one of the variables defined in listid list sets;
# till something else sets %{varname} to another value
%loadset -l listid -s setid
```

* a verb allows returning all setids in a listid (typically to loop over them): a table in lua bindings, a space-separated list in rpm syntax lang

```specfile
for sets in %(%listsets -l listid) ;  do …
%{lua: table = rpm.listsets("listid')
```

* the default set is not returned by this verb

* a verb allows returning all variables with the same name regardless of list or set (to implement something things like `%{sources}`. 

```specfile
# returns %{varname.listx.sety} %{varname.listi.setj} …
for sources in %(%listvars -v varname) ;  do …
%{lua: table = rpm.listvars("varname"')
```
* again, defaults are ignored.
* probably useful to add a listid switch to restrict to a particular list of sets.

All of this would have made most of the custom lua multiplexing code in
https://src.fedoraproject.org/rpms/redhat-rpm-config/pull-request/35
unecessary, be simpler more generic and more robuse

So I do not **need** it right now, like everyone else I've written my own hackish custom workaround. And like the other such workarounds it's custom, inconsistent, fragile, and a long-term maintenance drag.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/rpm-software-management/rpm/issues/573
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20181014/f91ff59e/attachment.html>


More information about the Rpm-maint mailing list