summaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
Diffstat (limited to 'guix')
-rw-r--r--guix/gexp.scm106
-rw-r--r--guix/scripts.scm20
-rw-r--r--guix/scripts/environment.scm40
-rw-r--r--guix/scripts/lint.scm5
-rw-r--r--guix/scripts/system.scm30
-rw-r--r--guix/utils.scm19
6 files changed, 197 insertions, 23 deletions
diff --git a/guix/gexp.scm b/guix/gexp.scm
index de49fef088..27bccc6206 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -43,10 +43,30 @@
plain-file-name
plain-file-content
+ computed-file
+ computed-file?
+ computed-file-name
+ computed-file-gexp
+ computed-file-modules
+ computed-file-options
+
+ program-file
+ program-file?
+ program-file-name
+ program-file-gexp
+ program-file-modules
+ program-file-guile
+
+ scheme-file
+ scheme-file?
+ scheme-file-name
+ scheme-file-gexp
+
gexp->derivation
gexp->file
gexp->script
text-file*
+ mixed-text-file
imported-files
imported-modules
compiled-modules
@@ -214,6 +234,77 @@ This is the declarative counterpart of 'text-file'."
(($ <plain-file> name content references)
(text-file name content references))))
+(define-record-type <computed-file>
+ (%computed-file name gexp modules options)
+ computed-file?
+ (name computed-file-name) ;string
+ (gexp computed-file-gexp) ;gexp
+ (modules computed-file-modules) ;list of module names
+ (options computed-file-options)) ;list of arguments
+
+(define* (computed-file name gexp
+ #:key (modules '()) (options '(#:local-build? #t)))
+ "Return an object representing the store item NAME, a file or directory
+computed by GEXP. MODULES specifies the set of modules visible in the
+execution context of GEXP. OPTIONS is a list of additional arguments to pass
+to 'gexp->derivation'.
+
+This is the declarative counterpart of 'gexp->derivation'."
+ (%computed-file name gexp modules options))
+
+(define-gexp-compiler (computed-file-compiler (file computed-file?)
+ system target)
+ ;; Compile FILE by returning a derivation whose build expression is its
+ ;; gexp.
+ (match file
+ (($ <computed-file> name gexp modules options)
+ (apply gexp->derivation name gexp #:modules modules options))))
+
+(define-record-type <program-file>
+ (%program-file name gexp modules guile)
+ program-file?
+ (name program-file-name) ;string
+ (gexp program-file-gexp) ;gexp
+ (modules program-file-modules) ;list of module names
+ (guile program-file-guile)) ;package
+
+(define* (program-file name gexp
+ #:key (modules '()) (guile #f))
+ "Return an object representing the executable store item NAME that runs
+GEXP. GUILE is the Guile package used to execute that script, and MODULES is
+the list of modules visible to that script.
+
+This is the declarative counterpart of 'gexp->script'."
+ (%program-file name gexp modules guile))
+
+(define-gexp-compiler (program-file-compiler (file program-file?)
+ system target)
+ ;; Compile FILE by returning a derivation that builds the script.
+ (match file
+ (($ <program-file> name gexp modules guile)
+ (gexp->script name gexp
+ #:modules modules
+ #:guile (or guile (default-guile))))))
+
+(define-record-type <scheme-file>
+ (%scheme-file name gexp)
+ scheme-file?
+ (name scheme-file-name) ;string
+ (gexp scheme-file-gexp)) ;gexp
+
+(define* (scheme-file name gexp)
+ "Return an object representing the Scheme file NAME that contains GEXP.
+
+This is the declarative counterpart of 'gexp->file'."
+ (%scheme-file name gexp))
+
+(define-gexp-compiler (scheme-file-compiler (file scheme-file?)
+ system target)
+ ;; Compile FILE by returning a derivation that builds the file.
+ (match file
+ (($ <scheme-file> name gexp)
+ (gexp->file name gexp))))
+
;;;
;;; Inputs & outputs.
@@ -903,6 +994,21 @@ resulting store file holds references to all these."
(gexp->derivation name builder))
+(define* (mixed-text-file name #:rest text)
+ "Return an object representing store file NAME containing TEXT. TEXT is a
+sequence of strings and file-like objects, as in:
+
+ (mixed-text-file \"profile\"
+ \"export PATH=\" coreutils \"/bin:\" grep \"/bin\")
+
+This is the declarative counterpart of 'text-file*'."
+ (define build
+ (gexp (call-with-output-file (ungexp output "out")
+ (lambda (port)
+ (display (string-append (ungexp-splicing text)) port)))))
+
+ (computed-file name build))
+
;;;
;;; Syntactic sugar.
diff --git a/guix/scripts.scm b/guix/scripts.scm
index e34d38904c..d84375f570 100644
--- a/guix/scripts.scm
+++ b/guix/scripts.scm
@@ -31,7 +31,8 @@
#:export (args-fold*
parse-command-line
maybe-build
- build-package))
+ build-package
+ build-package-source))
;;; Commentary:
;;;
@@ -115,4 +116,21 @@ Show what and how will/would be built."
#:dry-run? dry-run?)
(return (show-derivation-outputs derivation))))))
+(define* (build-package-source package
+ #:key dry-run? (use-substitutes? #t)
+ #:allow-other-keys
+ #:rest build-options)
+ "Build PACKAGE source using BUILD-OPTIONS."
+ (mbegin %store-monad
+ (apply set-build-options*
+ #:use-substitutes? use-substitutes?
+ (strip-keyword-arguments '(#:dry-run?) build-options))
+ (mlet %store-monad ((derivation (origin->derivation
+ (package-source package))))
+ (mbegin %store-monad
+ (maybe-build (list derivation)
+ #:use-substitutes? use-substitutes?
+ #:dry-run? dry-run?)
+ (return (show-derivation-outputs derivation))))))
+
;;; scripts.scm ends here
diff --git a/guix/scripts/environment.scm b/guix/scripts/environment.scm
index 7aa52e8a8a..2408420e18 100644
--- a/guix/scripts/environment.scm
+++ b/guix/scripts/environment.scm
@@ -57,6 +57,9 @@ OUTPUT) tuples."
(define %precious-variables
'("HOME" "USER" "LOGNAME" "DISPLAY" "TERM" "TZ" "PAGER"))
+(define %default-shell
+ (or (getenv "SHELL") "/bin/sh"))
+
(define (purify-environment)
"Unset almost all environment variables. A small number of variables such
as 'HOME' and 'USER' are left untouched."
@@ -103,9 +106,9 @@ existing environment variables with additional search paths."
,@(package-transitive-propagated-inputs package)))
(define (show-help)
- (display (_ "Usage: guix environment [OPTION]... PACKAGE...
-Build an environment that includes the dependencies of PACKAGE and execute a
-shell command in that environment.\n"))
+ (display (_ "Usage: guix environment [OPTION]... PACKAGE... [-- COMMAND...]
+Build an environment that includes the dependencies of PACKAGE and execute
+COMMAND or an interactive shell in that environment.\n"))
(display (_ "
-e, --expression=EXPR create environment for the package that EXPR
evaluates to"))
@@ -113,8 +116,6 @@ shell command in that environment.\n"))
-l, --load=FILE create environment for the package that the code within
FILE evaluates to"))
(display (_ "
- -E, --exec=COMMAND execute COMMAND in new environment"))
- (display (_ "
--ad-hoc include all specified packages in the environment instead
of only their inputs"))
(display (_ "
@@ -135,7 +136,7 @@ shell command in that environment.\n"))
(define %default-options
;; Default to opening a new shell.
- `((exec . ,(or (getenv "SHELL") "/bin/sh"))
+ `((exec . (,%default-shell))
(system . ,(%current-system))
(substitutes? . #t)
(max-silent-time . 3600)
@@ -153,9 +154,9 @@ shell command in that environment.\n"))
(option '("pure") #f #f
(lambda (opt name arg result)
(alist-cons 'pure #t result)))
- (option '(#\E "exec") #t #f
+ (option '(#\E "exec") #t #f ; deprecated
(lambda (opt name arg result)
- (alist-cons 'exec arg result)))
+ (alist-cons 'exec (list %default-shell "-c" arg) result)))
(option '("search-paths") #f #f
(lambda (opt name arg result)
(alist-cons 'search-paths #t result)))
@@ -230,14 +231,24 @@ OUTPUT) tuples, using the build options in OPTS."
(built-derivations derivations)
(return derivations))))))))
-;; Entry point.
-(define (guix-environment . args)
+(define (parse-args args)
+ "Parse the list of command line arguments ARGS."
(define (handle-argument arg result)
(alist-cons 'package arg result))
+ ;; The '--' token is used to separate the command to run from the rest of
+ ;; the operands.
+ (let-values (((args command) (split args "--")))
+ (let ((opts (parse-command-line args %options (list %default-options)
+ #:argument-handler handle-argument)))
+ (if (null? command)
+ opts
+ (alist-cons 'exec command opts)))))
+
+;; Entry point.
+(define (guix-environment . args)
(with-error-handling
- (let* ((opts (parse-command-line args %options (list %default-options)
- #:argument-handler handle-argument))
+ (let* ((opts (parse-args args))
(pure? (assoc-ref opts 'pure))
(ad-hoc? (assoc-ref opts 'ad-hoc?))
(command (assoc-ref opts 'exec))
@@ -282,4 +293,7 @@ OUTPUT) tuples, using the build options in OPTS."
(return #t))
(else
(create-environment inputs paths pure?)
- (return (exit (status:exit-val (system command)))))))))))))
+ (return
+ (exit
+ (status:exit-val
+ (apply system* command)))))))))))))
diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm
index 3b4ff722e9..b1707ade44 100644
--- a/guix/scripts/lint.scm
+++ b/guix/scripts/lint.scm
@@ -62,6 +62,7 @@
check-source-file-name
check-license
check-formatting
+ run-checkers
%checkers
lint-checker
@@ -709,8 +710,8 @@ or a list thereof")
(description "Look for formatting issues in the source")
(check check-formatting))))
-(define (run-checkers package checkers)
- ;; Run the given CHECKERS on PACKAGE.
+(define* (run-checkers package #:optional (checkers %checkers))
+ "Run the given CHECKERS on PACKAGE."
(let ((tty? (isatty? (current-error-port)))
(name (package-full-name package)))
(for-each (lambda (checker)
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 5e2d226dfe..71b92dacc7 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -300,7 +300,7 @@ it atomically, and then run OS's activation script."
(system-disk-image os #:disk-image-size image-size))))
(define* (perform-action action os
- #:key grub? dry-run?
+ #:key grub? dry-run? derivations-only?
use-substitutes? device target
image-size full-boot?
(mappings '()))
@@ -308,7 +308,13 @@ it atomically, and then run OS's activation script."
the target devices for GRUB; TARGET is the target root directory; IMAGE-SIZE
is the size of the image to be built, for the 'vm-image' and 'disk-image'
actions. FULL-BOOT? is used for the 'vm' action; it determines whether to
-boot directly to the kernel or to the bootloader."
+boot directly to the kernel or to the bootloader.
+
+When DERIVATIONS-ONLY? is true, print the derivation file name(s) without
+building anything."
+ (define println
+ (cut format #t "~a~%" <>))
+
(mlet* %store-monad
((sys (system-derivation-for-action os action
#:image-size image-size
@@ -322,14 +328,17 @@ boot directly to the kernel or to the bootloader."
(drvs -> (if (and grub? (memq action '(init reconfigure)))
(list sys grub grub.cfg)
(list sys)))
- (% (maybe-build drvs #:dry-run? dry-run?
- #:use-substitutes? use-substitutes?)))
+ (% (if derivations-only?
+ (return (for-each (compose println derivation-file-name)
+ drvs))
+ (maybe-build drvs #:dry-run? dry-run?
+ #:use-substitutes? use-substitutes?))))
- (if dry-run?
+ (if (or dry-run? derivations-only?)
(return #f)
(begin
- (for-each (cut format #t "~a~%" <>)
- (map derivation->output-path drvs))
+ (for-each (compose println derivation->output-path)
+ drvs)
;; Make sure GRUB is accessible.
(when grub?
@@ -383,6 +392,8 @@ Build the operating system declared in FILE according to ACTION.\n"))
(show-build-options-help)
(display (_ "
+ -d, --derivation return the derivation of the given system"))
+ (display (_ "
--on-error=STRATEGY
apply STRATEGY when an error occurs while reading FILE"))
(display (_ "
@@ -425,6 +436,9 @@ Build the operating system declared in FILE according to ACTION.\n"))
(option '(#\V "version") #f #f
(lambda args
(show-version-and-exit "guix system")))
+ (option '(#\d "derivation") #f #f
+ (lambda (opt name arg result)
+ (alist-cons 'derivations-only? #t result)))
(option '("on-error") #t #f
(lambda (opt name arg result)
(alist-cons 'on-error (string->symbol arg)
@@ -549,6 +563,8 @@ Build the operating system declared in FILE according to ACTION.\n"))
(set-guile-for-build (default-guile))
(perform-action action os
#:dry-run? dry?
+ #:derivations-only? (assoc-ref opts
+ 'derivations-only?)
#:use-substitutes? (assoc-ref opts 'substitutes?)
#:image-size (assoc-ref opts 'image-size)
#:full-boot? (assoc-ref opts 'full-boot?)
diff --git a/guix/utils.scm b/guix/utils.scm
index 1d4b2ff9b0..0802a1b67a 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2013, 2014, 2015 Mark H Weaver <mhw@netris.org>
;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net>
+;;; Copyright © 2015 David Thompson <davet@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -79,6 +80,7 @@
fold2
fold-tree
fold-tree-leaves
+ split
filtered-port
compressed-port
@@ -684,6 +686,23 @@ are connected to NODE in the tree, or '() or #f if NODE is a leaf node."
(else result)))
init children roots))
+(define (split lst e)
+ "Return two values, a list containing the elements of the list LST that
+appear before the first occurence of the object E and a list containing the
+elements after E."
+ (define (same? x)
+ (equal? e x))
+
+ (let loop ((rest lst)
+ (acc '()))
+ (match rest
+ (()
+ (values lst '()))
+ (((? same?) . tail)
+ (values (reverse acc) tail))
+ ((head . tail)
+ (loop tail (cons head acc))))))
+
;;;
;;; Source location.