1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
4 ;;; Copyright © 2013, 2015 Mark H Weaver <mhw@netris.org>
5 ;;; Copyright © 2014, 2016 Alex Kost <alezost@gmail.com>
6 ;;; Copyright © 2016 Roel Janssen <roel@gnu.org>
7 ;;; Copyright © 2016 Benz Schenk <benz.schenk@uzh.ch>
8 ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
10 ;;; This file is part of GNU Guix.
12 ;;; GNU Guix is free software; you can redistribute it and/or modify it
13 ;;; under the terms of the GNU General Public License as published by
14 ;;; the Free Software Foundation; either version 3 of the License, or (at
15 ;;; your option) any later version.
17 ;;; GNU Guix is distributed in the hope that it will be useful, but
18 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;;; GNU General Public License for more details.
22 ;;; You should have received a copy of the GNU General Public License
23 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
25 (define-module (guix scripts package)
26 #:use-module (guix ui)
27 #:use-module (guix store)
28 #:use-module (guix grafts)
29 #:use-module (guix derivations)
30 #:use-module (guix packages)
31 #:use-module (guix profiles)
32 #:use-module (guix search-paths)
33 #:use-module (guix monads)
34 #:use-module (guix utils)
35 #:use-module (guix config)
36 #:use-module (guix scripts)
37 #:use-module (guix scripts build)
38 #:use-module ((guix build utils)
39 #:select (directory-exists? mkdir-p))
40 #:use-module (ice-9 format)
41 #:use-module (ice-9 match)
42 #:use-module (ice-9 vlist)
43 #:use-module (srfi srfi-1)
44 #:use-module (srfi srfi-11)
45 #:use-module (srfi srfi-26)
46 #:use-module (srfi srfi-34)
47 #:use-module (srfi srfi-35)
48 #:use-module (srfi srfi-37)
49 #:use-module (gnu packages)
50 #:autoload (gnu packages base) (canonical-package)
51 #:autoload (gnu packages guile) (guile-2.0)
52 #:autoload (gnu packages bootstrap) (%bootstrap-guile)
53 #:export (build-and-use-profile
66 (define %user-profile-directory
67 (and=> (getenv "HOME")
68 (cut string-append <> "/.guix-profile")))
70 (define %profile-directory
71 (string-append %state-directory "/profiles/"
72 (or (and=> (or (getenv "USER")
74 (cut string-append "per-user/" <>))
77 (define %current-profile
78 ;; Call it `guix-profile', not `profile', to allow Guix profiles to
79 ;; coexist with Nix profiles.
80 (string-append %profile-directory "/guix-profile"))
82 (define (canonicalize-profile profile)
83 "If PROFILE is %USER-PROFILE-DIRECTORY, return %CURRENT-PROFILE. Otherwise
84 return PROFILE unchanged. The goal is to treat '-p ~/.guix-profile' as if
85 '-p' was omitted." ; see <http://bugs.gnu.org/17939>
86 (if (and %user-profile-directory
87 (string=? (canonicalize-path (dirname profile))
88 (dirname %user-profile-directory))
89 (string=? (basename profile) (basename %user-profile-directory)))
93 (define (user-friendly-profile profile)
94 "Return either ~/.guix-profile if that's what PROFILE refers to, directly or
95 indirectly, or PROFILE."
96 (if (and %user-profile-directory
98 (string=? (readlink %user-profile-directory) profile)))
99 %user-profile-directory
102 (define (ensure-default-profile)
103 "Ensure the default profile symlink and directory exist and are writable."
106 (format (current-error-port)
107 (_ "Try \"info '(guix) Invoking guix package'\" for \
108 more information.~%"))
111 ;; Create ~/.guix-profile if it doesn't exist yet.
112 (when (and %user-profile-directory
114 (not (false-if-exception
115 (lstat %user-profile-directory))))
116 (symlink %current-profile %user-profile-directory))
118 (let ((s (stat %profile-directory #f)))
119 ;; Attempt to create /…/profiles/per-user/$USER if needed.
120 (unless (and s (eq? 'directory (stat:type s)))
123 (mkdir-p %profile-directory))
125 ;; Often, we cannot create %PROFILE-DIRECTORY because its
126 ;; parent directory is root-owned and we're running
128 (format (current-error-port)
129 (_ "error: while creating directory `~a': ~a~%")
131 (strerror (system-error-errno args)))
132 (format (current-error-port)
133 (_ "Please create the `~a' directory, with you as the owner.~%")
137 ;; Bail out if it's not owned by the user.
138 (unless (or (not s) (= (stat:uid s) (getuid)))
139 (format (current-error-port)
140 (_ "error: directory `~a' is not owned by you~%")
142 (format (current-error-port)
143 (_ "Please change the owner of `~a' to user ~s.~%")
144 %profile-directory (or (getenv "USER")
149 (define (delete-generations store profile generations)
150 "Delete GENERATIONS from PROFILE.
151 GENERATIONS is a list of generation numbers."
152 (for-each (cut delete-generation* store profile <>)
155 (define (delete-matching-generations store profile pattern)
156 "Delete from PROFILE all the generations matching PATTERN. PATTERN must be
157 a string denoting a set of generations: the empty list means \"all generations
158 but the current one\", a number designates a generation, and other patterns
159 denote ranges as interpreted by 'matching-generations'."
160 (let ((current (generation-number profile)))
161 (cond ((not (file-exists? profile)) ; XXX: race condition
162 (raise (condition (&profile-not-found-error
163 (profile profile)))))
164 ((string-null? pattern)
165 (delete-generations store profile
166 (delv current (profile-generations profile))))
167 ;; Do not delete the zeroth generation.
168 ((equal? 0 (string->number pattern))
171 ;; If PATTERN is a duration, match generations that are
172 ;; older than the specified duration.
173 ((matching-generations pattern profile
174 #:duration-relation >)
177 (when (memv current numbers)
178 (warning (_ "not removing generation ~a, which is current~%")
181 ;; Make sure we don't inadvertently remove the current
183 (let ((numbers (delv current numbers)))
184 (when (null-list? numbers)
185 (leave (_ "no matching generation~%")))
186 (delete-generations store profile numbers))))
188 (leave (_ "invalid syntax: ~a~%") pattern)))))
190 (define* (build-and-use-profile store profile manifest
192 bootstrap? use-substitutes?
194 "Build a new generation of PROFILE, a file name, using the packages
195 specified in MANIFEST, a manifest object."
196 (when (equal? profile %current-profile)
197 (ensure-default-profile))
199 (let* ((prof-drv (run-with-store store
200 (profile-derivation manifest
201 #:hooks (if bootstrap?
203 %default-profile-hooks)
204 #:locales? (not bootstrap?))))
205 (prof (derivation->output-path prof-drv)))
206 (show-what-to-build store (list prof-drv)
207 #:use-substitutes? use-substitutes?
212 ((and (file-exists? profile)
213 (and=> (readlink* profile) (cut string=? prof <>)))
214 (format (current-error-port) (_ "nothing to be done~%")))
216 (let* ((number (generation-number profile))
218 ;; Always use NUMBER + 1 for the new profile, possibly
219 ;; overwriting a "previous future generation".
220 (name (generation-file-name profile (+ 1 number))))
221 (and (build-derivations store (list prof-drv))
222 (let* ((entries (manifest-entries manifest))
223 (count (length entries)))
224 (switch-symlinks name prof)
225 (switch-symlinks profile name)
226 (unless (string=? profile %current-profile)
227 (register-gc-root store name))
228 (format #t (N_ "~a package in profile~%"
229 "~a packages in profile~%"
232 (display-search-paths entries (list profile)
233 #:kind 'prefix))))))))
237 ;;; Package specifications.
240 (define (find-packages-by-description regexps)
241 "Return the list of packages whose name matches one of REGEXPS, or whose
242 synopsis or description matches all of REGEXPS."
243 (define version<? (negate version>=?))
245 (define (matches-all? str)
246 (every (cut regexp-exec <> str) regexps))
248 (define (matches-one? str)
249 (find (cut regexp-exec <> str) regexps))
252 (fold-packages (lambda (package result)
253 (if (or (matches-one? (package-name package))
254 (and=> (package-synopsis package)
255 (compose matches-all? P_))
256 (and=> (package-description package)
257 (compose matches-all? P_)))
258 (cons package result)
262 (case (string-compare (package-name p1) (package-name p2)
263 (const '<) (const '=) (const '>))
264 ((=) (version<? (package-version p1) (package-version p2)))
268 (define (transaction-upgrade-entry entry transaction)
269 "Return a variant of TRANSACTION that accounts for the upgrade of ENTRY, a
271 (define (supersede old new)
272 (info (_ "package '~a' has been superseded by '~a'~%")
273 (manifest-entry-name old) (package-name new))
274 (manifest-transaction-install-entry
275 (package->manifest-entry new (manifest-entry-output old))
276 (manifest-transaction-remove-pattern
278 (name (manifest-entry-name old))
279 (version (manifest-entry-version old))
280 (output (manifest-entry-output old)))
284 (($ <manifest-entry> name version output (? string? path))
285 (match (vhash-assoc name (find-newest-available-packages))
286 ((_ candidate-version pkg . rest)
287 (match (package-superseded pkg)
289 (supersede entry new))
291 (case (version-compare candidate-version version)
293 (manifest-transaction-install-entry
294 (package->manifest-entry pkg output)
299 (let ((candidate-path (derivation->output-path
300 (package-derivation (%store) pkg))))
301 (if (string=? path candidate-path)
303 (manifest-transaction-install-entry
304 (package->manifest-entry pkg output)
314 (define* (search-path-environment-variables entries profiles
315 #:optional (getenv getenv)
317 "Return environment variable definitions that may be needed for the use of
318 ENTRIES, a list of manifest entries, in PROFILES. Use GETENV to determine the
319 current settings and report only settings not already effective. KIND
320 must be one of 'exact, 'prefix, or 'suffix, depending on the kind of search
321 path definition to be returned."
322 (let ((search-paths (delete-duplicates
324 (append-map manifest-entry-search-paths
326 (filter-map (match-lambda
328 (let ((variable (search-path-specification-variable spec))
329 (sep (search-path-specification-separator spec)))
330 (environment-variable-definition variable value
333 (evaluate-search-paths search-paths profiles
336 (define* (display-search-paths entries profiles
338 "Display the search path environment variables that may need to be set for
339 ENTRIES, a list of manifest entries, in the context of PROFILE."
340 (let* ((profiles (map user-friendly-profile profiles))
341 (settings (search-path-environment-variables entries profiles
343 (unless (null? settings)
344 (format #t (_ "The following environment variable definitions may be needed:~%"))
345 (format #t "~{ ~a~%~}" settings))))
349 ;;; Command-line options.
352 (define %default-options
353 ;; Alist of default option values.
354 `((max-silent-time . 3600)
357 (substitutes? . #t)))
360 (display (_ "Usage: guix package [OPTION]...
361 Install, remove, or upgrade packages in a single transaction.\n"))
363 -i, --install PACKAGE ...
366 -e, --install-from-expression=EXP
367 install the package EXP evaluates to"))
369 -f, --install-from-file=FILE
370 install the package that the code within FILE
373 -r, --remove PACKAGE ...
376 -u, --upgrade[=REGEXP] upgrade all the installed packages matching REGEXP"))
378 -m, --manifest=FILE create a new profile generation with the manifest
381 --do-not-upgrade[=REGEXP] do not upgrade any packages matching REGEXP"))
383 --roll-back roll back to the previous generation"))
385 --search-paths[=KIND]
386 display needed environment variable definitions"))
388 -l, --list-generations[=PATTERN]
389 list generations matching PATTERN"))
391 -d, --delete-generations[=PATTERN]
392 delete generations matching PATTERN"))
394 -S, --switch-generation=PATTERN
395 switch to a generation matching PATTERN"))
397 -p, --profile=PROFILE use PROFILE instead of the user's default profile"))
400 --bootstrap use the bootstrap Guile to build the profile"))
402 --verbose produce verbose output"))
405 -s, --search=REGEXP search in synopsis and description using REGEXP"))
407 -I, --list-installed[=REGEXP]
408 list installed packages matching REGEXP"))
410 -A, --list-available[=REGEXP]
411 list available packages matching REGEXP"))
413 --show=PACKAGE show details about PACKAGE"))
415 (show-build-options-help)
417 (show-transformation-options-help)
420 -h, --help display this help and exit"))
422 -V, --version display version information and exit"))
424 (show-bug-report-information))
427 ;; Specification of the command-line options.
428 (cons* (option '(#\h "help") #f #f
432 (option '(#\V "version") #f #f
434 (show-version-and-exit "guix package")))
436 (option '(#\i "install") #f #t
437 (lambda (opt name arg result arg-handler)
438 (let arg-handler ((arg arg) (result result))
440 (alist-cons 'install arg result)
443 (option '(#\e "install-from-expression") #t #f
444 (lambda (opt name arg result arg-handler)
445 (values (alist-cons 'install (read/eval-package-expression arg)
448 (option '(#\f "install-from-file") #t #f
449 (lambda (opt name arg result arg-handler)
450 (values (alist-cons 'install
451 (load* arg (make-user-module '()))
454 (option '(#\r "remove") #f #t
455 (lambda (opt name arg result arg-handler)
456 (let arg-handler ((arg arg) (result result))
458 (alist-cons 'remove arg result)
461 (option '(#\u "upgrade") #f #t
462 (lambda (opt name arg result arg-handler)
463 (let arg-handler ((arg arg) (result result))
464 (values (alist-cons 'upgrade arg
465 ;; Delete any prior "upgrade all"
466 ;; command, or else "--upgrade gcc"
467 ;; would upgrade everything.
468 (delete '(upgrade . #f) result))
470 (option '("do-not-upgrade") #f #t
471 (lambda (opt name arg result arg-handler)
472 (let arg-handler ((arg arg) (result result))
474 (alist-cons 'do-not-upgrade arg result)
477 (option '("roll-back") #f #f
478 (lambda (opt name arg result arg-handler)
479 (values (alist-cons 'roll-back? #t result)
481 (option '(#\m "manifest") #t #f
482 (lambda (opt name arg result arg-handler)
483 (values (alist-cons 'manifest arg result)
485 (option '(#\l "list-generations") #f #t
486 (lambda (opt name arg result arg-handler)
487 (values (cons `(query list-generations ,(or arg ""))
490 (option '(#\d "delete-generations") #f #t
491 (lambda (opt name arg result arg-handler)
492 (values (alist-cons 'delete-generations (or arg "")
495 (option '(#\S "switch-generation") #t #f
496 (lambda (opt name arg result arg-handler)
497 (values (alist-cons 'switch-generation arg result)
499 (option '("search-paths") #f #t
500 (lambda (opt name arg result arg-handler)
501 (let ((kind (match arg
502 ((or "exact" "prefix" "suffix")
503 (string->symbol arg))
507 (leave (_ "~a: unsupported \
508 kind of search path~%")
510 (values (cons `(query search-paths ,kind)
513 (option '(#\p "profile") #t #f
514 (lambda (opt name arg result arg-handler)
515 (values (alist-cons 'profile (canonicalize-profile arg)
518 (option '(#\n "dry-run") #f #f
519 (lambda (opt name arg result arg-handler)
520 (values (alist-cons 'dry-run? #t
521 (alist-cons 'graft? #f result))
523 (option '("bootstrap") #f #f
524 (lambda (opt name arg result arg-handler)
525 (values (alist-cons 'bootstrap? #t result)
527 (option '("verbose") #f #f
528 (lambda (opt name arg result arg-handler)
529 (values (alist-cons 'verbose? #t result)
531 (option '(#\s "search") #t #f
532 (lambda (opt name arg result arg-handler)
533 (values (cons `(query search ,(or arg ""))
536 (option '(#\I "list-installed") #f #t
537 (lambda (opt name arg result arg-handler)
538 (values (cons `(query list-installed ,(or arg ""))
541 (option '(#\A "list-available") #f #t
542 (lambda (opt name arg result arg-handler)
543 (values (cons `(query list-available ,(or arg ""))
546 (option '("show") #t #t
547 (lambda (opt name arg result arg-handler)
548 (values (cons `(query show ,arg)
552 (append %transformation-options
553 %standard-build-options)))
555 (define (options->upgrade-predicate opts)
556 "Return a predicate based on the upgrade/do-not-upgrade regexps in OPTS
557 that, given a package name, returns true if the package is a candidate for
558 upgrading, #f otherwise."
559 (define upgrade-regexps
560 (filter-map (match-lambda
562 (make-regexp* (or regexp "")))
566 (define do-not-upgrade-regexps
567 (filter-map (match-lambda
568 (('do-not-upgrade . regexp)
569 (make-regexp* regexp))
574 (and (any (cut regexp-exec <> name) upgrade-regexps)
575 (not (any (cut regexp-exec <> name) do-not-upgrade-regexps)))))
577 (define (store-item->manifest-entry item)
578 "Return a manifest entry for ITEM, a \"/gnu/store/...\" file name."
579 (let-values (((name version)
580 (package-name->name+version (store-path-package-name item)
585 (output "out") ;XXX: wild guess
588 (define (options->installable opts manifest transaction)
589 "Given MANIFEST, the current manifest, and OPTS, the result of 'args-fold',
590 return an variant of TRANSACTION that accounts for the specified installations
593 (options->upgrade-predicate opts))
596 (fold (lambda (entry transaction)
597 (if (upgrade? (manifest-entry-name entry))
598 (transaction-upgrade-entry entry transaction)
601 (manifest-entries manifest)))
604 (filter-map (match-lambda
605 (('install . (? package? p))
606 ;; When given a package via `-e', install the first of its
608 (package->manifest-entry p "out"))
609 (('install . (? string? spec))
610 (if (store-path? spec)
611 (store-item->manifest-entry spec)
612 (let-values (((package output)
613 (specification->package+output spec)))
614 (package->manifest-entry package output))))
618 (fold manifest-transaction-install-entry
622 (define (options->removable options manifest transaction)
623 "Given options, return a variant of TRANSACTION augmented with the list of
624 patterns of packages to remove."
625 (fold (lambda (opt transaction)
630 (package-specification->name+version+output spec))
631 (lambda (name version output)
632 (manifest-transaction-remove-pattern
642 (define (register-gc-root store profile)
643 "Register PROFILE, a profile generation symlink, as a GC root, unless it
646 ;; We must pass the daemon an absolute file name for PROFILE. However, we
647 ;; cannot use (canonicalize-path profile) because that would return us the
648 ;; target of PROFILE in the store; using a store item as an indirect root
649 ;; would mean that said store item will always remain live, which is not
650 ;; what we want here.
651 (if (string-prefix? "/" profile)
653 (string-append (getcwd) "/" profile)))
655 (add-indirect-root store absolute))
659 ;;; Queries and actions.
662 (define (process-query opts)
663 "Process any query specified by OPTS. Return #t when a query was actually
664 processed, #f otherwise."
665 (let* ((profiles (match (filter-map (match-lambda
669 (() (list %current-profile))
670 (lst (reverse lst))))
671 (profile (match profiles
672 ((head tail ...) head))))
673 (match (assoc-ref opts 'query)
674 (('list-generations pattern)
675 (define (list-generation display-function number)
676 (unless (zero? number)
677 (display-generation profile number)
678 (display-function profile number)
680 (define (diff-profiles profile numbers)
681 (unless (null-list? (cdr numbers))
682 (display-profile-content-diff profile (car numbers) (cadr numbers))
683 (diff-profiles profile (cdr numbers))))
684 (cond ((not (file-exists? profile)) ; XXX: race condition
685 (raise (condition (&profile-not-found-error
686 (profile profile)))))
687 ((string-null? pattern)
688 (list-generation display-profile-content
689 (car (profile-generations profile)))
690 (diff-profiles profile (profile-generations profile)))
691 ((matching-generations pattern profile)
694 (if (null-list? numbers)
697 (list-generation display-profile-content (car numbers))
698 (diff-profiles profile numbers)))))
700 (leave (_ "invalid syntax: ~a~%")
704 (('list-installed regexp)
705 (let* ((regexp (and regexp (make-regexp* regexp)))
706 (manifest (profile-manifest profile))
707 (installed (manifest-entries manifest)))
709 (for-each (match-lambda
710 (($ <manifest-entry> name version output path _)
711 (when (or (not regexp)
712 (regexp-exec regexp name))
713 (format #t "~a\t~a\t~a\t~a~%"
714 name (or version "?") output path))))
716 ;; Show most recently installed packages last.
717 (reverse installed)))
720 (('list-available regexp)
721 (let* ((regexp (and regexp (make-regexp* regexp)))
722 (available (fold-packages
724 (let ((n (package-name p)))
725 (if (supported-package? p)
727 (if (regexp-exec regexp n)
734 (for-each (lambda (p)
735 (format #t "~a\t~a\t~a\t~a~%"
738 (string-join (package-outputs p) ",")
739 (location->string (package-location p))))
742 (string<? (package-name p1)
743 (package-name p2))))))
747 (let* ((patterns (filter-map (match-lambda
748 (('query 'search rx) rx)
751 (regexps (map (cut make-regexp* <> regexp/icase) patterns)))
753 (for-each (cute package->recutils <> (current-output-port))
754 (find-packages-by-description regexps)))
757 (('show requested-name)
758 (let-values (((name version)
759 (package-name->name+version requested-name)))
761 (for-each (cute package->recutils <> (current-output-port))
762 (find-packages-by-name name version)))
765 (('search-paths kind)
766 (let* ((manifests (map profile-manifest profiles))
767 (entries (append-map manifest-entries manifests))
768 (profiles (map user-friendly-profile profiles))
769 (settings (search-path-environment-variables entries profiles
772 (format #t "~{~a~%~}" settings)
778 (define* (roll-back-action store profile arg opts
780 "Roll back PROFILE to its previous generation."
782 (roll-back* store profile)))
784 (define* (switch-generation-action store profile spec opts
786 "Switch PROFILE to the generation specified by SPEC."
788 (let ((number (relative-generation-spec->number profile spec)))
790 (switch-to-generation* profile number)
791 (leave (_ "cannot switch to generation '~a'~%") spec)))))
793 (define* (delete-generations-action store profile pattern opts
795 "Delete PROFILE's generations that match PATTERN."
797 (delete-matching-generations store profile pattern)))
799 (define* (manifest-action store profile file opts
801 "Change PROFILE to contain the packages specified in FILE."
802 (let* ((user-module (make-user-module '((guix profiles) (gnu))))
803 (manifest (load* file user-module))
804 (bootstrap? (assoc-ref opts 'bootstrap?))
805 (substitutes? (assoc-ref opts 'substitutes?)))
807 (format #t (_ "would install new manifest from '~a' with ~d entries~%")
808 file (length (manifest-entries manifest)))
809 (format #t (_ "installing new manifest from '~a' with ~d entries~%")
810 file (length (manifest-entries manifest))))
811 (build-and-use-profile store profile manifest
812 #:bootstrap? bootstrap?
813 #:use-substitutes? substitutes?
814 #:dry-run? dry-run?)))
817 ;; List of actions that may be processed. The car of each pair is the
818 ;; action's symbol in the option list; the cdr is the action's procedure.
819 `((roll-back? . ,roll-back-action)
820 (switch-generation . ,switch-generation-action)
821 (delete-generations . ,delete-generations-action)
822 (manifest . ,manifest-action)))
824 (define (process-actions store opts)
825 "Process any install/remove/upgrade action from OPTS."
827 (define dry-run? (assoc-ref opts 'dry-run?))
828 (define bootstrap? (assoc-ref opts 'bootstrap?))
829 (define substitutes? (assoc-ref opts 'substitutes?))
830 (define profile (or (assoc-ref opts 'profile) %current-profile))
831 (define transform (options->transformation opts))
833 (define (transform-entry entry)
834 (let ((item (transform store (manifest-entry-item entry))))
838 (version (if (package? item)
839 (package-version item)
840 (manifest-entry-version entry))))))
842 ;; First, process roll-backs, generation removals, etc.
843 (for-each (match-lambda
845 (and=> (assoc-ref %actions key)
847 (proc store profile arg opts
848 #:dry-run? dry-run?)))))
851 ;; Then, process normal package installation/removal/upgrade.
852 (let* ((manifest (profile-manifest profile))
853 (step1 (options->installable opts manifest
854 (manifest-transaction)))
855 (step2 (options->removable opts manifest step1))
856 (step3 (manifest-transaction
858 (install (map transform-entry
859 (manifest-transaction-install step2)))))
860 (new (manifest-perform-transaction manifest step3)))
862 (unless (manifest-transaction-null? step3)
863 (show-manifest-transaction store manifest step3
865 (build-and-use-profile store profile new
866 #:bootstrap? bootstrap?
867 #:use-substitutes? substitutes?
868 #:dry-run? dry-run?))))
875 (define (guix-package . args)
876 (define (handle-argument arg result arg-handler)
877 ;; Process non-option argument ARG by calling back ARG-HANDLER.
879 (arg-handler arg result)
880 (leave (_ "~A: extraneous argument~%") arg)))
882 (let ((opts (parse-command-line args %options (list %default-options #f)
883 #:argument-handler handle-argument)))
885 (or (process-query opts)
886 (parameterize ((%store (open-connection))
887 (%graft? (assoc-ref opts 'graft?)))
888 (set-build-options-from-command-line (%store) opts)
890 (parameterize ((%guile-for-build
893 (if (assoc-ref opts 'bootstrap?)
895 (canonical-package guile-2.0)))))
896 (process-actions (%store) opts)))))))