123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329 |
- diff --git a/Makefile.am b/Makefile.am
- index 8924974e8a..a9cb615b3e 100644
- --- a/Makefile.am
- +++ b/Makefile.am
- @@ -17,6 +17,7 @@
- # Copyright © 2020, 2021, 2023 Maxim Cournoyer <maxim.cournoyer@gmail.com>
- # Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
- # Copyright © 2021 Andrew Tropin <andrew@trop.in>
- +# Copyright © 2023 Sarthak Shah <shahsarthakw@gmail.com>
- #
- # This file is part of GNU Guix.
- #
- @@ -114,6 +115,7 @@ MODULES = \
- guix/repl.scm \
- guix/rpm.scm \
- guix/transformations.scm \
- + guix/parameters.scm \
- guix/inferior.scm \
- guix/describe.scm \
- guix/quirks.scm \
- diff --git a/guix/parameters.scm b/guix/parameters.scm
- new file mode 100644
- index 0000000000..24fe1cbac9
- --- /dev/null
- +++ b/guix/parameters.scm
- @@ -0,0 +1,1180 @@
- +;;; GNU Guix --- Functional package management for GNU
- +;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org>
- +;;; Copyright © 2023 Sarthak Shah <shahsarthakw@gmail.com>
- +;;;
- +;;; This file is part of GNU Guix.
- +;;;
- +;;; GNU Guix is free software; you can redistribute it and/or modify it
- +;;; under the terms of the GNU General Public License as published by
- +;;; the Free Software Foundation; either version 3 of the License, or (at
- +;;; your option) any later version.
- +;;;
- +;;; GNU Guix is distributed in the hope that it will be useful, but
- +;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- +;;; GNU General Public License for more details.
- +;;;
- +;;; You should have received a copy of the GNU General Public License
- +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
- +
- +(define-module (guix parameters)
- + #:use-module (guix diagnostics)
- + #:use-module (guix i18n)
- + #:use-module (guix packages)
- + #:use-module (guix profiles)
- + #:use-module (guix records)
- + #:use-module (srfi srfi-1)
- + #:use-module (srfi srfi-13)
- + #:use-module (srfi srfi-26)
- + #:use-module (srfi srfi-34)
- + #:use-module (srfi srfi-35)
- + #:use-module (ice-9 hash-table)
- + #:use-module (ice-9 match)
- + #:use-module (ice-9 receive)
- + #:autoload (guix transformations) (options->transformation)
- + #:export (parameter-type
- + package-parameter
- + parameter-spec
- + boolean-parameter-type
- +
- + parameter-variant
- + parameter-variant-match
- + parameter-spec-property
- + package-parameter-spec
- + package-parameter-alist
- + all-spec-parameters
- + all-spec-parameters-with-types
- + base-parameter-alist
- + parameter-process-list
- + package-override-plist
- + parameter-spec-validate
- + package-resolve-parameter-list
- + %global-parameters
- + define-global-parameter
- +
- + package-with-parameters
- + parameterize-package
- + apply-variants
- + parameter-spec-parameter-alist
- + parameter-if
- + parameter-match
- + parameter-match-case
- + parameter-modify-inputs
- + parameter-substitute-keyword-arguments
- + ))
- +
- +;;; Commentary:
- +;;;
- +;;; This module provides a way to express high-level "package parameters",
- +;;; which allow users to customize how packages are built. Parameters are an
- +;;; interface that package developers define, where each parameter has a name
- +;;; and type. The user interface then converts parameter values from string
- +;;; to Scheme values and records them in the package properties.
- +;;;
- +;;; Package parameters are discoverable; their description is
- +;;; internationalized. The possible values of a parameter can be enumerated,
- +;;; and thus the Cartesian product of all possible parameter values for a
- +;;; package can be enumerated as well.
- +;;;
- +;;; Code:
- +
- +(define (give-me-a-symbol ex)
- + "Take a string or symbol EX and return a symbol."
- + (cond ((symbol? ex) ex)
- + ((string? ex) (string->symbol ex))
- + (else (raise (formatted-message
- + (G_ "Not a symbol or a string: ~s")
- + ex)))))
- +
- +(define-record-type* <parameter-type> parameter-type
- + make-parameter-type
- + parameter-type?
- + this-parameter-type
- + (name parameter-type-name
- + (sanitize give-me-a-symbol))
- + (accepted-values parameter-type-accepted-values)
- + (negation parameter-type-negation
- + (default (first (parameter-type-accepted-values this-parameter-type)))
- + (thunked))
- + (default parameter-type-default
- + (default (match (parameter-type-accepted-values this-parameter-type)
- + [(first second . rest)
- + (if (not (parameter-type-negation this-parameter-type))
- + first
- + second)]
- + [oth (raise (formatted-message
- + (G_ "Bad accepted-values form: ~s")
- + oth))]))
- + (thunked))
- + (description parameter-type-description
- + (default "")))
- +
- +(define boolean-parameter-type
- + (parameter-type
- + (name 'boolean)
- + (accepted-values '(off on))
- + (description "Boolean Parameter Type")))
- +
- +;; Package parameter interface.
- +(define-record-type* <package-parameter> package-parameter
- + make-package-parameter
- + package-parameter?
- + (name package-parameter-name
- + (sanitize give-me-a-symbol))
- + (type package-parameter-type
- + (default boolean-parameter-type))
- + (variants package-parameter-variants
- + (default '())
- + (sanitize sanitize-parametric-variants))
- + (dependencies package-parameter-dependencies
- + (default '())
- + (sanitize dependency-sanitizer)
- + (thunked))
- + (predicate package-parameter-predicate
- + (sanitize predicate-sanitizer)
- + (default (const #f)))
- + (description package-parameter-description (default "")))
- +
- +(define %global-parameters
- + (alist->hash-table '()))
- +
- +;; SANITIZERS
- +
- +(define (sanitize-parametric-variants ls)
- + "Raise an error if LS is not a list."
- + (cond ((list? ls) ls)
- + (else (raise (formatted-message
- + (G_ "Not a list: ~s")
- + ls)))))
- +
- +(define (predicate-sanitizer p)
- + (match p
- + [(? procedure? p) p]
- + [#t (and (warning
- + (G_ "Please use (const #t) instead of #t!~%"))
- + (const #t))]
- + [#f (and (warning
- + (G_ "Please use (const #f) instead of #f!~%"))
- + (const #f))]
- + [_ (raise (formatted-message
- + (G_ "Not a predicate: ~s")
- + p))]))
- +
- +
- +;; % USEFUL HELPER FUNCTIONS %
- +
- +(define (return-list lst)
- + "Take a value LST, return LST if it a list and (list LST) otherwise."
- + (if (list? lst)
- + lst
- + (list lst)))
- +
- +(define (append-everything . things)
- + "Take a number of THINGS, and append them all."
- + (apply append
- + (map return-list things)))
- +
- +(define (get-parameter-sym psym)
- + "If the argument is a cons cell, return the CAR otherwise return the argument."
- + (match psym
- + [(a . b) a]
- + [a a]))
- +
- +(define* (merge-same-key lst #:optional (carry '()))
- + "Merge the cells of LST with the same value in their CAR."
- + (match lst
- + [((a . b) . rest)
- + (if (null? (filter (lambda (y) (equal? a (first y)))
- + carry))
- + (merge-same-key rest (cons (cons a b) carry))
- + (merge-same-key rest (assq-set! carry
- + a
- + (append (assq-ref carry a) b))))]
- + [() carry]))
- +
- +(define-syntax lambdize-lambdas
- + (syntax-rules (:cruise)
- + [(% :cruise x . rest)
- + (if (keyword? x)
- + (lambdize-lambdas x . rest)
- + (cons x (lambdize-lambdas :cruise . rest)))]
- + [(% :cruise) '()]
- + [(% #:lambda fn . rest)
- + (cons #:lambda
- + (cons fn
- + (lambdize-lambdas :cruise . rest)))]
- + [(% x . rest)
- + (cons 'x (lambdize-lambdas . rest))]
- + [(%) '()]))
- +
- +(define-syntax parameter-variant
- + (syntax-rules ()
- + [(%) '()]
- + [(% psym variants ...)
- + (let ((parsed-variants
- + (parse-keyword-list (lambdize-lambdas variants ...))))
- + (map (cut cons <>
- + parsed-variants)
- + (return-list 'psym)))]))
- +
- +(define* (parse-keyword-list kw-lst)
- + "Parses a list of keywords, KW-LST and returns an alist."
- + (define (list-till-keyword lst)
- + (receive (a b)
- + (break keyword? lst)
- + (cons a b)))
- + (define* (break-keywords lst)
- + (match lst
- + [((? keyword? key) vals ..1)
- + (match (list-till-keyword vals)
- + [(first . rest)
- + (cons (cons (keyword->symbol key)
- + first)
- + (break-keywords rest))])]
- + [((? keyword? just-a-key)) ; (... #:key)
- + (cons (cons (keyword->symbol just-a-key) '())
- + '())]
- + [(singleton) '()]
- + [() '()]
- + [_ (raise (formatted-message
- + (G_ "Error trying to break keywords at ~a")
- + lst))]))
- + (merge-same-key (break-keywords kw-lst)))
- +
- +;; The lock here is used to signal when merge-same-key is to be used
- +;; having a :lock means merge-same-key has been used further up the tree
- +;; note that :lock is not a keyword but a symbol, as we are using keywords elsewhere
- +(define-syntax parameter-variant-match
- + (syntax-rules (:lock)
- + ((% :lock (x ...))
- + (return-list
- + (parameter-variant x ...)))
- + ((% :lock (x ...) rest ...)
- + (append
- + (return-list (parameter-variant x ...))
- + (parameter-variant-match :lock rest ...)))
- + ((% rest ...)
- + (map
- + (match-lambda
- + [(v . lst)
- + (cons v
- + (merge-same-key lst))])
- + (merge-same-key
- + (parameter-variant-match :lock rest ...))))))
- +
- +(define (local-sanitizer ls)
- + "Sanitize a list of local parameters, LS."
- + (if (list? ls)
- + (map (lambda (val)
- + (cond ((package-parameter? val) val)
- + ((symbol? val) (package-parameter (name val)))
- + ((string? val) (package-parameter (name (string->symbol val))))
- + (else (raise (formatted-message
- + (G_ "Not a parameter, symbol or string: ~s")
- + val)))))
- + ls)
- + (raise (formatted-message
- + (G_ "Spec's local field is not a list: ~s")
- + ls))))
- +
- +(define* (variant-sanitizer lv)
- + "Sanitize a list of variants."
- + ;; #:yes -> use default variant
- + ;; #:no -> don't use variant
- + ;; #:special -> use variant in rest
- + (define (sym->parameter psym)
- + "Take a symbol PSYM and return the corresponding parameter."
- + (or (find (lambda (g) (eqv? psym
- + (package-parameter-name g)))
- + lv)
- + (hash-ref %global-parameters psym)
- + (raise (formatted-message
- + (G_ "sym->parameter: not a symbol: ~s")
- + psym))))
- + (define-macro (assq-override! asslst key val)
- + `(set! ,asslst
- + (assq-set! ,asslst ,key ,val)))
- + (lambda (ls)
- + (let ((triad (parse-keyword-list ls)))
- + (if (find (lambda (g) (not (or (eqv? (first g) 'yes)
- + (eqv? (first g) 'no)
- + (eqv? (first g) 'special))))
- + triad)
- + (raise (formatted-message
- + (G_ "Invalid keyword in use-variants: ~s")
- + (first g))))
- + (let ((vars-lst '()))
- + (map
- + (match-lambda
- + [('yes rest ...)
- + (map
- + (lambda (p)
- + (if (not (symbol? p))
- + (raise (formatted-message
- + (G_ "Not a symbol: ~s")
- + p))
- + (assq-override! vars-lst p #:yes)))
- + rest)]
- + [('no rest ...)
- + (map
- + (lambda (p)
- + (if (not (symbol? p))
- + (raise (formatted-message
- + (G_ "Not a symbol: ~s")
- + p))
- + (assq-override! vars-lst p #:no)))
- + rest)]
- + [('special rest ...)
- + (map
- + (match-lambda
- + [(a . b)
- + (assq-override! vars-lst
- + a
- + b)])
- + rest)]
- + [_ (error "wrongly formatted use-variant!")])
- + triad)
- + (map
- + (lambda (x)
- + (match (assq-ref vars-lst (package-parameter-name x))
- + [#f (assq-override! vars-lst
- + (package-parameter-name x)
- + (package-parameter-variants x))]
- + [#:yes (assq-override! vars-lst
- + (package-parameter-name x)
- + (package-parameter-variants x))]
- + [#:no #f] ; do nothing
- + [varn (assq-override! vars-lst
- + (package-parameter-name x)
- + varn)]))
- + lv)
- + vars-lst))))
- +
- +(define (dependency-sanitizer deps)
- + "Sanitize the dependency-list of a package-parameter."
- + (unless (eqv? deps '())
- + (if (not (list? deps))
- + (raise (formatted-message
- + (G_ "Dependencies not a list: ~s")
- + deps)))
- + (if (keyword? (first deps))
- + (if (match (first deps)
- + [#:package (and (warning
- + (G_ "Package Dependencies are not supported!~%"))
- + #t)]
- + [#:parameter #t]
- + [_ #f])
- + (parse-keyword-list deps)
- + (raise (formatted-message
- + (G_ "Bad dependency keyword: ~s")
- + (first deps))))
- + (dependency-sanitizer (cons #:parameter deps)))))
- +
- +(define-record-type* <parameter-spec> parameter-spec
- + make-parameter-spec
- + parameter-spec?
- + this-parameter-spec
- + (local parameter-spec-local
- + (default '())
- + (sanitize local-sanitizer)
- + (thunked))
- + (defaults parameter-spec-defaults
- + (default '())
- + (thunked))
- + (required parameter-spec-required
- + (default '())
- + (thunked))
- + (optional parameter-spec-optional
- + (default '())
- + (thunked))
- + (one-of parameter-spec-one-of
- + (default '())
- + (thunked))
- + (combinations-with-substitutes
- + parameter-spec-combinations-with-substitutes
- + (default parameter-spec-defaults)
- + (thunked))
- + (use-variants parameter-spec-use-variants
- + (default '())
- + (sanitize (variant-sanitizer
- + (parameter-spec-local this-parameter-spec)))
- + (thunked))
- + (parameter-alist parameter-spec-parameter-alist
- + (default (base-parameter-alist this-parameter-spec))
- + (thunked)))
- +
- +(define-syntax parameter-spec-property
- + (syntax-rules ()
- + [(parameter-spec-property body ...)
- + (cons 'parameter-spec
- + (parameter-spec body ...))]))
- +
- +(define (apply-variants pkg vars)
- + "Apply a list of variants, VARS to the given package PKG."
- + (define (exact-sub v)
- + (match v
- + [(lst ...) ; to traverse the tree
- + (map exact-sub v)]
- + [#:package-name
- + (package-name pkg)]
- + [#:package
- + pkg]
- + [#:parameter-value
- + (match vars
- + [((_ . rest) . others)
- + rest])]
- + [x x]))
- + ;; substitute keywords - transforms
- + (define* (substitute-keywords-for-transforms in #:optional (ret '()))
- + (match in
- + [(a . rest)
- + (substitute-keywords-for-transforms
- + rest
- + (cons (exact-sub a) ret))]
- + [() (match (reverse ret)
- + [(a . rest)
- + (cons a (string-join rest "="))])]))
- + ;; substitute keywords
- + (define* (substitute-keywords in #:optional (ret '()))
- + (match in
- + [(a . rest)
- + (substitute-keywords
- + a
- + (cons (exact-sub a) ret))]
- + [() (reverse ret)]))
- +
- + (match vars
- + [(pcell (option optargs ...) . rest)
- + (match option
- + ['build-system
- + ;; halt execution if it does not match
- + (if (member (package-build-system the-package)
- + optargs) ; will be a list of build systems
- + (apply-variants pkg (cons pcell
- + rest))
- + pkg)]
- + ['transform
- + (apply-variants
- + ((options->transformation
- + (map substitute-keywords-for-transforms optargs))
- + pkg)
- + (cons pcell
- + rest))]
- + ['lambda
- + (apply-variants
- + (fold
- + (lambda (fn pack)
- + (case (first (procedure-minimum-arity fn))
- + [(0) (fn)]
- + [(1) (fn pack)]
- + [(2) (fn pack (match pcell [(_ . rest) rest]))]
- + [else (raise (formatted-message
- + (G_ "Procedure ~s has invalid arity.")
- + fn))]))
- + pkg
- + optargs)
- + (cons pcell
- + rest))]
- + [oth
- + (raise (formatted-message
- + (G_ "Invalid Option: ")
- + oth))])]
- + [(pcell (option) . rest)
- + (apply-variants pkg (cons pcell rest))]
- + [(pcell) pkg]
- + [_ (raise (formatted-message
- + (G_ "Poorly formatted variant spec: ~s")
- + vars))]))
- +
- +(define-syntax package-with-parameters
- + (syntax-rules ()
- + [(% spec body ...)
- + (let* [(the-package-0 (package body ...))
- + (the-package (package
- + (inherit the-package-0)
- + (replacement (package-replacement the-package-0))
- + (location (package-location the-package-0))
- + (properties
- + (cons (cons 'parameter-spec
- + spec)
- + (package-properties the-package-0)))))]
- + (parameterize-package the-package
- + (parameter-spec-parameter-alist spec)
- + #:force-parameterization? #t))]))
- +
- +(define* (parameterize-package the-initial-package
- + the-initial-list
- + #:key (force-parameterization? #f))
- + "Evaluates THE-INITIAL-PACKAGE with the parameter-list THE-INITIAL-LIST."
- + (define-macro (assq-override! asslst key val)
- + `(set! ,asslst
- + (assq-set! ,asslst ,key ,val)))
- +
- + (define smoothen
- + (match-lambda
- + [(a . #:off)
- + (cons a
- + (parameter-type-negation
- + (package-parameter-type (parameter-spec-get-parameter spec a))))]
- + [(a . #:default)
- + (cons a
- + (parameter-type-default
- + (package-parameter-type (parameter-spec-get-parameter spec a))))]
- + [cell cell]))
- +
- + (let* [(the-initial-spec
- + (package-parameter-spec the-initial-package))
- + (the-original-parameter-list
- + (package-parameter-alist the-initial-package))
- + (the-parameter-list
- + (package-resolve-parameter-list the-initial-package
- + the-initial-list))]
- + ;; exit and return the same package if no impactful changes
- + (if (and (not force-parameterization?)
- + (null? (filter (match-lambda
- + [(parameter-sym . parameter-value)
- + (not (eqv? (assq-ref
- + the-original-parameter-list
- + parameter-sym)
- + parameter-value))])
- + the-parameter-list)))
- + the-initial-package
- + (let* [(the-spec ; this value gets called very often
- + (parameter-spec
- + (inherit the-initial-spec)
- + (parameter-alist
- + the-parameter-list)))
- + (the-package
- + (package
- + (inherit the-initial-package)
- + (replacement (package-replacement the-initial-package))
- + (location (package-location the-initial-package))
- + (properties (assq-set! (package-properties the-initial-package)
- + 'parameter-spec
- + the-spec))))
- + (the-variants
- + ;; first get list of normal variants (local, etc)
- + ;; then match over use-variants
- + ;; if rest #:yes, check the-parameter-list for val
- + ;; if rest #:no, purge from prev list
- + ;; if rest #:special, /replace/ value
- + (let ((var-lst (parameter-spec-use-variants the-spec)))
- + (map (match-lambda
- + [(key . rest)
- + (set! var-lst
- + (assq-set! var-lst
- + key
- + (package-parameter-variants
- + (parameter-spec-get-parameter the-spec key))))])
- + (filter (lambda (x)
- + ((package-parameter-predicate
- + (parameter-spec-get-parameter
- + the-spec
- + (first x)))
- + the-package))
- + (filter
- + (lambda (x)
- + (not (assq-ref var-lst (first x)))) ; not in the variant-lst?
- + the-parameter-list)))
- + (map
- + (match-lambda
- + [(key . rest)
- + (match rest
- + [#:yes (assq-override! var-lst
- + key
- + (package-parameter-variants
- + (parameter-spec-get-parameter the-spec key)))]
- + [#:no (set! var-lst
- + (assq-remove! var-lst
- + key))]
- + [_ #f])])
- + var-lst)
- +
- + var-lst))
- + (applicable-variants
- + (map (match-lambda
- + [(key . rest)
- + (cons (cons key
- + (assq-ref the-parameter-list key))
- + (apply append
- + (map (match-lambda
- + [(_ . remaining)
- + (return-list remaining)])
- + rest)))])
- + ;; does it have values?
- + (filter (match-lambda
- + [(_ . rest)
- + (not (null? rest))])
- + (map ;; get list of applicable values
- + (match-lambda
- + [(p . lst)
- + (let ((absv (assq-ref the-parameter-list p))
- + ;; if absv is -ve, only -ve values allowed
- + ;; if absv is +ve, only +ve and _ allowed
- + (negv (parameter-type-negation
- + (package-parameter-type
- + (parameter-spec-get-parameter the-spec p))))
- + (defv (parameter-type-default
- + (package-parameter-type
- + (parameter-spec-get-parameter the-spec p)))))
- + (cons p
- + (filter
- + (lambda (ls)
- + (match (first ls)
- + ['_ (not (eqv? absv negv))]
- + [#:off (eqv? absv negv)]
- + [#:default (eqv? absv defv)]
- + [oth (eqv? absv oth)]))
- + lst)))])
- + (filter (lambda (x) (assq-ref the-parameter-list (first x)))
- + the-variants)))))]
- + (fold (lambda (vlst pack)
- + (apply-variants pack vlst))
- + the-package
- + applicable-variants)))))
- +
- +(define (package-parameter-spec package)
- + "Takes a package PACKAGE and returns its parameter-spec."
- + (or (assq-ref (package-properties package) 'parameter-spec)
- + (parameter-spec))) ; returns empty spec
- +
- +(define (package-parameter-alist package)
- + "Takes a package PACKAGE and returns its parameter-list."
- + (parameter-spec-parameter-alist
- + (package-parameter-spec package)))
- +
- +;;; PROCESSING PIPELINE
- +
- +;; Convention:
- +;; Works on Parameters? -> parameter-spec/fun
- +;; Works on Parameter-Spec? -> parameter-spec/fun
- +(define (parameter-spec-get-parameter pspec pcons)
- + "Takes a parameter cell PCONS and returns the corresponding package-parameter."
- + (let ((psym (get-parameter-sym pcons)))
- + (or (find (lambda (x)
- + (eqv? psym
- + (package-parameter-name x)))
- + (parameter-spec-local pspec))
- + (hash-ref %global-parameters psym)
- + (raise (formatted-message
- + (G_ "Parameter not found: ~s")
- + psym)))))
- +
- +(define (parameter-spec-negation-supported? pspec x)
- + "Is negation supported for the given parameter X?"
- + (let ((negv
- + (parameter-type-negation (package-parameter-type (parameter-spec-get-parameter pspec x)))))
- + (if negv
- + negv
- + '_)))
- +
- +(define (get-parameter-spec-dependencies pspec psym)
- + "Get the dependencies of the corresponding parameter to a given parameter symbol, PSYM."
- + (let ([p (parameter-spec-get-parameter pspec psym)])
- + (return-list
- + (assq-ref (package-parameter-dependencies p)
- + 'parameter))))
- +
- +;; 1. Fetching
- +
- +(define (base-parameter-alist pspec) ; returns base case
- + "Returns the BASE-PARAMETER-ALIST for a given parameter-spec PSPEC."
- + ;; '((a . psym) (b . #f) ...)
- + (let* ((v1 (parameter-process-list ; returns funneled list
- + (append-everything
- + (parameter-spec-defaults pspec)
- + (parameter-spec-required pspec))))
- + (v2 (parameter-process-list
- + (append-everything
- + (apply append
- + ;; XXX: change to a filter-map
- + (filter (cut first <>)
- + (map (cut get-parameter-spec-dependencies pspec <>)
- + (return-list v1))))
- + v1))))
- + ;; funnel will signal duplication err
- + ;; check if base case is valid
- + (parameter-spec-validate pspec v2)
- + v2))
- +
- +;; 2. Processing
- +
- +;; IMPORTANT CHANGE: Symbolic Negation no longer supported (psym!)
- +(define (parameter-process-list lst)
- + "Processes and formats a list of parameters, LST."
- + (define (return-cell p)
- + (match p
- + [(a b) (cons a b)]
- + [(a . b) p]
- + [a (cons a '_)]))
- + (define (funnel plst)
- + (define* (group-values lst #:optional (carry '()))
- + (match lst
- + [((a . b) . rest)
- + (let ((v (assq-ref carry a)))
- + (group-values rest
- + (assq-set! carry
- + a
- + (cons b
- + (if v v '())))))]
- + [() carry]
- + [_ (raise (formatted-message
- + (G_ "Poorly formatted assoc-list in group-values! ~s")
- + lst))]))
- + (define (figure-out psym p)
- + (or (and (< (length p) 3)
- + (or (and (eq? (length p) 1) (first p))
- + (and (member '_ p)
- + (first (delq '_ p)))))
- + (raise (formatted-message
- + (G_ "Too many values for a single parameter: ~s with ~s")
- + psym p))))
- + (map (match-lambda [(parameter . values)
- + (cons parameter
- + (figure-out parameter ; for the error message
- + (delete-duplicates values)))])
- + (group-values plst)))
- + (funnel (map
- + return-cell
- + lst)))
- +
- +;; 3. Overriding
- +
- +(define (all-spec-parameters pspec) ; for the UI
- + "Returns all the parameters in a parameter-spec, PSPEC."
- + ;; '(sym-a sym-b ...)
- + (delete-duplicates
- + (map get-parameter-sym ; we do not care about the values
- + (append-everything ; works same as before
- + (map package-parameter-name
- + (parameter-spec-local pspec))
- + (parameter-spec-defaults pspec)
- + (parameter-spec-required pspec)
- + ;; We are NOT pulling dependencies at this phase
- + ;; They will not be influenced by the user parameter alist
- + (filter (lambda (x) (not (eqv? x '_)))
- + (apply append (parameter-spec-one-of pspec)))
- + (parameter-spec-optional pspec)))))
- +
- +(define* (all-spec-parameters-with-types pspec #:key (show-booleans? #t))
- + (if show-booleans?
- + (map (lambda (x)
- + (string-append
- + (symbol->string x)
- + ":"
- + (symbol->string
- + (parameter-type-name
- + (package-parameter-type (parameter-spec-get-parameter pspec (cons x #f)))))))
- + (all-spec-parameters pspec))
- + (map (lambda (x)
- + (string-append
- + (symbol->string x)
- + ((lambda (x)
- + (if (eqv? x 'boolean)
- + ""
- + (string-append ":" (symbol->string x))))
- + (parameter-type-name
- + (package-parameter-type (parameter-spec-get-parameter pspec (cons x #f)))))))
- + (all-spec-parameters pspec))))
- +
- +
- +;; Now we compare it against the PLIST
- +;; NOTE: This is the only instance where GLOBAL PARAMETERS may be used
- +;; Since referring to the package is not possible, we pass it instead of pspec
- +(define (package-override-plist pkg plist)
- + "Takes a package PKG and parameter-list PLIST and overrides PLIST according to the package."
- + (let* ((pspec (package-parameter-spec pkg))
- + (all-p (all-spec-parameters pspec))
- + (filtered-plist (filter (match-lambda
- + [(sym . rest)
- + (or (member sym all-p)
- + (and (hash-ref %global-parameters sym)
- + ((package-parameter-predicate
- + (hash-ref %global-parameters sym))
- + pkg)))])
- + (parameter-process-list plist)))
- + (filtered-first (map first filtered-plist))
- + (remaining-p (filter (lambda (x) (not (member x filtered-first)))
- + all-p)))
- + (append-everything filtered-plist
- + (map (lambda (x) (if (parameter-spec-negation-supported? pspec x)
- + (cons x #:off)
- + (cons x '_)))
- + remaining-p))))
- +
- +;; 4. Funneling
- +
- +(define (override-spec-multi-match pspec plst)
- + "Overrides various keyword values in the parameter-list PLST."
- + (map
- + (match-lambda
- + [(a . '_)
- + (cons a
- + (match
- + (parameter-type-accepted-values
- + (package-parameter-type (parameter-spec-get-parameter pspec a)))
- + [(_ . (val . rest)) val]))]
- + [(a . #:off)
- + (cons a
- + (parameter-type-negation (package-parameter-type (parameter-spec-get-parameter pspec a))))]
- + [(a . #:default)
- + (cons a
- + (parameter-type-default (package-parameter-type (parameter-spec-get-parameter pspec a))))]
- + [cell cell])
- + plst))
- +
- +;; 5. Validation
- +
- +(define (parameter-spec-validate pspec plst)
- + "Validates a parameter-list PLST against the parameter-spec PSPEC."
- + (define (process-multi-list lst)
- + (apply append
- + (map (lambda (x)
- + (parameter-process-list (list x)))
- + (filter (lambda (x) (not (eqv? x '_)))
- + lst))))
- +
- + ;; We want all tests to run
- + (let ((works? #t))
- +
- + (define (m+eqv? new-val orig-val)
- + (or (and (eqv? orig-val '_)
- + (not (eqv? new-val #:off)))
- + (eqv? orig-val new-val)))
- +
- + (define (throw+f sym vals)
- + (raise (formatted-message
- + (G_ "Parameter Validation Error: ~a with values ~s~%")
- + sym vals))
- + (set! works? #f))
- +
- + ;; first we check duplication
- + ;; a bit unnecessary
- + (define (validate/duplication)
- + (let ((symlst (map first plst)))
- + (unless (eqv? symlst (delete-duplicates symlst))
- + (throw+f "Duplicates" plst))))
- +
- + ;; logic checking checks for:
- + ;; - presence of required parameters
- + ;; - 'one-of' conflicts
- + ;; - dependency satisfaction
- + (define (validate/logic)
- + (map ; required
- + (match-lambda
- + [(psym . value)
- + (unless
- + (let ((new-val (assq-ref plst psym)))
- + (m+eqv? (if (eqv?
- + new-val
- + (parameter-spec-negation-supported?
- + pspec
- + psym))
- + #:off new-val)
- + value))
- + (throw+f "Unsatisfied Requirements" (cons psym value)))])
- + (parameter-process-list ; cannot have duplicates here!
- + (parameter-spec-required pspec)))
- + (map ; one-of
- + (lambda (ls)
- + (unless
- + (let ((satisfied (count
- + (match-lambda
- + [(psym . value)
- + (let ((new-val (assq-ref plst psym)))
- + (m+eqv?
- + (if
- + (eqv? new-val
- + (parameter-spec-negation-supported?
- + pspec
- + psym))
- + #:off new-val)
- + value))])
- + (process-multi-list ls)))) ; duplicates could happen!
- + (or (= satisfied 1)
- + (and (= satisfied 0)
- + (eqv? (first ls) '_))))
- + (throw+f "Unsatisfied One-Of" ls)))
- + (parameter-spec-one-of pspec))
- +
- + (unless (not (member #f
- + (return-list
- + (map (lambda (x)
- + (let ((deps (package-parameter-dependencies
- + (parameter-spec-get-parameter pspec x))))
- + (if deps
- + (not
- + (member
- + #f
- + (map
- + (lambda (dep)
- + ;; 0. restructure dep to a proper cell
- + (match (first
- + (parameter-process-list
- + (return-list dep)))
- + ;; 1. assq-ref
- + [(psym . value)
- + (m+eqv?
- + (assq-ref plst psym)
- + value)]))
- + (return-list
- + ;;; XXX: check for packages
- + ;; not doable in the current state as the validator
- + ;; does not take the entire package as an argument
- + ;; the validator will have to be heavily modified
- + (assq-ref deps 'parameter)))))
- + #t)))
- + ;; filter to check if parameter is not its negation
- + (filter (match-lambda
- + [(psym . value)
- + (not (eqv? value
- + (parameter-spec-negation-supported?
- + pspec
- + psym)))])
- + plst)))))
- + (throw+f "Bad dependencies!" plst)))
- +
- + (validate/duplication)
- +
- + (validate/logic)
- +
- + works?))
- +
- +;; need pkg instead of pspec for override-spec
- +(define (package-resolve-parameter-list pkg plst)
- + "Resolves a parameter-list PLST against the package PKG."
- + (let* ([pspec (package-parameter-spec pkg)]
- + [proper-plst (override-spec-multi-match
- + pspec
- + (package-override-plist
- + pkg
- + (parameter-process-list plst)))])
- + (if (parameter-spec-validate pspec proper-plst)
- + proper-plst
- + (base-parameter-alist pspec))))
- +
- +;; %global-parameters: hash table containing global parameters ref'd by syms
- +
- +(define-syntax define-global-parameter
- + (syntax-rules ()
- + [(define-global-parameter parameter-definition)
- + (let ((gp-val parameter-definition))
- + (hash-set! %global-parameters
- + (package-parameter-name gp-val)
- + gp-val))]))
- +
- +(define-syntax parameter-inside?
- + (syntax-rules ()
- + [(% p pkg)
- + (let ((plst
- + (parameter-spec-parameter-alist
- + (package-parameter-spec pkg))))
- + (not
- + (eqv? (or (assq-ref plst (first p))
- + (error "Parameter not found!"))
- + (parameter-type-negation
- + (package-parameter-type
- + (parameter-spec-get-parameter
- + (package-parameter-spec pkg)
- + p))))))]))
- +
- +(define-syntax parameter-if
- + (syntax-rules ()
- + [(parameter-if #:package pkg rest ...)
- + (parameter-if-branches pkg rest ...)]
- + [(parameter-if rest ...)
- + (parameter-if-branches this-pkg rest ...)]))
- +
- +(define-syntax parameter-if-branches
- + (syntax-rules ()
- + [(parameter-if-branches pkg parameters exp)
- + (parameter-if-driven pkg parameters exp '())]
- + [(parameter-if-branches pkg parameters exp exp-else)
- + (parameter-if-driven pkg parameters exp exp-else)]
- + [(% anything ...)
- + (raise (formatted-message
- + (G_ "Poorly formatted parameter-if: ~s"
- + '(parameter-if anything ...))))]))
- +
- +(define-syntax parameter-if-driven
- + (syntax-rules ()
- + [(parameter-if-driven pkg (#:all parameters ...) exp exp-else)
- + (if (not (member
- + #f
- + (map (cut parameter-inside? <> pkg)
- + (parameter-process-list '(parameters ...)))))
- + exp
- + exp-else)]
- + [(parameter-if-driven pkg (parameters ...) exp exp-else)
- + (if (member
- + #t
- + (map (cut parameter-inside? <> pkg)
- + (parameter-process-list '(parameters ...))))
- + exp
- + exp-else)]))
- +
- +(define-syntax parameter-match
- + (syntax-rules (_)
- + [(% #:package pkg rest ...)
- + (parameter-match-driven pkg rest ...)]
- + [(% rest ...)
- + (parameter-match-driven this-package rest ...)]))
- +
- +(define-syntax parameter-match-driven
- + (syntax-rules (_)
- + [(% pkg) '()]
- + [(% pkg (_ clauses ...) rest ...) (begin (begin clauses ...) (parameter-match-driven pkg rest ...))]
- + [(% pkg (parameters) rest ...) (parameter-match-driven pkg rest ...)]
- + [(% pkg ((#:all parameters ...) clauses ...) rest ...)
- + (begin
- + (and (not (member #f (map (cut parameter-inside? <> pkg)
- + (parameter-process-list '(parameters ...)))))
- + (begin clauses ...))
- + (parameter-match-driven pkg rest ...))]
- + [(% pkg ((parameters ...) clauses ...) rest ...)
- + (begin
- + (and (member #t (map (cut parameter-inside? <> pkg)
- + (parameter-process-list '(parameters ...))))
- + (begin clauses ...))
- + (parameter-match-driven pkg rest ...))]
- + [(% pkg (parameter clauses ...) rest ...)
- + (begin
- + (and (parameter-inside? parameter pkg)
- + (begin clauses ...))
- + (parameter-match-driven pkg rest ...))]
- + [(% pkg anything ...)
- + (raise (formatted-message
- + (G_ "Poorly formatted parameter-match: ~s"
- + '(parameter-match anything ...))))]))
- +
- +(define-syntax parameter-match-case
- + (syntax-rules (_)
- + [(% #:package pkg rest ...)
- + (parameter-match-case-driven pkg rest ...)]
- + [(% rest ...)
- + (parameter-match-case-driven this-package rest ...)]))
- +
- +(define-syntax parameter-match-case-driven
- + (syntax-rules (_)
- + [(% pkg) '()]
- + [(% pkg (_ clauses ...) rest ...) (begin clauses ...)]
- + [(% pkg (parameters) rest ...) (parameter-match-case-driven pkg rest ...)]
- + [(% pkg ((#:all parameters ...) clauses ...) rest ...)
- + (if (not (member #f (map (cut parameter-inside? <> pkg)
- + (parameter-process-list '(parameters ...)))))
- + (begin clauses ...)
- + (parameter-match-case-driven pkg rest ...))]
- + [(% pkg ((parameters ...) clauses ...) rest ...)
- + (if (member #t (map (cut parameter-inside? <> pkg)
- + (parameter-process-list '(parameters ...))))
- + (begin clauses ...)
- + (parameter-match-case-driven pkg rest ...))]
- + [(% pkg (parameter clauses ...) rest ...)
- + (if (parameter-inside? parameter pkg)
- + (begin clauses ...)
- + (parameter-match-case-driven pkg rest ...))]
- + [(% pkg anything ...)
- + (raise (formatted-message
- + (G_ "Poorly formatted parameter-match-case: ~s"
- + '(parameter-match-case anything ...))))]))
- +
- +;; modified to take the original package, similar to modify-inputs
- +(define-syntax parameter-modify-inputs
- + (syntax-rules (_ :lock prepend append delete replace)
- + [(% inputs) inputs]
- + [(% inputs :lock ())
- + inputs]
- + [(% inputs :lock (stuff ...))
- + (modify-inputs inputs stuff ...)]
- + [(% inputs :lock (stuff ...) (_ clauses ...) rest ...)
- + (parameter-modify-inputs inputs :lock (stuff ... clauses ...) rest ...)]
- + [(% inputs :lock stuff (parameters) rest ...)
- + (parameter-modify-inputs inputs :lock stuff rest ...)]
- + [(% inputs :lock (stuff ...) ((#:all parameters ...) clauses ...) rest ...)
- + (if (not (member #f (map (cut parameter-inside?
- + <> this-package)
- + (parameter-process-list '(parameters ...)))))
- + (parameter-modify-inputs inputs :lock
- + (stuff ... clauses ...)
- + rest ...)
- + (parameter-modify-inputs inputs :lock (stuff ...) rest ...))]
- + [(% inputs :lock (stuff ...) ((parameters ...) clauses ...) rest ...)
- + (if (member #t (map (cut parameter-inside?
- + <> this-package)
- + (parameter-process-list '(parameters ...))))
- + (parameter-modify-inputs inputs :lock
- + (stuff ... clauses ...)
- + rest ...)
- + (parameter-modify-inputs inputs :lock (stuff ...) rest ...))]
- + [(% inputs :lock (stuff ...) (parameter clauses ...) rest ...)
- + (if (parameter-inside? parameter
- + this-package)
- + (parameter-modify-inputs inputs :lock
- + (stuff ... clauses ...)
- + rest ...)
- + (parameter-modify-inputs inputs :lock (stuff ...) rest ...))]
- + [(% inputs rest ...)
- + (parameter-modify-inputs inputs :lock () rest ...)]
- + [(% . anything)
- + (raise (formatted-message (G_ "Poorly formatted parameter-modify-inputs: ~s" anything)))]))
- +
- +(define-syntax parameter-substitute-keyword-arguments
- + (syntax-rules (_ :lock prepend append delete replace)
- + [(% arguments) arguments]
- + [(% arguments :lock ())
- + arguments]
- + [(% arguments :lock (stuff ...))
- + (substitute-keyword-arguments arguments stuff ...)]
- + [(% arguments :lock (stuff ...) (_ clauses ...) rest ...)
- + (parameter-substitute-keyword-arguments arguments :lock (stuff ... clauses ...) rest ...)]
- + [(% arguments :lock stuff (parameters) rest ...)
- + (parameter-substitute-keyword-arguments arguments :lock stuff rest ...)]
- + [(% arguments :lock (stuff ...) ((#:all parameters ...) clauses ...) rest ...)
- + (if (not (member #f (map (cut parameter-inside?
- + <> this-package)
- + (parameter-process-list '(parameters ...)))))
- + (parameter-substitute-keyword-arguments arguments :lock
- + (stuff ... clauses ...)
- + rest ...)
- + (parameter-substitute-keyword-arguments arguments :lock (stuff ...) rest ...))]
- + [(% arguments :lock (stuff ...) ((parameters ...) clauses ...) rest ...)
- + (if (member #t (map (cut parameter-inside?
- + <> this-package)
- + (parameter-process-list '(parameters ...))))
- + (parameter-substitute-keyword-arguments arguments :lock
- + (stuff ... clauses ...)
- + rest ...)
- + (parameter-substitute-keyword-arguments arguments :lock (stuff ...) rest ...))]
- + [(% arguments :lock (stuff ...) (parameter clauses ...) rest ...)
- + (if (parameter-inside? parameter
- + this-package)
- + (parameter-substitute-keyword-arguments arguments :lock
- + (stuff ... clauses ...)
- + rest ...)
- + (parameter-substitute-keyword-arguments arguments :lock (stuff ...) rest ...))]
- + [(% arguments rest ...)
- + (parameter-substitute-keyword-arguments arguments :lock () rest ...)]
- + [(% . anything)
- + (raise (formatted-message (G_ "Poorly formatted parameter-substitute-keyword-arguments: ~s" anything)))]))
- +
- +
- +;; Some global parameters
- +
- +(define-global-parameter
- + (package-parameter
- + (name 'static-lib)
- + (variants
- + (parameter-variant-match
- + (_ #:transform
- + (with-configure-flag #:package-name "=--disable-shared")
- + (with-configure-flag #:package-name "=--enable-static"))))
- + (predicate #t)))
- +
- +(define-global-parameter
- + (package-parameter
- + (name 'tests)
- + (variants
- + (parameter-variant-match
- + (#:off #:transform (without-tests #:package-name))))
- + (description "Toggle for tests")
- + (predicate #t)))
- diff --git a/guix/transformations.scm b/guix/transformations.scm
- index 9cba6bedab..f451d646f9 100644
- --- a/guix/transformations.scm
- +++ b/guix/transformations.scm
- @@ -36,6 +36,7 @@ (define-module (guix transformations)
- #:autoload (guix cpu) (current-cpu
- cpu->gcc-architecture
- gcc-architecture->micro-architecture-level)
- + #:autoload (guix parameters) (package-parameter-alist parameterize-package)
- #:use-module (guix utils)
- #:use-module (guix memoization)
- #:use-module (guix gexp)
- @@ -354,6 +355,59 @@ (define rewrite
- (rewrite obj)
- obj)))
-
- +(define (evaluate-parameter-specs specs)
- + "Parse SPECS, a list of strings like \"bitlbee=purple=true\", and return a
- +list of spec/procedure pairs, where (PROC PACKAGE PARAMETER VALUE) is called
- +to return the replacement package. Raise an error if an element of SPECS uses
- +invalid syntax, or if a package it refers to could not be found."
- + (let [(package-assq '())]
- + (map (lambda (spec)
- + (match (string-tokenize spec %not-equal)
- + ((pkg name value)
- + (set! package-assq
- + (assq-set! package-assq pkg
- + (cons (cons (string->symbol name)
- + (string->symbol value))
- + (or (assq-ref package-assq pkg)
- + '())))))
- + (_
- + (raise
- + (formatted-message
- + (G_ "invalid package parameter specification: ~s")
- + spec)))))
- + specs)
- + (map (lambda (x) ; (<pkg> <plist>)
- + (let ((package-name (car x))
- + (parameter-lst (cdr x)))
- + (cons package-name
- + (lambda (x)
- + (let* [(original-lst (map (lambda (x)
- + (cons (car x) (cdr x)))
- + (package-parameter-alist x)))
- + (final-lst
- + (fold (lambda (z y)
- + (assq-set! y
- + (car z)
- + (cdr z)))
- + original-lst
- + parameter-lst))]
- + (parameterize-package x final-lst))))))
- + package-assq)))
- +
- +(define (transform-package-parameters replacement-specs)
- + "Return a procedure that, when passed a package, replaces its direct
- +dependencies according to REPLACEMENT-SPECS. REPLACEMENT-SPECS is a list of
- +strings like \"guile-next=stable-3.0\" meaning that packages are built using
- +'guile-next' from the latest commit on its 'stable-3.0' branch."
- +
- + ;; we'll apply per-package parameterization and then return
- + (let* ((replacements (evaluate-parameter-specs replacement-specs))
- + (rewrite (package-input-rewriting/spec replacements)))
- + (lambda (obj)
- + (if (package? obj)
- + (rewrite obj)
- + obj))))
- +
- (define (package-dependents/spec top bottom)
- "Return the list of dependents of BOTTOM, a spec string, that are also
- dependencies of TOP, a package."
- @@ -910,6 +964,7 @@ (define %transformations
- (with-branch . ,transform-package-source-branch)
- (with-commit . ,transform-package-source-commit)
- (with-git-url . ,transform-package-source-git-url)
- + (with-parameter . ,transform-package-parameters)
- (with-c-toolchain . ,transform-package-toolchain)
- (tune . ,transform-package-tuning)
- (with-debug-info . ,transform-package-with-debug-info)
- @@ -957,6 +1012,8 @@ (define %transformation-options
- (parser 'with-commit))
- (option '("with-git-url") #t #f
- (parser 'with-git-url))
- + (option '("with-parameter") #t #f
- + (parser 'with-parameter))
- (option '("with-c-toolchain") #t #f
- (parser 'with-c-toolchain))
- (option '("tune") #f #t
- diff --git a/guix/ui.scm b/guix/ui.scm
- index 6f2d4fe245..013091d458 100644
- --- a/guix/ui.scm
- +++ b/guix/ui.scm
- @@ -19,6 +19,7 @@
- ;;; Copyright © 2018 Steve Sprang <scs@stevesprang.com>
- ;;; Copyright © 2022 Taiju HIGASHI <higashi@taiju.info>
- ;;; Copyright © 2022 Liliana Marie Prikler <liliana.prikler@gmail.com>
- +;;; Copyright © 2023 Sarthak Shah <shahsarthakw@gmail.com>
- ;;;
- ;;; This file is part of GNU Guix.
- ;;;
- @@ -76,6 +77,7 @@ (define-module (guix ui)
- #:use-module (ice-9 format)
- #:use-module (ice-9 regex)
- #:autoload (ice-9 popen) (open-pipe* close-pipe)
- + #:autoload (guix parameters) (all-spec-parameters-with-types package-parameter-spec)
- #:autoload (system repl repl) (start-repl)
- #:autoload (system repl debug) (make-debug stack->vector)
- #:use-module (texinfo)
- @@ -1607,7 +1609,11 @@ (define highlighting*
- (outputs ; multiple outputs
- (format port "outputs:~%~{~a~%~}"
- (map (cut output->recutils p <>) (package-outputs/out-last p)))))
- -
- + (match (all-spec-parameters-with-types
- + (package-parameter-spec p))
- + (() #t)
- + (lst (format port "parameters:~{ ~a~}~%"
- + lst)))
- (format port "systems: ~a~%"
- (split-lines (string-join (package-transitive-supported-systems p))
- (string-length "systems: ")))
|