guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Pinning package inputs using inferiors?


From: Phil
Subject: Pinning package inputs using inferiors?
Date: Thu, 20 Oct 2022 22:37:21 +0100
User-agent: mu4e 1.4.15; emacs 27.2

Hi all,

A change in a package ("dependency" in the below example) in a channel I
own has caused a conflict in another package in the same channel that depends
on it ("test-package" in the below).  Whilst fixing the "test-package"
package is the right solution, this is too complicated in do in the
short-term.  I need to pin "dependency" to v1.0 in test-pacakge's
propagated-inputs. Simultaneously, other packages need the new update to
the "dependency" package to use this functionality to deliver new
functionality that can't wait. 

This isn't a one-off situation; this happens frequently and I'm
interested in how other Guixers resolve this with as little friction to
users as possible?

One brainwave I had was to use inferiors - but this doesn't seem to
work.  Continuing from the above example we could define access to a
historical v1.0 of the dependency package for the test-package like so:

(define dependency-inferior
  ;; An inferior containing dependency v1.0.
  (inferior-for-channels dependency-channels))

If we do this then I can get the below manifest to work, just like the
example in the manual:

(packages->manifest
 (list (specification->package "python") ;; useful for testing
       ;; Remove current dependency add old dependency
       (package/inherit test-package
                        (propagated-inputs
                         (modify-inputs (package-propagated-inputs test-package)
                                        (delete "dependency"))))
       (car (lookup-inferior-packages dependency-inferior "dependency"
 "1.0"))))

But this isn't a practical approach - knocking "dependency" out of
test-package's inputs means the unit tests would fail, so I would also
have to delete the check phase - I don't want to do this, it's too much
compromise.

Instead I was hoping to replace the dependency *inside* the package
definition with an inferior like this, so it's still available whilst
the inherited package is being built.

(packages->manifest
 (list (specification->package "python") ;; useful for testing
       ;; Remove current dependency, add old dependency
       (package/inherit test-package
                        (propagated-inputs
                         (modify-inputs (package-propagated-inputs test-package)
                                        (replace "dependency" (car 
(lookup-inferior-packages dependency-inferior "dependency" "1.0"))))))))

When I try this, depending what operation I perform on the manifest, I
normally get some type mismatch telling me I've used a package-inferior
when Guile was expecting a package.  Nothing works, alas.

Thus I'm assuming the two types are not completely substitutable, and
this won't work?

Given this, the workaround I am employing is to replace a single package
definition of "dependency" with locally scoped definitions for each
package that uses it.  This is duplication feels suboptimal.

FWIW, a much more involved solution is to store the dependency package
inside test-package's project repo (rather than my channel), and then
automate copying this into the channel at build time.  This is a cool
exercise, but means we are decentralizing the channel's package
definitions and co-locating them across many repos - which feels not in
the spirit of Guix, and more like how requirements.txt files are
co-located in (non-Guix) python projects. 

My questions are:

1. Is my above use of inferiors always doomed, or something we code make
work with changes to Guix core?

2. Is there another way of handling the situation elegantly without
using inferiors or duplicating package definitions at module scope. 


Any advice or comments gladly received!

Cheers,
Phil.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]