Subject: bug#55139: package-location is wrong for transformed packages

From: Maxim Cournoyer <[email-masked]>
Date: Sun, 22 May 2022 01:16:32 -0400

Hi,

Ludovic Courtès <[email-masked]> writes:

> Hi,
>
> Maxim Cournoyer <[email-masked]> skribis:
>
>>> ,import (gnu packages) (guix packages)
>>> (car (find-packages-by-name "python2-pyalsaaudio"))
>> $1 = #<package [email-masked] gnu/packages/audio.scm:4327 7f2b76fab160>
>>> (package-definition-location-code package $1)
>> $2 = #f
>>> (package-definition-location $2)
>> $3 = #<<location> file: "gnu/packages/audio.scm" line: 4327 column: 2>
>>
>>
>> This is wrong though, and gives the location of the parent package (the
>> one it inherited from).  This seems to be made on purpose (?) given the
>> code in (gnu build-system python):
>>
>> (package/inherit p
>>         (location (package-location p))
>>
>>         ^ Here, we explicitly set the location to that of its parent.
>
> Indeed, that’s on purpose; the rationale is that it’s more useful to see
> the location of the original package (the Python 3 variant) than always
> this one line in gnu/build-system/python.scm.
>
>> Another related issue for package-with-python2 packages:
>>
>>> (package-definition-location-code $1)
>> $4 = #f
>
> Yes, I see it’s annoying, but that’s expected.
>
>> I was expecting to use this to get rid of all leaf Python 2 packages,
>> but it seems that may not work (as easily as I'd hoped).
>
> You were willing to have a script that would automatically delete the
> relevant lines, right?
>
> It’s kinda silly but I think the script will have to estimate the
> definition location by looking for “(define-public python2-…”.

Yeah, I ended up with this [0]:

--8<---------------cut here---------------start------------->8---
(define (locate-package-via-git name)
  "Return the location object corresponding to package NAME, searched via git."
  (let* ((input-pipe (open-pipe* OPEN_READ
				 "git" "grep" "-n" "--column"
                                 (format #f "^(define-public ~a$" name)))
	 (output (get-string-all input-pipe)) ;file:line:column:match
	 (exit-val (status:exit-val (close-pipe input-pipe))))
    (case exit-val
      ((0)
       (let ((components (string-split output #\:)))
         (location
          (first components)                   ;file
          (string->number (second components)) ;1-indexed line
          ;; FIXME: Comment discrepancy in (guix diagnostics), which
          ;; says the column is 0-indexed.
          (and=> (string->number (third components)) 1-)))) ;0-indexed column
      ((1) #f)                                            ;no match
      (else (error "git grep failed with status" exit-val)))))
--8<---------------cut here---------------end--------------->8---

and it does feel silly to have to shell out to git, but it did the job.

Thanks,

Maxim

[0]  https://notabug.org/apteryx/guix-api-examples/src/master/purge-python2-packages.scm#L42