all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Efraim Flashner <efraim@flashner.co.il>
To: Phil <phil@beadling.co.uk>
Cc: zimoun <zimon.toutoune@gmail.com>, guix-devel@gnu.org
Subject: Re: Pinning package inputs using inferiors?
Date: Sat, 22 Oct 2022 22:04:46 +0300	[thread overview]
Message-ID: <Y1Q+zlhdbLqPKW/n@3900XT> (raw)
In-Reply-To: <87czakdgw5.fsf@beadling.co.uk>

[-- Attachment #1: Type: text/plain, Size: 6078 bytes --]

On Fri, Oct 21, 2022 at 10:08:10PM +0100, Phil wrote:
> Thanks Simon - I've given an example below.
> 
> zimoun writes:
> 
> > For an example, see python-numpy and python-numpy-next in (gnu packages
> > python-xyz).
> 
> This was my original way of handling this but in what is perhaps a niche
> use of Guix by my department - it ultimately doesn't scale well, for our
> use-case.
> 
> Originally the department was small enough that there was only a handful
> of applications sharing one or two common in-house libraries.
> 
> As we've scaled-up we now have the situation where 3 or 4 common
> libraries are being used by say 10 applications.
> 
> We have rapid release schedules - and want to be able to release the
> common libraries on a weekly basis.  But the time to sign-off on a
> common library takes a few days per application, so it's not practical for
> every project to bump version every week - they have other priorities.
> 
> In an ideal world automated unit and regression testing would be
> comprehensive enough that we could move aggressively each week, but at
> least for now that's not practical given the complex nature of signing
> off the libraries and the applications which use the libraries.
> 
> So, ideally, what we'd like to do is just have each common library
> churn-out releases every week, and have the releases available in Guix,
> but without having an obligation on dependent applications to adopt
> these changes if they don't want to.
> 
> Note all libraries and applications share the same channel - one
> solution would be to have each library in their own channel, but this
> feels ugly to me.
> 
> Our solution (somewhat tricky to explain without a whiteboard -
> apologies!) is to co-locate the package definition of the common library
> in the common library repo itself - we call it something like
> .requirements.scm and it is naturally kept in lockstep with the code in
> that repo that the definition will build.  This is very different to
> traditional Guix where channels contain definitions separately in a
> different repo to the code those definitions describe how to build. 
> 
> We then have a job in our CI/CD system that allows us to give a tag on the
> common library repo, and the name of an application that uses the common
> library.
> 
> The job will copy the .requirements.scm into our channel inside a
> private module specific to the application that uses the common library.
> 
> The idea is that you can have many versions of .requirements.scm private
> to every application package definition that references it.
> 
> You could even read .requirements.scm using a function that clones the
> application repo on-the-fly rather than statically storing it in the
> channel - we haven't gone this far yet, as it makes the system even more
> complex to reason about.
> 
> This is basically the same idea as the python-numpy-next but allows for
> many versions of python-numpy to co-exist by keeping them all in private
> modules so they don't clash.
> 
> It's a cool idea and works pretty well, but requires us to augment Guix
> with a set of extra tools to lift and shift these private definitions
> around, which complicates our setup considerably.
> 
> It feels like wanting to make many versions of a library available at
> once isn't an unreasonable way to work at-scale.  However, it also feels
> like a departure from the philosophy of Guix to decentralise package
> definitions and to allow for a potentially large range of versions to
> co-exist in the same channel commit.
> 
> We could try to further integrate the idea into guix by writing new guix
> commands to support it - we're still working out the details ourselves,
> but if it works well we'd love to present it at a future Guix Days or
> similar!
> 
> In the meantime I was wondering if anyone else had a similar use-case
> for Guix and if they had tried something similar or different to handle
> many versions in an automated way in the same channel commit?
> 
> Apologies that's more than I was intending to write - but hopefully that
> makes some sense!  If it doesn't I can try to flesh out specific example?

Apologies for not slotting in the reply inline, I'm not sure exactly
where to put it.

This might be a good use for package transformations. Imagine the
following:

;;; Python-dep-1

(define-publid python-dep1-week1
  ...)

(define-publid python-dep1-week2
  ...)

(define-publid python-dep1-week3
  ...)

;;; Python-dep-2

(define-publid python-dep2-week1
  ...)

(define-publid python-dep2-week2
  ...)

(define-publid python-dep2-week3
  ...)

;;; Python package

(define my-python-package-base
  (name "my-python-package-base")
  ...
  (inputs
   (list python-dep1
         python-dep2)))

(define-public my-python-package
  (inherit my-python-package-base)
  (name "my-python-package")
  (inputs
   (modify-inputs (package-inputs python-package-base)
     (replace python-dep1 python-dep1-week3)
     (replace python-dep2 python-dep2-week2))))

or if you wanted to do it recursively

(define package-inputs-for-my-python-package
  (package-input-rewriting/spec
    `(("python-dep1" . ,(const python-dep1-week3))
      ("python-dep2" . ,(const python-dep2-week2)))))

(define-public python-package-with-correct-inputs
  (package
    (inherit (package-inputs-for-ython-package my-python-package-base))
    (name "my-python-package")))


Both ideas use 'placeholder packages' so that you can swap them out for
your actual dependency, the first one only for itself and the second one
working recursively. I use the second one myself at work to replace
tensorflow with a version built for the machine it's running on, and at
home to use some newer golang libraries.

-- 
Efraim Flashner   <efraim@flashner.co.il>   אפרים פלשנר
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2022-10-24  7:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-20 21:37 Pinning package inputs using inferiors? Phil
2022-10-21  9:36 ` zimoun
2022-10-21 21:08   ` Phil
2022-10-22 12:33     ` david larsson
2022-10-22 19:04     ` Efraim Flashner [this message]
2022-10-23  5:58     ` Felix Lechner via Development of GNU Guix and the GNU System distribution.
2022-10-24  8:06       ` zimoun

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y1Q+zlhdbLqPKW/n@3900XT \
    --to=efraim@flashner.co.il \
    --cc=guix-devel@gnu.org \
    --cc=phil@beadling.co.uk \
    --cc=zimon.toutoune@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.