[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Functional package interface
From: |
Nicolas Graves |
Subject: |
Re: Functional package interface |
Date: |
Mon, 15 Apr 2024 23:31:45 +0200 |
Hi spacecadet!
Isn't what you're trying to do already in Guix? Have a look at
package-inputs-rewrite right there :
https://guix.gnu.org/manual/devel/en/html_node/Defining-Package-Variants.html
I've also been working on general package propagation in RDE, it's still
a work in progress, but it's not far from it :
https://lists.sr.ht/~abcdw/rde-devel/patches/49956
Best regards,
Nicolas
On 2024-04-14 07:02, spacecadet wrote:
> Hi guix
>
> I started working on a "functional interface" to guix packages, as an
> approach to globally modifying packages in an environment, similar to
> nix overlays or the parameterization project.
> Right now it's just a syntax rule that you can wrap a bunch of package
> definitions in with some inputs in the style of a let.
>
>
> (define-syntax define-public-package-set
> (syntax-rules ()
> ((define-public-package-set pkgset
> ((input ...)
> ...)
> (package-name package-def)
> ...)
> (begin
> (define-public pkgset
> (lambda* (#:optional packages
> #:key (input ...)
> ...
> #:allow-other-keys)
> (define package-name package-def)
> ...
> (cond ((and packages (list? packages))
> (map (lambda (package)
> (cond ((eq? package 'package-name)
> `(package-name . ,package-name))
> ...))
> packages))
> (packages
> (cond ((eq? packages 'package-name)
> package-name)
> ...))
> (else
> `((package-name . ,package-name)
> ...)))))
> (set-procedure-property! pkgset 'package-set? #t)
> (define-public package-name
> (pkgset 'package-name))
> ...))))
>
>
> Tried rewriting the guile packages module with it, link to the full
> code further down but here's a snip:
>
>
> ;; existing module
> (define-module (gnu packages guile)
> #:use-module ((guix licenses) #:prefix license:)
> #:use-module (gnu packages)
> ...
>
> ;; package-set definition
> (define-public-package-set gnu-packages-guile
> ((bash-minimal bash-minimal) ;; inputs
> (gawk gawk)
> (gmp gmp)
> ...
> (url-fetch url-fetch))
>
> ;; packages
> (guile-1.8
> (package
> (name "guile")
> ...
>
>
> You end up with a public "gnu-packages-guile" function that takes
> keyword-argument inputs like:
>
> (gnu-packages-guile #:gawk (@ (gnu packages bioinformatics) bioawk))
> ;; => all the packages in gnu/packages/guile.scm, but every instance
> ;; of awk is replaced with bioawk
>
>
> Then returns an alist of all the packages in the set with the inputs
> appropriately "modified". For the keys in the alist I'm using the
> variable names as symbols instead of the package names like in inputs,
> because I feel that's more generally appropriate in the case where a
> package-set might contain something that's not a package record.
> Will probably write a helper function that spits out input pairs.
>
> It can also take a single symbol or list of symbols as an optional
> argument to produce either a single package or list of requested
> packages:
>
>
> (gnu-packages-guile 'guile-3.0)
> ;; => #<package guile@3.0.9 ... )
> (gnu-packages-guile '(guile-2.2 guile2.2-json))
> ;; => (#<package guile@2.2.7 ... #<package guile2.2-json@4.7.3 ...)
>
>
> Packages still get define-public'd, I assume in a way that would
> preserve the existing working condition of the repository (although
> there is one issue right now, more below) so this could hopefully turn
> into a drop-in addition after some more work. I tried to make very few
> changes necessary to the existing code to for the same reason.
>
> Eventually, the goal is to be able to create an operating system
> definition (or manifest, or anything else) using this, with a
> hypothetical case like:
>
>
> (use-package-modules base network etc.)
>
> (define my-package-set
> (packaget-set-append gnu-packages-base
> gnu-packages-network ...))
>
> (with-package-set
> (my-package-set #:mesa something-else)
> (operating-system
> (...)))
>
>
> Adapting more complicated package modules would probably be a task, but
> I'm invested enough to keep working on it.
>
> There are also a few problems with the current implementation, and I
> think they all boil down to one issue:
> If packages A and B are both in the same module, and B is an input to
> A, I can't replace B.
> There may be a solution, it might be as simple as providing a dummy
> input for each package in the module, I don't know, open to ideas.
>
> Another more minor problem is that it won't pull:
>
>
> In ice-9/boot-9.scm:
> 222:29 19 (map1 _)
> 222:29 18 (map1 _)
> 222:29 17 (map1 _)
> 222:29 16 (map1 _)
> 222:29 15 (map1 _)
> 222:17 14 (map1 (((gnu packages guile))))
> 3327:17 13 (resolve-interface (gnu packages guile) #:select _ #:hid
> In ice-9/threads.scm:
> 390:8 12 (_ _)
> In ice-9/boot-9.scm:
> 3253:13 11 (_)
> In ice-9/threads.scm:
> 390:8 10 (_ _)
> In ice-9/boot-9.scm:
> 3544:20 9 (_)
> 2836:4 8 (save-module-excursion _)
> 3564:26 7 (_)
> In unknown file:
> 6 (primitive-load-path "gnu/packages/guile" #<procedure 7f
> In ice-9/eval.scm:
> 619:8 5 (_ #f)
> 626:19 4 (_ #<directory (gnu packages guile) 7fffec4d2dc0>)
> 619:8 3 (_ #(#(#<directory (gnu packages guile) 7fffec4d2dc0>) #
> 632:34 2 (_ #(#(#<directory (gnu packages guile) 7fffec4d2dc0>) #
> 223:20 1 (proc #(#(#<directory (gnu packages guile) 7fffec4d2dc0>
> In unknown file:
> 0 (%resolve-variable (5 (gnu packages bash) bash-minimal .
>
> ERROR: In procedure %resolve-variable:
> error: bash-minimal: unbound variable
>
>
> So I'm probably doing something bad.
> Seems like the first variable in the "inputs" fails to resolve
> somewhere? I don't even have a guess what's going wrong.
>
> My code is available at https://gitlab.vulnix.sh/spacecadet/guix
> Open to comments or ideas, and if anyone can give me a hand figuring out
> the pull issue I'd be grateful.
>
> - sc
>
--
Best regards,
Nicolas Graves