Bug 1188611

Summary: rpmlint-mini: use a proper rpmlintrc (single) file
Product: [openSUSE] openSUSE Tumbleweed Reporter: Jan Engelhardt <jengelh>
Component: DevelopmentAssignee: Martin Liška <martin.liska>
Status: RESOLVED WONTFIX QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None CC: dmueller, ngompa13, steven.kowalik
Version: Current   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Bug Depends on:    
Bug Blocks: 1179039    

Description Jan Engelhardt 2021-07-22 11:02:47 UTC
The package rpmlint-mini contains a file rpmlint.wrapper, which itself has these lines:

---
rpmlintrc=$(ls -1 /home/abuild/rpmbuild/SOURCES/*rpmlintrc 2>/dev/null)
if [ -n "$rpmlintrc" ]; then
    args="-r $rpmlintrc"
fi
exec /opt/testing/bin/rpmlint.real $args $@
---

ls can yield multiple rpmlintrc files, but, like most option parsers, -r will only take *one* file and the rest is subject to other processing.

Therefore, if any source package has multiple rpmlintrc files (such as Mesa), rpmlint.real from rpmlint-2.0 gets really unhappy because arguments were not constructed right.

https://build.opensuse.org/package/live_build_log/openSUSE:Factory:Staging:O/Mesa/standard/x86_64
Comment 1 Martin Liška 2021-07-22 11:33:13 UTC
Can you please take a look Steve?
Comment 2 Jan Engelhardt 2021-07-22 17:22:09 UTC
The other thing is that the --info argument is no longer available in rpmlint 2.x. It needs to be removed from the wrapper.
Comment 3 Martin Liška 2021-07-22 18:21:24 UTC
(In reply to Jan Engelhardt from comment #2)
> The other thing is that the --info argument is no longer available in
> rpmlint 2.x. It needs to be removed from the wrapper.

No, it's a valid argument:

$ ./lint.py --help
...
  -v, --verbose, --info
                        provide detailed explanations where available
...
Comment 4 Martin Liška 2021-07-22 18:33:15 UTC
Note that rpmlint can load automatically rpmlintrc files:
https://github.com/rpm-software-management/rpmlint/commit/3ec4e4ea2d8ce2855e06451b8a84b0179926ec01

The question is how can one identify which one to use? In the case of Mesa, only one should be used, depending on which multibuild target is being built, right?
Comment 5 Jan Engelhardt 2021-07-22 19:40:21 UTC
chroot /var/run/build/standard (tw)

a4:/ # /opt/testing/bin/rpmlint.real -r /home/abuild/rpmbuild/SOURCES/Mesa-drivers-rpmlintrc /home/abuild/rpmbuild/SOURCES/Mesa-rpmlintrc --info //home/abuild/rpmbuild/RPMS/x86_64/Mesa-libglapi-devel-21.1.5-0.x86_64.rpm                     usage: rpmlint [-h] [-V] [-c CONFIG] [-e EXPLAIN [EXPLAIN ...]] [-r RPMLINTRC] [-v] [-p]                                               [-i INSTALLED [INSTALLED ...]] [-t] [-T] [-s | -P]                                                                      [rpmfile [rpmfile ...]]                                                                                  rpmlint: error: unrecognized arguments: //home/abuild/rpmbuild/RPMS/x86_64/Mesa-libglapi-devel-21.1.5-0.x86_64.rpm      a4:/ # rpm -qf /opt/testing/bin/rpmlint.real                                                                            rpmlint-mini-2.0-1.6.x86_64                                                                                             a4:/ #
Comment 6 Jan Engelhardt 2021-07-22 19:49:37 UTC
>No, it's a valid argument:

Yeah sorry. This argument parsing is silly:
[-i INSTALLED [INSTALLED ...]] [rpmfile [rpmfile...]]
is ambiguous at best. Any 'rpmfile' argument could be an 'installed' and vice versa if this OBNF is to be believed.

>Note that rpmlint can load automatically rpmlintrc files:
>The question is how can one identify which one to use?

rpmlint itself cannot make that determination. obs-build needs to drive it, if at all, as it is the one having been invoked with a .spec file argument from which one can construct `${spec%.spec}-rpmlintrc` to pass to rpmlint.
Comment 7 Steve Kowalik 2021-07-23 04:21:40 UTC
Ah ha, multiple rpmlintrc files, I wasn't aware this was a thing! I've rewritten that portion of that wrapper to handle multiple.
Comment 8 Martin Liška 2021-08-04 12:29:49 UTC
(In reply to Jan Engelhardt from comment #6)
> >No, it's a valid argument:
> 
> Yeah sorry. This argument parsing is silly:
> [-i INSTALLED [INSTALLED ...]] [rpmfile [rpmfile...]]
> is ambiguous at best. Any 'rpmfile' argument could be an 'installed' and
> vice versa if this OBNF is to be believed.
> 
> >Note that rpmlint can load automatically rpmlintrc files:
> >The question is how can one identify which one to use?
> 
> rpmlint itself cannot make that determination. obs-build needs to drive it,
> if at all, as it is the one having been invoked with a .spec file argument
> from which one can construct `${spec%.spec}-rpmlintrc` to pass to rpmlint.

Can you please help us with that? I see the rpmlint is invoked here:
https://github.com/openSUSE/obs-build/blob/master/build-recipe-spec#L317

How can we get to the spec name and pass it to rpmlint?
Comment 9 Jan Engelhardt 2021-08-04 13:44:29 UTC
>How can we get to the spec name and pass it to rpmlint?

A few pointers..

In https://github.com/openSUSE/obs-build/blob/master/build#L1358 I see a general build loop with ${RECIPEFILES[@]}. It appears obs-build could/will happily take multiple .spec files. That slightly complicates things, as rpmlint is currently only made to look at the union of all BRPMs/SRPMs produced by this loop. One probably would have to inspect the "Source RPM:" field of each BRPM to see which rpmlintrc to apply.

In the loop, of note are these transforms:

#L1361
    RECIPEFILE="${RECIPEFILE##*/}"

#L1558
    # strip prefix from autogenerated files of source services.
    RECIPEFILE="${RECIPEFILE##*:}"

These may need to be done inside or right before the call to recipe_run_rpmlint(). This is near L1709.

#L1709
if test -n "$RPMS" -a "$DO_CHECKS" != false ; then
    TIME_RPMLINT=`date +%s`
    recipe_run_rpmlint "${RECIPEFILES[@]}"
    TIME_RPMLINT=$(( `date +%s` - $TIME_RPMLINT ))
fi

HTH
Comment 10 Martin Liška 2021-08-05 10:45:20 UTC
(In reply to Jan Engelhardt from comment #9)
> >How can we get to the spec name and pass it to rpmlint?
> 
> A few pointers..

Thank you for them!

> 
> In https://github.com/openSUSE/obs-build/blob/master/build#L1358 I see a
> general build loop with ${RECIPEFILES[@]}. It appears obs-build could/will
> happily take multiple .spec files.

The question is if it really happens in reality? I guess just a single SRPM file is created by OBS, or?
Knowing that we can deduce which rpmlintrc file should be used.

> That slightly complicates things, as
> rpmlint is currently only made to look at the union of all BRPMs/SRPMs
> produced by this loop. One probably would have to inspect the "Source RPM:"
> field of each BRPM to see which rpmlintrc to apply.
> 
> In the loop, of note are these transforms:
> 
> #L1361
>     RECIPEFILE="${RECIPEFILE##*/}"
> 
> #L1558
>     # strip prefix from autogenerated files of source services.
>     RECIPEFILE="${RECIPEFILE##*:}"
> 
> These may need to be done inside or right before the call to
> recipe_run_rpmlint(). This is near L1709.

That's possible.

> 
> #L1709
> if test -n "$RPMS" -a "$DO_CHECKS" != false ; then
>     TIME_RPMLINT=`date +%s`
>     recipe_run_rpmlint "${RECIPEFILES[@]}"
>     TIME_RPMLINT=$(( `date +%s` - $TIME_RPMLINT ))
> fi

Alternatively, we can simply load all provided rpmlintrc files, hopefully, most of the filter rules are complementary.
I think we speak only about some of the multibuild packages, right?
What do you see as the best solution?
Comment 11 Martin Liška 2021-08-05 18:02:38 UTC
For now, I removed passing arguments from rpmlint-mini wrapper as rpmlint can do that automatically:
https://github.com/rpm-software-management/rpmlint/commit/3ec4e4ea2d8ce2855e06451b8a84b0179926ec01

Moreover, it can load multiple rc files, which should work in most of cases.
Let's see if it bring any fallout.
Comment 12 Martin Liška 2022-04-13 09:46:30 UTC
Apparently, we can live with the limitation as rpmlint 2 is in use in Factory for quite some time.