Merge branch 'master' into core-updates
This commit is contained in:
commit
a13c1bf4ca
@ -73,6 +73,9 @@
|
||||
(eval . (put 'run-with-state 'scheme-indent-function 1))
|
||||
(eval . (put 'wrap-program 'scheme-indent-function 1))
|
||||
(eval . (put 'with-imported-modules 'scheme-indent-function 1))
|
||||
(eval . (put 'with-extensions 'scheme-indent-function 1))
|
||||
|
||||
(eval . (put 'with-database 'scheme-indent-function 2))
|
||||
|
||||
(eval . (put 'call-with-container 'scheme-indent-function 1))
|
||||
(eval . (put 'container-excursion 'scheme-indent-function 1))
|
||||
|
19
Makefile.am
19
Makefile.am
@ -257,6 +257,17 @@ MODULES += \
|
||||
|
||||
endif BUILD_DAEMON_OFFLOAD
|
||||
|
||||
# Scheme implementation of the build daemon and related functionality.
|
||||
STORE_MODULES = \
|
||||
guix/store/database.scm \
|
||||
guix/store/deduplication.scm
|
||||
|
||||
if HAVE_GUILE_SQLITE3
|
||||
MODULES += $(STORE_MODULES)
|
||||
else
|
||||
MODULES_NOT_COMPILED += $(STORE_MODULES)
|
||||
endif !HAVE_GUILE_SQLITE3
|
||||
|
||||
# Internal modules with test suite support.
|
||||
dist_noinst_DATA = guix/tests.scm guix/tests/http.scm
|
||||
|
||||
@ -379,6 +390,14 @@ SCM_TESTS += \
|
||||
|
||||
endif
|
||||
|
||||
if HAVE_GUILE_SQLITE3
|
||||
|
||||
SCM_TESTS += \
|
||||
tests/store-database.scm \
|
||||
tests/store-deduplication.scm
|
||||
|
||||
endif
|
||||
|
||||
SH_TESTS = \
|
||||
tests/guix-build.sh \
|
||||
tests/guix-download.sh \
|
||||
|
@ -124,6 +124,11 @@ dnl Guile-JSON is used in various places.
|
||||
GUILE_MODULE_AVAILABLE([have_guile_json], [(json)])
|
||||
AM_CONDITIONAL([HAVE_GUILE_JSON], [test "x$have_guile_json" = "xyes"])
|
||||
|
||||
dnl Guile-Sqlite3 is used by the (guix store ...) modules.
|
||||
GUIX_CHECK_GUILE_SQLITE3
|
||||
AM_CONDITIONAL([HAVE_GUILE_SQLITE3],
|
||||
[test "x$guix_cv_have_recent_guile_sqlite3" = "xyes"])
|
||||
|
||||
dnl Make sure we have a full-fledged Guile.
|
||||
GUIX_ASSERT_GUILE_FEATURES([regex posix socket net-db threads])
|
||||
|
||||
|
@ -47,7 +47,8 @@ Copyright @copyright{} 2017, 2018 Arun Isaac@*
|
||||
Copyright @copyright{} 2017 nee@*
|
||||
Copyright @copyright{} 2018 Rutger Helling@*
|
||||
Copyright @copyright{} 2018 Oleg Pykhalov@*
|
||||
Copyright @copyright{} 2018 Mike Gerwitz
|
||||
Copyright @copyright{} 2018 Mike Gerwitz@*
|
||||
Copyright @copyright{} 2018 Pierre-Antoine Rouby
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
@ -5063,6 +5064,23 @@ headers, which comes in handy in this case:
|
||||
@dots{})))
|
||||
@end example
|
||||
|
||||
@cindex extensions, for gexps
|
||||
@findex with-extensions
|
||||
In the same vein, sometimes you want to import not just pure-Scheme
|
||||
modules, but also ``extensions'' such as Guile bindings to C libraries
|
||||
or other ``full-blown'' packages. Say you need the @code{guile-json}
|
||||
package available on the build side, here's how you would do it:
|
||||
|
||||
@example
|
||||
(use-modules (gnu packages guile)) ;for 'guile-json'
|
||||
|
||||
(with-extensions (list guile-json)
|
||||
(gexp->derivation "something-with-json"
|
||||
#~(begin
|
||||
(use-modules (json))
|
||||
@dots{})))
|
||||
@end example
|
||||
|
||||
The syntactic form to construct gexps is summarized below.
|
||||
|
||||
@deffn {Scheme Syntax} #~@var{exp}
|
||||
@ -5146,6 +5164,18 @@ directly defined in @var{body}@dots{}, but not on those defined, say, in
|
||||
procedures called from @var{body}@dots{}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} with-extensions @var{extensions} @var{body}@dots{}
|
||||
Mark the gexps defined in @var{body}@dots{} as requiring
|
||||
@var{extensions} in their build and execution environment.
|
||||
@var{extensions} is typically a list of package objects such as those
|
||||
defined in the @code{(gnu packages guile)} module.
|
||||
|
||||
Concretely, the packages listed in @var{extensions} are added to the
|
||||
load path while compiling imported modules in @var{body}@dots{}; they
|
||||
are also added to the load path of the gexp returned by
|
||||
@var{body}@dots{}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} gexp? @var{obj}
|
||||
Return @code{#t} if @var{obj} is a G-expression.
|
||||
@end deffn
|
||||
@ -5160,6 +5190,7 @@ information about monads.)
|
||||
[#:hash #f] [#:hash-algo #f] @
|
||||
[#:recursive? #f] [#:env-vars '()] [#:modules '()] @
|
||||
[#:module-path @var{%load-path}] @
|
||||
[#:effective-version "2.2"] @
|
||||
[#:references-graphs #f] [#:allowed-references #f] @
|
||||
[#:disallowed-references #f] @
|
||||
[#:leaked-env-vars #f] @
|
||||
@ -5180,6 +5211,9 @@ make @var{modules} available in the evaluation context of @var{exp};
|
||||
the load path during the execution of @var{exp}---e.g., @code{((guix
|
||||
build utils) (guix build gnu-build-system))}.
|
||||
|
||||
@var{effective-version} determines the string to use when adding extensions of
|
||||
@var{exp} (see @code{with-extensions}) to the search path---e.g., @code{"2.2"}.
|
||||
|
||||
@var{graft?} determines whether packages referred to by @var{exp} should be grafted when
|
||||
applicable.
|
||||
|
||||
@ -16159,6 +16193,64 @@ A simple setup for cat-avatar-generator can look like this:
|
||||
%base-services))
|
||||
@end example
|
||||
|
||||
@subsubheading Hpcguix-web
|
||||
|
||||
@cindex hpcguix-web
|
||||
The @uref{hpcguix-web, https://github.com/UMCUGenetics/hpcguix-web/}
|
||||
program is a customizable web interface to browse Guix packages,
|
||||
initially designed for users of high-performance computing (HPC)
|
||||
clusters.
|
||||
|
||||
@defvr {Scheme Variable} hpcguix-web-service-type
|
||||
The service type for @code{hpcguix-web}.
|
||||
@end defvr
|
||||
|
||||
@deftp {Data Type} hpcguix-web-configuration
|
||||
Data type for the hpcguix-web service configuration.
|
||||
|
||||
@table @asis
|
||||
@item @code{specs}
|
||||
A gexp (@pxref{G-Expressions}) specifying the hpcguix-web service
|
||||
configuration. The main items available in this spec are:
|
||||
|
||||
@table @asis
|
||||
@item @code{title-prefix} (default: @code{"hpcguix | "})
|
||||
The page title prefix.
|
||||
|
||||
@item @code{guix-command} (default: @code{"guix"})
|
||||
The @command{guix} command.
|
||||
|
||||
@item @code{package-filter-proc} (default: @code{(const #t)})
|
||||
A procedure specifying how to filter packages that are displayed.
|
||||
|
||||
@item @code{package-page-extension-proc} (default: @code{(const '())})
|
||||
Extension package for @code{hpcguix-web}.
|
||||
|
||||
@item @code{menu} (default: @code{'()})
|
||||
Additional entry in page @code{menu}.
|
||||
@end table
|
||||
|
||||
See the hpcguix-web repository for a
|
||||
@uref{https://github.com/UMCUGenetics/hpcguix-web/blob/master/hpcweb-configuration.scm,
|
||||
complete example}.
|
||||
|
||||
@item @code{package} (default: @code{hpcguix-web})
|
||||
The hpcguix-web package to use.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
A typical hpcguix-web service declaration looks like this:
|
||||
|
||||
@example
|
||||
(service hpcguix-web-service-type
|
||||
(hpcguix-web-configuration
|
||||
(specs
|
||||
#~(define site-config
|
||||
(hpcweb-configuration
|
||||
(title-prefix "Guix-HPC - ")
|
||||
(menu '(("/about" "ABOUT"))))))))
|
||||
@end example
|
||||
|
||||
@node Certificate Services
|
||||
@subsubsection Certificate Services
|
||||
|
||||
|
@ -121,25 +121,14 @@ (define (bootloader-theme config)
|
||||
|
||||
(define* (svg->png svg #:key width height)
|
||||
"Build a PNG of HEIGHT x WIDTH from SVG."
|
||||
;; Note: Guile-RSVG & co. are now built for Guile 2.2, so we use 2.2 here.
|
||||
;; TODO: Remove #:guile-for-build when 2.2 has become the default.
|
||||
(mlet %store-monad ((guile (package->derivation guile-2.2 #:graft? #f)))
|
||||
(gexp->derivation "grub-image.png"
|
||||
(with-imported-modules '((gnu build svg))
|
||||
(gexp->derivation "grub-image.png"
|
||||
(with-imported-modules '((gnu build svg))
|
||||
(with-extensions (list guile-rsvg guile-cairo)
|
||||
#~(begin
|
||||
;; We need these two libraries.
|
||||
(add-to-load-path (string-append #+guile-rsvg
|
||||
"/share/guile/site/"
|
||||
(effective-version)))
|
||||
(add-to-load-path (string-append #+guile-cairo
|
||||
"/share/guile/site/"
|
||||
(effective-version)))
|
||||
|
||||
(use-modules (gnu build svg))
|
||||
(svg->png #+svg #$output
|
||||
#:width #$width
|
||||
#:height #$height)))
|
||||
#:guile-for-build guile)))
|
||||
#:height #$height))))))
|
||||
|
||||
(define* (grub-background-image config #:key (width 1024) (height 768))
|
||||
"Return the GRUB background image defined in CONFIG with a ratio of
|
||||
|
@ -499,8 +499,8 @@ (define (resolve find-partition spec fmt)
|
||||
|
||||
(match spec
|
||||
((? string?)
|
||||
;; Nothing to do.
|
||||
spec)
|
||||
;; Nothing to do, but wait until SPEC shows up.
|
||||
(resolve identity spec identity))
|
||||
((? file-system-label?)
|
||||
;; Resolve the label.
|
||||
(resolve find-partition-by-label
|
||||
|
@ -26,6 +26,7 @@ (define-module (gnu build marionette)
|
||||
make-marionette
|
||||
marionette-eval
|
||||
wait-for-file
|
||||
wait-for-tcp-port
|
||||
marionette-control
|
||||
marionette-screen-text
|
||||
wait-for-screen-text
|
||||
@ -187,6 +188,32 @@ (define* (wait-for-file file marionette
|
||||
('failure
|
||||
(error "file didn't show up" file))))
|
||||
|
||||
(define* (wait-for-tcp-port port marionette
|
||||
#:key (timeout 20))
|
||||
"Wait for up to TIMEOUT seconds for PORT to accept connections in
|
||||
MARIONETTE. Raise an error on failure."
|
||||
;; Note: The 'connect' loop has to run within the guest because, when we
|
||||
;; forward ports to the host, connecting to the host never raises
|
||||
;; ECONNREFUSED.
|
||||
(match (marionette-eval
|
||||
`(begin
|
||||
(let ((sock (socket PF_INET SOCK_STREAM 0)))
|
||||
(let loop ((i 0))
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
(connect sock AF_INET INADDR_LOOPBACK ,port)
|
||||
'success)
|
||||
(lambda args
|
||||
(if (< i ,timeout)
|
||||
(begin
|
||||
(sleep 1)
|
||||
(loop (+ 1 i)))
|
||||
'failure))))))
|
||||
marionette)
|
||||
('success #t)
|
||||
('failure
|
||||
(error "nobody's listening on port" port))))
|
||||
|
||||
(define (marionette-control command marionette)
|
||||
"Run COMMAND in the QEMU monitor of MARIONETTE. COMMAND is a string such as
|
||||
\"sendkey ctrl-alt-f1\" or \"screendump foo.ppm\" (info \"(qemu-doc)
|
||||
|
@ -1,5 +1,5 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
@ -18,16 +18,11 @@
|
||||
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define-module (gnu build svg)
|
||||
#:use-module (rsvg)
|
||||
#:use-module (cairo)
|
||||
#:use-module (srfi srfi-11)
|
||||
#:export (svg->png))
|
||||
|
||||
;; We need Guile-RSVG and Guile-Cairo. Load them lazily, at run time, to
|
||||
;; allow compilation to proceed. See also <http://bugs.gnu.org/12202>.
|
||||
(module-autoload! (current-module)
|
||||
'(rsvg) '(rsvg-handle-new-from-file))
|
||||
(module-autoload! (current-module)
|
||||
'(cairo) '(cairo-image-surface-create))
|
||||
|
||||
(define* (downscaled-surface surface
|
||||
#:key
|
||||
source-width source-height
|
||||
|
@ -1092,6 +1092,7 @@ dist_patch_DATA = \
|
||||
%D%/packages/patches/scotch-build-parallelism.patch \
|
||||
%D%/packages/patches/scotch-graph-diam-64.patch \
|
||||
%D%/packages/patches/scotch-graph-induce-type-64.patch \
|
||||
%D%/packages/patches/sddm-fix-build-with-qt-5.11-1024.patch \
|
||||
%D%/packages/patches/sdl-libx11-1.6.patch \
|
||||
%D%/packages/patches/seq24-rename-mutex.patch \
|
||||
%D%/packages/patches/sharutils-CVE-2018-1000097.patch \
|
||||
|
@ -87,6 +87,8 @@ (define-public bear
|
||||
(base32
|
||||
"1m0w0wqnz983l7fpp5p9pdsqr7n3ybrzp8ywjcvn0rihsrzj65j6"))))
|
||||
(build-system cmake-build-system)
|
||||
(inputs
|
||||
`(("python" ,python-wrapper)))
|
||||
(home-page "https://github.com/rizsotto/Bear")
|
||||
(synopsis "Tool for generating a compilation database")
|
||||
(description "A JSON compilation database is used in the Clang project to
|
||||
|
@ -6,6 +6,7 @@
|
||||
;;; Copyright © 2017 Sou Bunnbu <iyzsong@gmail.com>
|
||||
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
|
||||
;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
|
||||
;;; Copyright © 2018 Stefan Stefanović <stefanx2ovic@gmail.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -143,7 +144,8 @@ (define-public sddm
|
||||
"sddm-" version ".tar.xz"))
|
||||
(sha256
|
||||
(base32
|
||||
"0ch6rdppgy2vbzw0c2x9a4c6ry46vx7p6b76d8xbh2nvxh23xv0k"))))
|
||||
"0ch6rdppgy2vbzw0c2x9a4c6ry46vx7p6b76d8xbh2nvxh23xv0k"))
|
||||
(patches (search-patches "sddm-fix-build-with-qt-5.11-1024.patch"))))
|
||||
(build-system cmake-build-system)
|
||||
(native-inputs
|
||||
`(("extra-cmake-modules" ,extra-cmake-modules)
|
||||
|
@ -751,77 +751,91 @@ (define-public flycheck
|
||||
;;;
|
||||
|
||||
(define-public emacs-w3m
|
||||
(package
|
||||
(name "emacs-w3m")
|
||||
(version "1.4.538+0.20141022")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "mirror://debian/pool/main/w/w3m-el/w3m-el_"
|
||||
version ".orig.tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"0zfxmq86pwk64yv0426gnjrvhjrgrjqn08sdcdhmmjmfpmqvm79y"))))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs `(("autoconf" ,autoconf)
|
||||
("emacs" ,emacs-minimal)))
|
||||
(inputs `(("w3m" ,w3m)
|
||||
("imagemagick" ,imagemagick)))
|
||||
(arguments
|
||||
`(#:modules ((guix build gnu-build-system)
|
||||
(guix build utils)
|
||||
(guix build emacs-utils))
|
||||
#:imported-modules (,@%gnu-build-system-modules
|
||||
(guix build emacs-utils))
|
||||
#:configure-flags
|
||||
(let ((out (assoc-ref %outputs "out")))
|
||||
(list (string-append "--with-lispdir="
|
||||
out "/share/emacs/site-lisp")
|
||||
(string-append "--with-icondir="
|
||||
out "/share/images/emacs-w3m")
|
||||
;; Leave .el files uncompressed, otherwise GC can't
|
||||
;; identify run-time dependencies. See
|
||||
;; <http://lists.gnu.org/archive/html/guix-devel/2015-12/msg00208.html>
|
||||
"--without-compress-install"))
|
||||
#:tests? #f ; no check target
|
||||
#:phases
|
||||
(modify-phases %standard-phases
|
||||
(add-after 'unpack 'autoconf
|
||||
(lambda _
|
||||
(zero? (system* "autoconf"))))
|
||||
(add-before 'build 'patch-exec-paths
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let ((out (assoc-ref outputs "out"))
|
||||
(w3m (assoc-ref inputs "w3m"))
|
||||
(imagemagick (assoc-ref inputs "imagemagick"))
|
||||
(coreutils (assoc-ref inputs "coreutils")))
|
||||
(emacs-substitute-variables "w3m.el"
|
||||
("w3m-command" (string-append w3m "/bin/w3m"))
|
||||
("w3m-touch-command"
|
||||
(string-append coreutils "/bin/touch"))
|
||||
("w3m-image-viewer"
|
||||
(string-append imagemagick "/bin/display"))
|
||||
("w3m-icon-directory"
|
||||
(string-append out "/share/images/emacs-w3m")))
|
||||
(emacs-substitute-variables "w3m-image.el"
|
||||
("w3m-imagick-convert-program"
|
||||
(string-append imagemagick "/bin/convert"))
|
||||
("w3m-imagick-identify-program"
|
||||
(string-append imagemagick "/bin/identify")))
|
||||
#t)))
|
||||
(replace 'install
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(and (zero? (system* "make" "install" "install-icons"))
|
||||
(with-directory-excursion
|
||||
(string-append (assoc-ref outputs "out")
|
||||
"/share/emacs/site-lisp")
|
||||
(for-each delete-file '("ChangeLog" "ChangeLog.1"))
|
||||
(symlink "w3m-load.el" "w3m-autoloads.el")
|
||||
#t)))))))
|
||||
(home-page "http://emacs-w3m.namazu.org/")
|
||||
(synopsis "Simple Web browser for Emacs based on w3m")
|
||||
(description
|
||||
"Emacs-w3m is an emacs interface for the w3m web browser.")
|
||||
(license license:gpl2+)))
|
||||
;; Emacs-w3m follows a "rolling release" model from its CVS repo. We could
|
||||
;; use CVS, sure, but instead we choose to use this Git mirror described on
|
||||
;; the home page as an "unofficial" mirror.
|
||||
(let ((commit "0dd5691f46d314a84da63f3a7277d721815811a2"))
|
||||
(package
|
||||
(name "emacs-w3m")
|
||||
(version (git-version "1.5" "0" commit))
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://github.com/ecbrown/emacs-w3m")
|
||||
(commit commit)))
|
||||
(sha256
|
||||
(base32
|
||||
"02xalyxbrkgl4n8nj7xxkmsbm6lshhwdc8bzs2l4wz3hkpgkj7x4"))))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs `(("autoconf" ,autoconf)
|
||||
("texinfo" ,texinfo)
|
||||
("emacs" ,emacs-minimal)))
|
||||
(inputs `(("w3m" ,w3m)
|
||||
("imagemagick" ,imagemagick)))
|
||||
(arguments
|
||||
`(#:modules ((guix build gnu-build-system)
|
||||
(guix build utils)
|
||||
(guix build emacs-utils))
|
||||
#:imported-modules (,@%gnu-build-system-modules
|
||||
(guix build emacs-utils))
|
||||
#:configure-flags
|
||||
(let ((out (assoc-ref %outputs "out")))
|
||||
(list (string-append "--with-lispdir="
|
||||
out "/share/emacs/site-lisp")
|
||||
(string-append "--with-icondir="
|
||||
out "/share/images/emacs-w3m")
|
||||
;; Leave .el files uncompressed, otherwise GC can't
|
||||
;; identify run-time dependencies. See
|
||||
;; <http://lists.gnu.org/archive/html/guix-devel/2015-12/msg00208.html>
|
||||
"--without-compress-install"))
|
||||
#:tests? #f ; no check target
|
||||
#:phases
|
||||
(modify-phases %standard-phases
|
||||
(add-after 'unpack 'autoconf
|
||||
(lambda _
|
||||
(zero? (system* "autoconf"))))
|
||||
(add-before 'configure 'support-emacs!
|
||||
(lambda _
|
||||
;; For some reason 'AC_PATH_EMACS' thinks that 'Emacs 26' is
|
||||
;; unsupported.
|
||||
(substitute* "configure"
|
||||
(("EMACS_FLAVOR=unsupported")
|
||||
"EMACS_FLAVOR=emacs"))
|
||||
#t))
|
||||
(add-before 'build 'patch-exec-paths
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let ((out (assoc-ref outputs "out"))
|
||||
(w3m (assoc-ref inputs "w3m"))
|
||||
(imagemagick (assoc-ref inputs "imagemagick"))
|
||||
(coreutils (assoc-ref inputs "coreutils")))
|
||||
(make-file-writable "w3m.el")
|
||||
(emacs-substitute-variables "w3m.el"
|
||||
("w3m-command" (string-append w3m "/bin/w3m"))
|
||||
("w3m-touch-command"
|
||||
(string-append coreutils "/bin/touch"))
|
||||
("w3m-icon-directory"
|
||||
(string-append out "/share/images/emacs-w3m")))
|
||||
(make-file-writable "w3m-image.el")
|
||||
(emacs-substitute-variables "w3m-image.el"
|
||||
("w3m-imagick-convert-program"
|
||||
(string-append imagemagick "/bin/convert"))
|
||||
("w3m-imagick-identify-program"
|
||||
(string-append imagemagick "/bin/identify")))
|
||||
#t)))
|
||||
(replace 'install
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(and (zero? (system* "make" "install" "install-icons"))
|
||||
(with-directory-excursion
|
||||
(string-append (assoc-ref outputs "out")
|
||||
"/share/emacs/site-lisp")
|
||||
(for-each delete-file '("ChangeLog" "ChangeLog.1"))
|
||||
(symlink "w3m-load.el" "w3m-autoloads.el")
|
||||
#t)))))))
|
||||
(home-page "http://emacs-w3m.namazu.org/")
|
||||
(synopsis "Simple Web browser for Emacs based on w3m")
|
||||
(description
|
||||
"Emacs-w3m is an emacs interface for the w3m web browser.")
|
||||
(license license:gpl2+))))
|
||||
|
||||
(define-public emacs-wget
|
||||
(package
|
||||
@ -10571,3 +10585,52 @@ (define-public emacs-desktop-environment
|
||||
availability of shell commands to do the hard work for us. These commands can
|
||||
be changed by customizing the appropriate variables.")
|
||||
(license license:gpl3+)))
|
||||
|
||||
(define-public emacs-org-caldav
|
||||
(package
|
||||
(name "emacs-org-caldav")
|
||||
(version "20180403")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append
|
||||
"https://github.com/dengste/org-caldav/raw/"
|
||||
"8d3492c27a09f437d2d94f2736c56d7652e87aa0"
|
||||
"/org-caldav.el"))
|
||||
(sha256
|
||||
(base32
|
||||
"1fh4gh68ddj0is99z2ccyh97v6psnyda61n2dsadzqhcxn51amlc"))))
|
||||
(build-system emacs-build-system)
|
||||
(propagated-inputs `(("emacs-org" ,emacs-org)))
|
||||
(home-page "https://github.com/dengste/org-caldav")
|
||||
(synopsis
|
||||
"Sync Org files with external calendars via the CalDAV protocol")
|
||||
(description
|
||||
"Synchronize between events in Org-mode files and a CalDAV calendar.
|
||||
This code is still alpha.")
|
||||
(license license:gpl3+)))
|
||||
|
||||
(define-public emacs-zotxt
|
||||
(package
|
||||
(name "emacs-zotxt")
|
||||
(version "20180518")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append
|
||||
"https://github.com/egh/zotxt-emacs/archive/"
|
||||
"23a4a9f74a658222027d53a9a83cd4bcc583ca8b"
|
||||
".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"1qlibaciqgsva6fc7vv9krssjq00bi880396jk7llbi3c52q9n1y"))))
|
||||
(build-system emacs-build-system)
|
||||
(propagated-inputs
|
||||
`(("emacs-deferred" ,emacs-deferred)
|
||||
("emacs-request" ,emacs-request)))
|
||||
(home-page "https://github.com/egh/zotxt-emacs")
|
||||
(synopsis "Integrate Emacs with Zotero")
|
||||
(description "This package provides two integration features between Emacs
|
||||
and the Zotero research assistant: Insertion of links to Zotero items into an
|
||||
Org-mode file, and citations of Zotero items in Pandoc Markdown files.")
|
||||
(license license:gpl3+)))
|
||||
|
@ -489,7 +489,17 @@ (define-public icecat
|
||||
(mozilla-patch "icecat-bug-1459206-pt2.patch" "9ad16112044a" "0ayya67sx7avcb8bplfdxb92l9g4mjrb1s3hby283llhqv0ikg9b")
|
||||
(mozilla-patch "icecat-bug-1459162.patch" "11d8a87fb6d6" "1rkmdk18llw0x1jakix75hlhy0hpsmlminnflagbzrzjli81gwm1")
|
||||
(mozilla-patch "icecat-bug-1451297.patch" "407b10ad1273" "16qzsfirw045xag96f1qvpdlibm8lwdj9l1mlli4n1vz0db91v9q")
|
||||
(mozilla-patch "icecat-bug-1462682.patch" "e76e2e481b17" "0hnx13msjy28n3bpa2c24kpzalam4bdk5gnp0f9k671l48rs9yb3")))
|
||||
(mozilla-patch "icecat-bug-1462682.patch" "e76e2e481b17" "0hnx13msjy28n3bpa2c24kpzalam4bdk5gnp0f9k671l48rs9yb3")
|
||||
(mozilla-patch "icecat-bug-1450688.patch" "2c75bfcd465c" "1pjinj8qypafqm2fk68s3hzcbzcijn09qzrpcxvzq6bl1yfc1xfd")
|
||||
(mozilla-patch "icecat-bug-1456975.patch" "042f80f3befd" "0av918kin4bkrq7gnjz0h9w8kkq8rk9l93250lfl5kqrinza1gsk")
|
||||
(mozilla-patch "icecat-bugs-1442722+1455071+1433642+1456604+1458320.patch"
|
||||
"bb0451c9c4a0" "1lhm1b2a7c6jwhzsg3c830hfhp17p8j9zbcmgchpb8c5jkc3vw0x")
|
||||
(mozilla-patch "icecat-bug-1465108-pt1.patch" "8189b262e3b9" "13rh86ddwmj1bhv3ibbil3sv5xbqq1c9v1czgbsna5hxxkzc1y3b")
|
||||
(mozilla-patch "icecat-bug-1465108-pt2.patch" "9f81ae3f6e1d" "05vfg8a8jrzd93n1wvncmvdmqgf9cgsl8ryxgjs3032gbbjkga7q")
|
||||
(mozilla-patch "icecat-bug-1459693.patch" "face7a3dd5d7" "0jclw30mf693w8lrmvn0iankggj21nh4j3zh51q5363rj5xncdzx")
|
||||
(mozilla-patch "icecat-bug-1464829.patch" "7afb58c046c8" "1r0569r76712x7x1sw6xr0x06ilv6iw3fncb0f8r8b9mp6wrpx34")
|
||||
(mozilla-patch "icecat-bug-1452375-pt1.patch" "f1a745f8c42d" "11q73pb7a8f09xjzil4rhg5nr49zrnz1vb0prni0kqvrnppf5s40")
|
||||
(mozilla-patch "icecat-bug-1452375-pt2.patch" "1f9a430881cc" "0f79rv7njliqxx33z07n60b50jg0a596d1km7ayz2hivbl2d0168")))
|
||||
(modules '((guix build utils)))
|
||||
(snippet
|
||||
'(begin
|
||||
|
@ -14,6 +14,7 @@
|
||||
;;; Copyright © 2017 rsiddharth <s@ricketyspace.net>
|
||||
;;; Copyright © 2017, 2018 Tobias Geerinckx-Rice <me@tobias.gr>
|
||||
;;; Copyright © 2018 Tonton <tonton@riseup.net>
|
||||
;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -1940,6 +1941,30 @@ (define-public ghc-parallel
|
||||
"This package provides a library for parallel programming.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-safesemaphore
|
||||
(package
|
||||
(name "ghc-safesemaphore")
|
||||
(version "0.10.1")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"SafeSemaphore/SafeSemaphore-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"0rpg9j6fy70i0b9dkrip9d6wim0nac0snp7qzbhykjkqlcvvgr91"))))
|
||||
(build-system haskell-build-system)
|
||||
(inputs
|
||||
`(("ghc-stm" ,ghc-stm)))
|
||||
(native-inputs
|
||||
`(("ghc-hunit" ,ghc-hunit)))
|
||||
(home-page "https://github.com/ChrisKuklewicz/SafeSemaphore")
|
||||
(synopsis "Exception safe semaphores")
|
||||
(description "This library provides exception safe semaphores that can be
|
||||
used in place of @code{QSem}, @code{QSemN}, and @code{SampleVar}, all of which
|
||||
are not exception safe and can be broken by @code{killThread}.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-text
|
||||
(package
|
||||
(name "ghc-text")
|
||||
@ -2990,6 +3015,35 @@ (define-public ghc-xml
|
||||
(description "This package provides a simple XML library for Haskell.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-feed
|
||||
(package
|
||||
(name "ghc-feed")
|
||||
(version "0.3.12.0")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"feed/feed-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"0hkrsinspg70bbm3hwqdrvivws6zya1hyk0a3awpaz82j4xnlbfc"))))
|
||||
(build-system haskell-build-system)
|
||||
(inputs
|
||||
`(("ghc-old-locale" ,ghc-old-locale)
|
||||
("ghc-old-time" ,ghc-old-time)
|
||||
("ghc-time-locale-compat" ,ghc-time-locale-compat)
|
||||
("ghc-utf8-string" ,ghc-utf8-string)
|
||||
("ghc-xml" ,ghc-xml)))
|
||||
(native-inputs
|
||||
`(("ghc-hunit" ,ghc-hunit)
|
||||
("ghc-test-framework" ,ghc-test-framework)
|
||||
("ghc-test-framework-hunit" ,ghc-test-framework-hunit)))
|
||||
(home-page "https://github.com/bergmark/feed")
|
||||
(synopsis "Haskell package for handling various syndication formats")
|
||||
(description "This Haskell package includes tools for generating and
|
||||
consuming feeds in both RSS (Really Simple Syndication) and Atom format.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-exceptions
|
||||
(package
|
||||
(name "ghc-exceptions")
|
||||
@ -3575,6 +3629,31 @@ (define-public ghc-vector-binary-instances
|
||||
boxed and storable vectors.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-bloomfilter
|
||||
(package
|
||||
(name "ghc-bloomfilter")
|
||||
(version "2.0.1.0")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"bloomfilter/bloomfilter-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"03vrmncg1c10a2wcg5skq30m1yiknn7nwxz2gblyyfaxglshspkc"))))
|
||||
(build-system haskell-build-system)
|
||||
(native-inputs
|
||||
`(("ghc-quickcheck" ,ghc-quickcheck)
|
||||
("ghc-random" ,ghc-random)
|
||||
("ghc-test-framework" ,ghc-test-framework)
|
||||
("ghc-test-framework-quickcheck2" ,ghc-test-framework-quickcheck2)))
|
||||
(home-page "https://github.com/bos/bloomfilter")
|
||||
(synopsis "Pure and impure Bloom filter implementations")
|
||||
(description "This package provides both mutable and immutable Bloom
|
||||
filter data types, along with a family of hash functions and an easy-to-use
|
||||
interface.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-network
|
||||
(package
|
||||
(name "ghc-network")
|
||||
@ -3760,6 +3839,27 @@ (define-public ghc-mmorph
|
||||
manipulating monad transformer stacks.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-ifelse
|
||||
(package
|
||||
(name "ghc-ifelse")
|
||||
(version "0.85")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"IfElse/IfElse-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"1kfx1bwfjczj93a8yqz1n8snqiq5655qgzwv1lrycry8wb1vzlwa"))))
|
||||
(build-system haskell-build-system)
|
||||
(inputs `(("ghc-mtl" ,ghc-mtl)))
|
||||
(home-page "http://hackage.haskell.org/package/IfElse")
|
||||
(synopsis "Monadic control flow with anaphoric variants")
|
||||
(description "This library provides functions for control flow inside of
|
||||
monads with anaphoric variants on @code{if} and @code{when} and a C-like
|
||||
@code{switch} function.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-monad-control
|
||||
(package
|
||||
(name "ghc-monad-control")
|
||||
@ -7738,6 +7838,44 @@ (define-public ghc-json
|
||||
JSON (JavaScript Object Notation) is a lightweight data-interchange format.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-esqueleto
|
||||
(package
|
||||
(name "ghc-esqueleto")
|
||||
(version "2.5.3")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"esqueleto/esqueleto-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"10n49rzqmblky7pwjnysalyy6nacmxfms8dqbsdv6hlyzr8pb69x"))))
|
||||
(build-system haskell-build-system)
|
||||
(inputs
|
||||
`(("ghc-blaze-html" ,ghc-blaze-html)
|
||||
("ghc-conduit" ,ghc-conduit)
|
||||
("ghc-monad-logger" ,ghc-monad-logger)
|
||||
("ghc-persistent" ,ghc-persistent)
|
||||
("ghc-resourcet" ,ghc-resourcet)
|
||||
("ghc-tagged" ,ghc-tagged)
|
||||
("ghc-text" ,ghc-text)
|
||||
("ghc-unordered-containers" ,ghc-unordered-containers)))
|
||||
(native-inputs
|
||||
`(("ghc-hspec" ,ghc-hspec)
|
||||
("ghc-hunit" ,ghc-hunit)
|
||||
("ghc-monad-control" ,ghc-monad-control)
|
||||
("ghc-persistent-sqlite" ,ghc-persistent-sqlite)
|
||||
("ghc-persistent-template" ,ghc-persistent-template)
|
||||
("ghc-quickcheck" ,ghc-quickcheck)))
|
||||
(home-page "https://github.com/bitemyapp/esqueleto")
|
||||
(synopsis "Type-safe embedded domain specific language for SQL queries")
|
||||
(description "This library provides a type-safe embedded domain specific
|
||||
language (EDSL) for SQL queries that works with SQL backends as provided by
|
||||
@code{ghc-persistent}. Its language closely resembles SQL, so you don't have
|
||||
to learn new concepts, just new syntax, and it's fairly easy to predict the
|
||||
generated SQL and optimize it for your backend.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public shellcheck
|
||||
(package
|
||||
(name "shellcheck")
|
||||
@ -7836,6 +7974,8 @@ (define-public ghc-psqueues
|
||||
(base32
|
||||
"0n39s1i88j6s7vvsdhpbhcr3gpbwlzabwcc3nbd7nqb4kb4i0sls"))))
|
||||
(build-system haskell-build-system)
|
||||
(arguments
|
||||
`(#:configure-flags (list "--allow-newer=QuickCheck")))
|
||||
(inputs
|
||||
`(("ghc-hashable" ,ghc-hashable)))
|
||||
(native-inputs
|
||||
@ -9518,4 +9658,24 @@ (define-public ghc-bytes
|
||||
(home-page "https://hackage.haskell.org/package/bytes")
|
||||
(license license:bsd-3)))
|
||||
|
||||
(define-public ghc-disk-free-space
|
||||
(package
|
||||
(name "ghc-disk-free-space")
|
||||
(version "0.1.0.1")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"disk-free-space/disk-free-space-"
|
||||
version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"07rqj8k1vh3cykq9yidpjxhgh1f7vgmjs6y1nv5kq2217ff4yypi"))))
|
||||
(build-system haskell-build-system)
|
||||
(home-page "https://github.com/redneb/disk-free-space")
|
||||
(synopsis "Retrieve information about disk space usage")
|
||||
(description "A cross-platform library for retrieving information about
|
||||
disk space usage.")
|
||||
(license license:bsd-3)))
|
||||
|
||||
;;; haskell.scm ends here
|
||||
|
@ -736,14 +736,14 @@ (define-public dino
|
||||
(define-public prosody
|
||||
(package
|
||||
(name "prosody")
|
||||
(version "0.10.1")
|
||||
(version "0.10.2")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://prosody.im/downloads/source/"
|
||||
"prosody-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"1kmmpkkgymg1r8r0k8j83pgmiskg1phl8hmpzjrnvlvsfnrnjplr"))))
|
||||
"13knr7izscw0zx648b9582dx11aap4cq9bzfiqh5ykd7wwsz1dbm"))))
|
||||
(build-system gnu-build-system)
|
||||
(arguments
|
||||
`(#:tests? #f ; no "check" target
|
||||
|
28
gnu/packages/patches/sddm-fix-build-with-qt-5.11-1024.patch
Normal file
28
gnu/packages/patches/sddm-fix-build-with-qt-5.11-1024.patch
Normal file
@ -0,0 +1,28 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 2efc649..8903b52 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -93,7 +95,7 @@
|
||||
find_package(XKB REQUIRED)
|
||||
|
||||
# Qt 5
|
||||
-find_package(Qt5 5.6.0 CONFIG REQUIRED Core DBus Gui Qml Quick LinguistTools)
|
||||
+find_package(Qt5 5.8.0 CONFIG REQUIRED Core DBus Gui Qml Quick LinguistTools Test)
|
||||
|
||||
# find qt5 imports dir
|
||||
get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
|
||||
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
|
||||
index c9d935a..bb85ddd 100644
|
||||
--- a/test/CMakeLists.txt
|
||||
+++ b/test/CMakeLists.txt
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
include_directories(../src/common)
|
||||
|
||||
-
|
||||
set(ConfigurationTest_SRCS ConfigurationTest.cpp ../src/common/ConfigReader.cpp)
|
||||
add_executable(ConfigurationTest ${ConfigurationTest_SRCS})
|
||||
add_test(NAME Configuration COMMAND ConfigurationTest)
|
||||
|
||||
-qt5_use_modules(ConfigurationTest Test)
|
||||
+target_link_libraries(ConfigurationTest Qt5::Core Qt5::Test)
|
@ -5243,6 +5243,29 @@ (define-public python-mpmath
|
||||
(define-public python2-mpmath
|
||||
(package-with-python2 python-mpmath))
|
||||
|
||||
(define-public python-bigfloat
|
||||
(package
|
||||
(name "python-bigfloat")
|
||||
(version "0.3.0")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (pypi-uri "bigfloat" version))
|
||||
(sha256
|
||||
(base32 "0xd7q4l7v0f463diznjv4k9wlaks80pn9drdqmfifi7zx8qvybi6"))))
|
||||
(build-system python-build-system)
|
||||
(inputs
|
||||
`(("mpfr" ,mpfr)))
|
||||
(home-page "https://github.com/mdickinson/bigfloat")
|
||||
(synopsis "Arbitrary precision floating-point arithmetic for Python")
|
||||
(description
|
||||
"This packages provides a Python interface to the MPFR library for
|
||||
multiprecision arithmetic.")
|
||||
(license license:lgpl3+)))
|
||||
|
||||
(define-public python2-bigfloat
|
||||
(package-with-python2 python-bigfloat))
|
||||
|
||||
(define-public python-sympy
|
||||
(package
|
||||
(name "python-sympy")
|
||||
|
@ -489,6 +489,16 @@ (define-public qtbase
|
||||
out "/share/doc/qt5/examples")
|
||||
"-opensource"
|
||||
"-confirm-license"
|
||||
|
||||
;; These features require higher versions of Linux than the
|
||||
;; minimum version of the glibc. See
|
||||
;; src/corelib/global/minimum-linux_p.h. By disabling these
|
||||
;; features Qt5 applications can be used on the oldest
|
||||
;; kernels that the glibc supports, including the RHEL6
|
||||
;; (2.6.32) and RHEL7 (3.10) kernels.
|
||||
"-no-feature-getentropy" ; requires Linux 3.17
|
||||
"-no-feature-renameat2" ; requires Linux 3.16
|
||||
|
||||
;; Do not build examples; if desired, these could go
|
||||
;; into a separate output, but for the time being, we
|
||||
;; prefer to save the space and build time.
|
||||
|
@ -63,32 +63,34 @@ (define rust-bootstrap
|
||||
(package
|
||||
(name "rust-bootstrap")
|
||||
(version "1.22.1")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (string-append
|
||||
"https://static.rust-lang.org/dist/"
|
||||
"rust-" version "-" %host-type ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
(match %host-type
|
||||
("i686-unknown-linux-gnu"
|
||||
"15zqbx86nm13d5vq2gm69b7av4vg479f74b5by64hs3bcwwm08pr")
|
||||
("x86_64-unknown-linux-gnu"
|
||||
"1yll78x6b3abnvgjf2b66gvp6mmcb9y9jdiqcwhmgc0z0i0fix4c")
|
||||
("armv7-unknown-linux-gnueabihf"
|
||||
"138a8l528kzp5wyk1mgjaxs304ac5ms8vlpq0ggjaznm6bn2j7a5")
|
||||
("aarch64-unknown-linux-gnu"
|
||||
"0z6m9m1rx4d96nvybbfmpscq4dv616m615ijy16d5wh2vx0p4na8")
|
||||
("mips64el-unknown-linux-gnuabi64"
|
||||
"07k4pcv7jvfa48cscdj8752lby7m7xdl88v3a6na1vs675lhgja2")
|
||||
(_ ""))))))
|
||||
(source #f)
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs
|
||||
`(("patchelf" ,patchelf)))
|
||||
(inputs
|
||||
`(("gcc" ,(canonical-package gcc))
|
||||
("gcc:lib" ,(canonical-package gcc) "lib")
|
||||
("zlib" ,zlib)))
|
||||
("zlib" ,zlib)
|
||||
("source"
|
||||
,(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append
|
||||
"https://static.rust-lang.org/dist/"
|
||||
"rust-" version "-" (nix-system->gnu-triplet) ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
(match (nix-system->gnu-triplet)
|
||||
("i686-unknown-linux-gnu"
|
||||
"15zqbx86nm13d5vq2gm69b7av4vg479f74b5by64hs3bcwwm08pr")
|
||||
("x86_64-unknown-linux-gnu"
|
||||
"1yll78x6b3abnvgjf2b66gvp6mmcb9y9jdiqcwhmgc0z0i0fix4c")
|
||||
("armv7-unknown-linux-gnueabihf"
|
||||
"138a8l528kzp5wyk1mgjaxs304ac5ms8vlpq0ggjaznm6bn2j7a5")
|
||||
("aarch64-unknown-linux-gnu"
|
||||
"0z6m9m1rx4d96nvybbfmpscq4dv616m615ijy16d5wh2vx0p4na8")
|
||||
("mips64el-unknown-linux-gnuabi64"
|
||||
"07k4pcv7jvfa48cscdj8752lby7m7xdl88v3a6na1vs675lhgja2")
|
||||
(_ ""))))))))
|
||||
(outputs '("out" "cargo"))
|
||||
(arguments
|
||||
`(#:tests? #f
|
||||
@ -117,7 +119,7 @@ (define rust-bootstrap
|
||||
(invoke "bash" "install.sh"
|
||||
(string-append "--prefix=" out)
|
||||
(string-append "--components=rustc,"
|
||||
"rust-std-" %host-type))
|
||||
"rust-std-" ,(nix-system->gnu-triplet)))
|
||||
;; Instal cargo
|
||||
(invoke "bash" "install.sh"
|
||||
(string-append "--prefix=" cargo-out)
|
||||
@ -196,6 +198,12 @@ (define-public rust-1.19
|
||||
;; This test is known to fail on aarch64 and powerpc64le:
|
||||
;; https://github.com/rust-lang/rust/issues/45410
|
||||
(("fn test_loading_cosine") "#[ignore]\nfn test_loading_cosine"))
|
||||
;; nm doesn't recognize the file format because of the
|
||||
;; nonstandard sections used by the Rust compiler, but readelf
|
||||
;; ignores them.
|
||||
(substitute* "src/test/run-make/atomic-lock-free/Makefile"
|
||||
(("\tnm ")
|
||||
"\treadelf -c "))
|
||||
#t)))
|
||||
(add-after 'patch-source-shebangs 'patch-cargo-checksums
|
||||
(lambda* _
|
||||
@ -386,6 +394,10 @@ (define-public rust-1.23
|
||||
(substitute* "src/tools/cargo/tests/death.rs"
|
||||
;; This is stuck when built in container.
|
||||
(("fn ctrl_c_kills_everyone") "#[ignore]\nfn ctrl_c_kills_everyone"))
|
||||
;; Prints test output in the wrong order when built on
|
||||
;; i686-linux.
|
||||
(substitute* "src/tools/cargo/tests/test.rs"
|
||||
(("fn cargo_test_env") "#[ignore]\nfn cargo_test_env"))
|
||||
#t))
|
||||
(add-after 'patch-cargo-tests 'fix-mtime-bug
|
||||
(lambda* _
|
||||
@ -433,7 +445,7 @@ (define-public rust-1.23
|
||||
# codegen/mainsubprogram.rs and codegen/mainsubprogramstart.rs
|
||||
# This tests required patched LLVM
|
||||
codegen-tests = false
|
||||
[target." %host-type "]
|
||||
[target." ,(nix-system->gnu-triplet) "]
|
||||
llvm-config = \"" llvm "/bin/llvm-config" "\"
|
||||
cc = \"" gcc "/bin/gcc" "\"
|
||||
cxx = \"" gcc "/bin/g++" "\"
|
||||
@ -456,8 +468,10 @@ (define ref (stat "README.md"))
|
||||
(invoke "./x.py" "build" "src/tools/cargo")))
|
||||
(replace 'check
|
||||
(lambda* _
|
||||
(invoke "./x.py" "test")
|
||||
(invoke "./x.py" "test" "src/tools/cargo")))
|
||||
;; Disable parallel execution to prevent EAGAIN errors when
|
||||
;; running tests.
|
||||
(invoke "./x.py" "-j1" "test")
|
||||
(invoke "./x.py" "-j1" "test" "src/tools/cargo")))
|
||||
(replace 'install
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(invoke "./x.py" "install")
|
||||
|
@ -20,6 +20,7 @@
|
||||
;;; Copyright © 2017 Oleg Pykhalov <go.wigust@gmail.com>
|
||||
;;; Copyright © 2018 Sou Bunnbu <iyzsong@member.fsf.org>
|
||||
;;; Copyright © 2018 Christopher Baines <mail@cbaines.net>
|
||||
;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -84,6 +85,7 @@ (define-module (gnu packages version-control)
|
||||
#:use-module (gnu packages python)
|
||||
#:use-module (gnu packages python-web)
|
||||
#:use-module (gnu packages readline)
|
||||
#:use-module (gnu packages rsync)
|
||||
#:use-module (gnu packages databases)
|
||||
#:use-module (gnu packages admin)
|
||||
#:use-module (gnu packages xml)
|
||||
@ -1993,3 +1995,130 @@ (define-public src
|
||||
cases like all those little scripts in your @file{~/bin} directory, or a
|
||||
directory full of HOWTOs.")
|
||||
(license license:bsd-2)))
|
||||
|
||||
(define-public git-annex
|
||||
(package
|
||||
(name "git-annex")
|
||||
(version "6.20170818")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://hackage.haskell.org/package/"
|
||||
"git-annex/git-annex-" version ".tar.gz"))
|
||||
(sha256
|
||||
(base32
|
||||
"0ybxixbqvy4rx6mq9s02rh349rbr04hb17z4bfayin0qwa5kzpvx"))))
|
||||
(build-system haskell-build-system)
|
||||
(arguments
|
||||
`(#:configure-flags
|
||||
'("--flags=-Android -Assistant -Pairing -S3 -Webapp -WebDAV")
|
||||
#:phases
|
||||
(modify-phases %standard-phases
|
||||
(add-before 'configure 'patch-shell
|
||||
(lambda _
|
||||
(substitute* "Utility/Shell.hs"
|
||||
(("/bin/sh") (which "sh")))
|
||||
#t))
|
||||
(add-before 'configure 'factor-setup
|
||||
(lambda _
|
||||
;; Factor out necessary build logic from the provided
|
||||
;; `Setup.hs' script. The script as-is does not work because
|
||||
;; it cannot find its dependencies, and there is no obvious way
|
||||
;; to tell it where to look. Note that we do not preserve the
|
||||
;; code that installs man pages here.
|
||||
(call-with-output-file "PreConf.hs"
|
||||
(lambda (out)
|
||||
(format out "import qualified Build.Configure as Configure~%")
|
||||
(format out "main = Configure.run Configure.tests~%")))
|
||||
(call-with-output-file "Setup.hs"
|
||||
(lambda (out)
|
||||
(format out "import Distribution.Simple~%")
|
||||
(format out "main = defaultMain~%")))
|
||||
#t))
|
||||
(add-before 'configure 'pre-configure
|
||||
(lambda _
|
||||
(invoke "runhaskell" "PreConf.hs")
|
||||
#t))
|
||||
(replace 'check
|
||||
(lambda _
|
||||
;; We need to set the path so that Git recognizes
|
||||
;; `git annex' as a custom command.
|
||||
(setenv "PATH" (string-append (getenv "PATH") ":"
|
||||
(getcwd) "/dist/build/git-annex"))
|
||||
(with-directory-excursion "dist/build/git-annex"
|
||||
(symlink "git-annex" "git-annex-shell"))
|
||||
(invoke "git-annex" "test")
|
||||
#t))
|
||||
(add-after 'install 'install-symlinks
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(let* ((out (assoc-ref outputs "out"))
|
||||
(bin (string-append out "/bin")))
|
||||
(symlink (string-append bin "/git-annex")
|
||||
(string-append bin "/git-annex-shell"))
|
||||
(symlink (string-append bin "/git-annex")
|
||||
(string-append bin "/git-remote-tor-annex"))
|
||||
#t))))))
|
||||
(inputs
|
||||
`(("curl" ,curl)
|
||||
("ghc-aeson" ,ghc-aeson)
|
||||
("ghc-async" ,ghc-async)
|
||||
("ghc-bloomfilter" ,ghc-bloomfilter)
|
||||
("ghc-byteable" ,ghc-byteable)
|
||||
("ghc-case-insensitive" ,ghc-case-insensitive)
|
||||
("ghc-crypto-api" ,ghc-crypto-api)
|
||||
("ghc-cryptonite" ,ghc-cryptonite)
|
||||
("ghc-data-default" ,ghc-data-default)
|
||||
("ghc-disk-free-space" ,ghc-disk-free-space)
|
||||
("ghc-dlist" ,ghc-dlist)
|
||||
("ghc-edit-distance" ,ghc-edit-distance)
|
||||
("ghc-esqueleto" ,ghc-esqueleto)
|
||||
("ghc-exceptions" ,ghc-exceptions)
|
||||
("ghc-feed" ,ghc-feed)
|
||||
("ghc-free" ,ghc-free)
|
||||
("ghc-hslogger" ,ghc-hslogger)
|
||||
("ghc-http-client" ,ghc-http-client)
|
||||
("ghc-http-conduit" ,ghc-http-conduit)
|
||||
("ghc-http-types" ,ghc-http-types)
|
||||
("ghc-ifelse" ,ghc-ifelse)
|
||||
("ghc-memory" ,ghc-memory)
|
||||
("ghc-monad-control" ,ghc-monad-control)
|
||||
("ghc-monad-logger" ,ghc-monad-logger)
|
||||
("ghc-mtl" ,ghc-mtl)
|
||||
("ghc-network" ,ghc-network)
|
||||
("ghc-old-locale" ,ghc-old-locale)
|
||||
("ghc-optparse-applicative" ,ghc-optparse-applicative)
|
||||
("ghc-persistent" ,ghc-persistent)
|
||||
("ghc-persistent-sqlite" ,ghc-persistent-sqlite)
|
||||
("ghc-persistent-template" ,ghc-persistent-template)
|
||||
("ghc-quickcheck" ,ghc-quickcheck)
|
||||
("ghc-random" ,ghc-random)
|
||||
("ghc-regex-tdfa" ,ghc-regex-tdfa)
|
||||
("ghc-resourcet" ,ghc-resourcet)
|
||||
("ghc-safesemaphore" ,ghc-safesemaphore)
|
||||
("ghc-sandi" ,ghc-sandi)
|
||||
("ghc-securemem" ,ghc-securemem)
|
||||
("ghc-socks" ,ghc-socks)
|
||||
("ghc-split" ,ghc-split)
|
||||
("ghc-stm" ,ghc-stm)
|
||||
("ghc-stm-chans" ,ghc-stm-chans)
|
||||
("ghc-text" ,ghc-text)
|
||||
("ghc-unix-compat" ,ghc-unix-compat)
|
||||
("ghc-unordered-containers" ,ghc-unordered-containers)
|
||||
("ghc-utf8-string" ,ghc-utf8-string)
|
||||
("ghc-uuid" ,ghc-uuid)
|
||||
("git" ,git)
|
||||
("rsync" ,rsync)))
|
||||
(native-inputs
|
||||
`(("ghc-tasty" ,ghc-tasty)
|
||||
("ghc-tasty-hunit" ,ghc-tasty-hunit)
|
||||
("ghc-tasty-quickcheck" ,ghc-tasty-quickcheck)
|
||||
("ghc-tasty-rerun" ,ghc-tasty-rerun)))
|
||||
(home-page "https://git-annex.branchable.com/")
|
||||
(synopsis "Manage files with Git, without checking in their contents")
|
||||
(description "This package allows managing files with Git, without
|
||||
checking the file contents into Git. It can store files in many places,
|
||||
such as local hard drives and cloud storage services. It can also be
|
||||
used to keep a folder in sync between computers.")
|
||||
;; The web app is released under the AGPLv3+.
|
||||
(license (list license:gpl3+
|
||||
license:agpl3+))))
|
||||
|
@ -25,6 +25,7 @@
|
||||
;;; Copyright © 2017 Pierre Langlois <pierre.langlois@gmx.com>
|
||||
;;; Copyright © 2017 Rutger Helling <rhelling@mykolab.com>
|
||||
;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
|
||||
;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -82,6 +83,7 @@ (define-module (gnu packages web)
|
||||
#:use-module (gnu packages gnuzilla)
|
||||
#:use-module (gnu packages gperf)
|
||||
#:use-module (gnu packages gtk)
|
||||
#:use-module (gnu packages guile)
|
||||
#:use-module (gnu packages java)
|
||||
#:use-module (gnu packages javascript)
|
||||
#:use-module (gnu packages jemalloc)
|
||||
@ -96,6 +98,7 @@ (define-module (gnu packages web)
|
||||
#:use-module (gnu packages ncurses)
|
||||
#:use-module (gnu packages openstack)
|
||||
#:use-module (gnu packages base)
|
||||
#:use-module (gnu packages package-management)
|
||||
#:use-module (gnu packages perl)
|
||||
#:use-module (gnu packages perl-check)
|
||||
#:use-module (gnu packages python)
|
||||
@ -6424,3 +6427,81 @@ (define-public nghttp2
|
||||
@item @command{inflatehd} converts such compressed headers back to JSON pairs.
|
||||
@end itemize\n")
|
||||
(license l:expat)))
|
||||
|
||||
(define-public hpcguix-web
|
||||
(let ((commit "3e3b9a3a406ee2dcd10c96cbedcc16ea378e8e8f"))
|
||||
(package
|
||||
(name "hpcguix-web")
|
||||
(version (git-version "0.0.1" "0" commit))
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://github.com/UMCUGenetics/hpcguix-web.git")
|
||||
(commit commit)))
|
||||
(file-name (git-file-name name version))
|
||||
(sha256
|
||||
(base32
|
||||
"01888byi9mh7d3adcmwhmg44kg98g92r44ilc4wd7an66mjnxpry"))))
|
||||
(build-system gnu-build-system)
|
||||
(arguments
|
||||
`(#:modules ((guix build gnu-build-system)
|
||||
(guix build utils)
|
||||
(srfi srfi-26)
|
||||
(ice-9 popen)
|
||||
(ice-9 rdelim))
|
||||
|
||||
#:phases
|
||||
(modify-phases %standard-phases
|
||||
(add-before 'configure 'autoconf
|
||||
(lambda _
|
||||
(setenv "GUILE_AUTO_COMPILE" "0")
|
||||
(setenv "XDG_CACHE_HOME" (getcwd))
|
||||
(invoke "autoreconf" "-vif")))
|
||||
(add-after 'install 'wrap-program
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let* ((out (assoc-ref outputs "out"))
|
||||
(guix (assoc-ref inputs "guix"))
|
||||
(guile (assoc-ref inputs "guile"))
|
||||
(json (assoc-ref inputs "guile-json"))
|
||||
(guile-cm (assoc-ref inputs
|
||||
"guile-commonmark"))
|
||||
(deps (list guile guile-cm guix json))
|
||||
(effective
|
||||
(read-line
|
||||
(open-pipe* OPEN_READ
|
||||
(string-append guile "/bin/guile")
|
||||
"-c" "(display (effective-version))")))
|
||||
(path (string-join
|
||||
(map (cut string-append <>
|
||||
"/share/guile/site/"
|
||||
effective)
|
||||
deps)
|
||||
":"))
|
||||
(gopath (string-join
|
||||
(map (cut string-append <>
|
||||
"/lib/guile/" effective
|
||||
"/site-ccache")
|
||||
deps)
|
||||
":")))
|
||||
(wrap-program (string-append out "/bin/run")
|
||||
`("GUILE_LOAD_PATH" ":" prefix (,path))
|
||||
`("GUILE_LOAD_COMPILED_PATH" ":" prefix (,gopath)))
|
||||
|
||||
#t))))))
|
||||
(native-inputs
|
||||
`(("autoconf" ,autoconf)
|
||||
("automake" ,automake)
|
||||
("uglify-js" ,uglify-js)
|
||||
("pkg-config" ,pkg-config)))
|
||||
(inputs
|
||||
`(("guix" ,guix)))
|
||||
(propagated-inputs
|
||||
`(("guile" ,guile-2.2)
|
||||
("guile-commonmark" ,guile-commonmark)
|
||||
("guile-json" ,guile-json)))
|
||||
(home-page "https://github.com/UMCUGenetics/hpcguix-web")
|
||||
(synopsis "Web interface for cluster deployments of Guix")
|
||||
(description "Hpcguix-web provides a web interface to the list of packages
|
||||
provided by Guix. The list of packages is searchable and provides
|
||||
instructions on how to use Guix in a shared HPC environment.")
|
||||
(license l:agpl3+))))
|
||||
|
@ -6,6 +6,7 @@
|
||||
;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
|
||||
;;; Copyright © 2017 nee <nee-git@hidamari.blue>
|
||||
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
|
||||
;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -25,11 +26,14 @@
|
||||
(define-module (gnu services web)
|
||||
#:use-module (gnu services)
|
||||
#:use-module (gnu services shepherd)
|
||||
#:use-module (gnu system pam)
|
||||
#:use-module (gnu system shadow)
|
||||
#:use-module (gnu packages admin)
|
||||
#:use-module (gnu packages web)
|
||||
#:use-module (gnu packages php)
|
||||
#:use-module (gnu packages guile)
|
||||
#:use-module (guix records)
|
||||
#:use-module (guix modules)
|
||||
#:use-module (guix gexp)
|
||||
#:use-module ((guix utils) #:select (version-major))
|
||||
#:use-module ((guix packages) #:select (package-version))
|
||||
@ -155,7 +159,11 @@ (define-module (gnu services web)
|
||||
php-fpm-service-type
|
||||
nginx-php-location
|
||||
|
||||
cat-avatar-generator-service))
|
||||
cat-avatar-generator-service
|
||||
|
||||
hpcguix-web-configuration
|
||||
hpcguix-web-configuration?
|
||||
hpcguix-web-service-type))
|
||||
|
||||
;;; Commentary:
|
||||
;;;
|
||||
@ -893,3 +901,65 @@ (define* (cat-avatar-generator-service
|
||||
(nginx-server-configuration-locations configuration)))
|
||||
(root #~(string-append #$package
|
||||
"/share/web/cat-avatar-generator"))))))
|
||||
|
||||
|
||||
(define-record-type* <hpcguix-web-configuration>
|
||||
hpcguix-web-configuration make-hpcguix-web-configuration
|
||||
hpcguix-web-configuration?
|
||||
|
||||
(package hpcguix-web-package (default hpcguix-web)) ;<package>
|
||||
|
||||
;; Specs is gexp of hpcguix-web configuration file
|
||||
(specs hpcguix-web-configuration-specs))
|
||||
|
||||
(define %hpcguix-web-accounts
|
||||
(list (user-group
|
||||
(name "hpcguix-web")
|
||||
(system? #t))
|
||||
(user-account
|
||||
(name "hpcguix-web")
|
||||
(group "hpcguix-web")
|
||||
(system? #t)
|
||||
(comment "hpcguix-web")
|
||||
(home-directory "/var/empty")
|
||||
(shell (file-append shadow "/sbin/nologin")))))
|
||||
|
||||
(define %hpcguix-web-activation
|
||||
#~(begin
|
||||
(use-modules (guix build utils))
|
||||
(let ((home-dir "/var/cache/guix/web")
|
||||
(user (getpwnam "hpcguix-web")))
|
||||
(mkdir-p home-dir)
|
||||
(chown home-dir (passwd:uid user) (passwd:gid user))
|
||||
(chmod home-dir #o755))))
|
||||
|
||||
(define (hpcguix-web-shepherd-service config)
|
||||
(let ((specs (hpcguix-web-configuration-specs config))
|
||||
(hpcguix-web (hpcguix-web-package config)))
|
||||
(with-imported-modules (source-module-closure
|
||||
'((gnu build shepherd)))
|
||||
(shepherd-service
|
||||
(documentation "hpcguix-web daemon")
|
||||
(provision '(hpcguix-web))
|
||||
(requirement '(networking))
|
||||
(start #~(make-forkexec-constructor
|
||||
(list #$(file-append hpcguix-web "/bin/run")
|
||||
(string-append "--config="
|
||||
#$(scheme-file "hpcguix-web.scm" specs)))
|
||||
#:user "hpcguix-web"
|
||||
#:group "hpcguix-web"
|
||||
#:environment-variables
|
||||
(list "XDG_CACHE_HOME=/var/cache")))
|
||||
(stop #~(make-kill-destructor))))))
|
||||
|
||||
(define hpcguix-web-service-type
|
||||
(service-type
|
||||
(name 'hpcguix-web)
|
||||
(description "Run the hpcguix-web server.")
|
||||
(extensions
|
||||
(list (service-extension account-service-type
|
||||
(const %hpcguix-web-accounts))
|
||||
(service-extension activation-service-type
|
||||
(const %hpcguix-web-activation))
|
||||
(service-extension shepherd-root-service-type
|
||||
(compose list hpcguix-web-shepherd-service))))))
|
||||
|
@ -317,8 +317,8 @@ (define device-sexp->device
|
||||
(_ ;the old format
|
||||
"/")))))
|
||||
(x ;unsupported format
|
||||
(warning (G_ "unrecognized boot parameters for '~a'~%")
|
||||
system)
|
||||
(warning (G_ "unrecognized boot parameters at '~a'~%")
|
||||
(port-filename port))
|
||||
#f)))
|
||||
|
||||
(define (read-boot-parameters-file system)
|
||||
|
@ -410,58 +410,57 @@ (define-module (guix config)
|
||||
(eval-when (expand load eval)
|
||||
(define %libgcrypt
|
||||
#+(file-append libgcrypt "/lib/libgcrypt"))))))
|
||||
|
||||
(mlet %store-monad ((os-drv (operating-system-derivation os #:container? #t))
|
||||
(name -> (string-append name ".tar.gz"))
|
||||
(graph -> "system-graph"))
|
||||
(define build
|
||||
(with-imported-modules `(,@(source-module-closure '((guix docker)
|
||||
(guix build utils)
|
||||
(gnu build vm))
|
||||
#:select? not-config?)
|
||||
(guix build store-copy)
|
||||
((guix config) => ,config))
|
||||
#~(begin
|
||||
;; Guile-JSON is required by (guix docker).
|
||||
(add-to-load-path
|
||||
(string-append #+guile-json "/share/guile/site/"
|
||||
(effective-version)))
|
||||
(use-modules (guix docker)
|
||||
(guix build utils)
|
||||
(gnu build vm)
|
||||
(srfi srfi-19)
|
||||
(guix build store-copy))
|
||||
(with-extensions (list guile-json) ;for (guix docker)
|
||||
(with-imported-modules `(,@(source-module-closure
|
||||
'((guix docker)
|
||||
(guix build utils)
|
||||
(gnu build vm))
|
||||
#:select? not-config?)
|
||||
(guix build store-copy)
|
||||
((guix config) => ,config))
|
||||
#~(begin
|
||||
(use-modules (guix docker)
|
||||
(guix build utils)
|
||||
(gnu build vm)
|
||||
(srfi srfi-19)
|
||||
(guix build store-copy))
|
||||
|
||||
(let* ((inputs '#$(append (list tar)
|
||||
(if register-closures?
|
||||
(list guix)
|
||||
'())))
|
||||
;; This initializer requires elevated privileges that are
|
||||
;; not normally available in the build environment (e.g.,
|
||||
;; it needs to create device nodes). In order to obtain
|
||||
;; such privileges, we run it as root in a VM.
|
||||
(initialize (root-partition-initializer
|
||||
#:closures '(#$graph)
|
||||
#:register-closures? #$register-closures?
|
||||
#:system-directory #$os-drv
|
||||
;; De-duplication would fail due to
|
||||
;; cross-device link errors, so don't do it.
|
||||
#:deduplicate? #f))
|
||||
;; Even as root in a VM, the initializer would fail due to
|
||||
;; lack of privileges if we use a root-directory that is on
|
||||
;; a file system that is shared with the host (e.g., /tmp).
|
||||
(root-directory "/guixsd-system-root"))
|
||||
(set-path-environment-variable "PATH" '("bin" "sbin") inputs)
|
||||
(mkdir root-directory)
|
||||
(initialize root-directory)
|
||||
(build-docker-image
|
||||
(string-append "/xchg/" #$name) ;; The output file.
|
||||
(cons* root-directory
|
||||
(call-with-input-file (string-append "/xchg/" #$graph)
|
||||
read-reference-graph))
|
||||
#$os-drv
|
||||
#:compressor '(#+(file-append gzip "/bin/gzip") "-9n")
|
||||
#:creation-time (make-time time-utc 0 1)
|
||||
#:transformations `((,root-directory -> "")))))))
|
||||
(let* ((inputs '#$(append (list tar)
|
||||
(if register-closures?
|
||||
(list guix)
|
||||
'())))
|
||||
;; This initializer requires elevated privileges that are
|
||||
;; not normally available in the build environment (e.g.,
|
||||
;; it needs to create device nodes). In order to obtain
|
||||
;; such privileges, we run it as root in a VM.
|
||||
(initialize (root-partition-initializer
|
||||
#:closures '(#$graph)
|
||||
#:register-closures? #$register-closures?
|
||||
#:system-directory #$os-drv
|
||||
;; De-duplication would fail due to
|
||||
;; cross-device link errors, so don't do it.
|
||||
#:deduplicate? #f))
|
||||
;; Even as root in a VM, the initializer would fail due to
|
||||
;; lack of privileges if we use a root-directory that is on
|
||||
;; a file system that is shared with the host (e.g., /tmp).
|
||||
(root-directory "/guixsd-system-root"))
|
||||
(set-path-environment-variable "PATH" '("bin" "sbin") inputs)
|
||||
(mkdir root-directory)
|
||||
(initialize root-directory)
|
||||
(build-docker-image
|
||||
(string-append "/xchg/" #$name) ;; The output file.
|
||||
(cons* root-directory
|
||||
(call-with-input-file (string-append "/xchg/" #$graph)
|
||||
read-reference-graph))
|
||||
#$os-drv
|
||||
#:compressor '(#+(file-append gzip "/bin/gzip") "-9n")
|
||||
#:creation-time (make-time time-utc 0 1)
|
||||
#:transformations `((,root-directory -> ""))))))))
|
||||
(expression->derivation-in-linux-vm
|
||||
name
|
||||
;; The VM's initrd Guile doesn't support dlopen, but our "build" gexp
|
||||
|
@ -1,5 +1,5 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -96,22 +96,7 @@ (define %dico-socket
|
||||
;; Wait until dicod is actually listening.
|
||||
;; TODO: Use a PID file instead.
|
||||
(test-assert "connect inside"
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (ice-9 rdelim))
|
||||
(let ((sock (socket PF_INET SOCK_STREAM 0)))
|
||||
(let loop ((i 0))
|
||||
(pk 'try i)
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
(connect sock AF_INET INADDR_LOOPBACK 2628))
|
||||
(lambda args
|
||||
(pk 'connection-error args)
|
||||
(when (< i 20)
|
||||
(sleep 1)
|
||||
(loop (+ 1 i))))))
|
||||
(read-line sock 'concat)))
|
||||
marionette))
|
||||
(wait-for-tcp-port 2628 marionette))
|
||||
|
||||
(test-assert "connect"
|
||||
(let ((addr (make-socket-address AF_INET INADDR_LOOPBACK 8000)))
|
||||
|
@ -1,5 +1,5 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
|
||||
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
|
||||
;;;
|
||||
@ -49,156 +49,150 @@ (define vm
|
||||
|
||||
(define test
|
||||
(with-imported-modules '((gnu build marionette))
|
||||
#~(begin
|
||||
(eval-when (expand load eval)
|
||||
;; Prepare to use Guile-SSH.
|
||||
(set! %load-path
|
||||
(cons (string-append #+guile-ssh "/share/guile/site/"
|
||||
(effective-version))
|
||||
%load-path)))
|
||||
(with-extensions (list guile-ssh)
|
||||
#~(begin
|
||||
(use-modules (gnu build marionette)
|
||||
(srfi srfi-26)
|
||||
(srfi srfi-64)
|
||||
(ice-9 match)
|
||||
(ssh session)
|
||||
(ssh auth)
|
||||
(ssh channel)
|
||||
(ssh sftp))
|
||||
|
||||
(use-modules (gnu build marionette)
|
||||
(srfi srfi-26)
|
||||
(srfi srfi-64)
|
||||
(ice-9 match)
|
||||
(ssh session)
|
||||
(ssh auth)
|
||||
(ssh channel)
|
||||
(ssh sftp))
|
||||
(define marionette
|
||||
;; Enable TCP forwarding of the guest's port 22.
|
||||
(make-marionette (list #$vm)))
|
||||
|
||||
(define marionette
|
||||
;; Enable TCP forwarding of the guest's port 22.
|
||||
(make-marionette (list #$vm)))
|
||||
(define (make-session-for-test)
|
||||
"Make a session with predefined parameters for a test."
|
||||
(make-session #:user "root"
|
||||
#:port 2222
|
||||
#:host "localhost"
|
||||
#:log-verbosity 'protocol))
|
||||
|
||||
(define (make-session-for-test)
|
||||
"Make a session with predefined parameters for a test."
|
||||
(make-session #:user "root"
|
||||
#:port 2222
|
||||
#:host "localhost"
|
||||
#:log-verbosity 'protocol))
|
||||
|
||||
(define (call-with-connected-session proc)
|
||||
"Call the one-argument procedure PROC with a freshly created and
|
||||
(define (call-with-connected-session proc)
|
||||
"Call the one-argument procedure PROC with a freshly created and
|
||||
connected SSH session object, return the result of the procedure call. The
|
||||
session is disconnected when the PROC is finished."
|
||||
(let ((session (make-session-for-test)))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
(let ((result (connect! session)))
|
||||
(unless (equal? result 'ok)
|
||||
(error "Could not connect to a server"
|
||||
session result))))
|
||||
(lambda () (proc session))
|
||||
(lambda () (disconnect! session)))))
|
||||
(let ((session (make-session-for-test)))
|
||||
(dynamic-wind
|
||||
(lambda ()
|
||||
(let ((result (connect! session)))
|
||||
(unless (equal? result 'ok)
|
||||
(error "Could not connect to a server"
|
||||
session result))))
|
||||
(lambda () (proc session))
|
||||
(lambda () (disconnect! session)))))
|
||||
|
||||
(define (call-with-connected-session/auth proc)
|
||||
"Make an authenticated session. We should be able to connect as
|
||||
(define (call-with-connected-session/auth proc)
|
||||
"Make an authenticated session. We should be able to connect as
|
||||
root with an empty password."
|
||||
(call-with-connected-session
|
||||
(lambda (session)
|
||||
;; Try the simple authentication methods. Dropbear requires
|
||||
;; 'none' when there are no passwords, whereas OpenSSH accepts
|
||||
;; 'password' with an empty password.
|
||||
(let loop ((methods (list (cut userauth-password! <> "")
|
||||
(cut userauth-none! <>))))
|
||||
(match methods
|
||||
(()
|
||||
(error "all the authentication methods failed"))
|
||||
((auth rest ...)
|
||||
(match (pk 'auth (auth session))
|
||||
('success
|
||||
(proc session))
|
||||
('denied
|
||||
(loop rest)))))))))
|
||||
(call-with-connected-session
|
||||
(lambda (session)
|
||||
;; Try the simple authentication methods. Dropbear requires
|
||||
;; 'none' when there are no passwords, whereas OpenSSH accepts
|
||||
;; 'password' with an empty password.
|
||||
(let loop ((methods (list (cut userauth-password! <> "")
|
||||
(cut userauth-none! <>))))
|
||||
(match methods
|
||||
(()
|
||||
(error "all the authentication methods failed"))
|
||||
((auth rest ...)
|
||||
(match (pk 'auth (auth session))
|
||||
('success
|
||||
(proc session))
|
||||
('denied
|
||||
(loop rest)))))))))
|
||||
|
||||
(mkdir #$output)
|
||||
(chdir #$output)
|
||||
(mkdir #$output)
|
||||
(chdir #$output)
|
||||
|
||||
(test-begin "ssh-daemon")
|
||||
(test-begin "ssh-daemon")
|
||||
|
||||
;; Wait for sshd to be up and running.
|
||||
(test-eq "service running"
|
||||
'running!
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (gnu services herd))
|
||||
(start-service 'ssh-daemon)
|
||||
'running!)
|
||||
marionette))
|
||||
;; Wait for sshd to be up and running.
|
||||
(test-eq "service running"
|
||||
'running!
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (gnu services herd))
|
||||
(start-service 'ssh-daemon)
|
||||
'running!)
|
||||
marionette))
|
||||
|
||||
;; Check sshd's PID file.
|
||||
(test-equal "sshd PID"
|
||||
(wait-for-file #$pid-file marionette)
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (gnu services herd)
|
||||
(srfi srfi-1))
|
||||
;; Check sshd's PID file.
|
||||
(test-equal "sshd PID"
|
||||
(wait-for-file #$pid-file marionette)
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (gnu services herd)
|
||||
(srfi srfi-1))
|
||||
|
||||
(live-service-running
|
||||
(find (lambda (live)
|
||||
(memq 'ssh-daemon
|
||||
(live-service-provision live)))
|
||||
(current-services))))
|
||||
marionette))
|
||||
(live-service-running
|
||||
(find (lambda (live)
|
||||
(memq 'ssh-daemon
|
||||
(live-service-provision live)))
|
||||
(current-services))))
|
||||
marionette))
|
||||
|
||||
;; Connect to the guest over SSH. Make sure we can run a shell
|
||||
;; command there.
|
||||
(test-equal "shell command"
|
||||
'hello
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
;; FIXME: 'get-server-public-key' segfaults.
|
||||
;; (get-server-public-key session)
|
||||
(let ((channel (make-channel session)))
|
||||
(channel-open-session channel)
|
||||
(channel-request-exec channel "echo hello > /root/witness")
|
||||
(and (zero? (channel-get-exit-status channel))
|
||||
(wait-for-file "/root/witness" marionette))))))
|
||||
;; Connect to the guest over SSH. Make sure we can run a shell
|
||||
;; command there.
|
||||
(test-equal "shell command"
|
||||
'hello
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
;; FIXME: 'get-server-public-key' segfaults.
|
||||
;; (get-server-public-key session)
|
||||
(let ((channel (make-channel session)))
|
||||
(channel-open-session channel)
|
||||
(channel-request-exec channel "echo hello > /root/witness")
|
||||
(and (zero? (channel-get-exit-status channel))
|
||||
(wait-for-file "/root/witness" marionette))))))
|
||||
|
||||
;; Connect to the guest over SFTP. Make sure we can write and
|
||||
;; read a file there.
|
||||
(unless #$sftp?
|
||||
(test-skip 1))
|
||||
(test-equal "SFTP file writing and reading"
|
||||
'hello
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
(let ((sftp-session (make-sftp-session session))
|
||||
(witness "/root/sftp-witness"))
|
||||
(call-with-remote-output-file sftp-session witness
|
||||
(cut display "hello" <>))
|
||||
(call-with-remote-input-file sftp-session witness
|
||||
read)))))
|
||||
;; Connect to the guest over SFTP. Make sure we can write and
|
||||
;; read a file there.
|
||||
(unless #$sftp?
|
||||
(test-skip 1))
|
||||
(test-equal "SFTP file writing and reading"
|
||||
'hello
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
(let ((sftp-session (make-sftp-session session))
|
||||
(witness "/root/sftp-witness"))
|
||||
(call-with-remote-output-file sftp-session witness
|
||||
(cut display "hello" <>))
|
||||
(call-with-remote-input-file sftp-session witness
|
||||
read)))))
|
||||
|
||||
;; Connect to the guest over SSH. Make sure we can run commands
|
||||
;; from the system profile.
|
||||
(test-equal "run executables from system profile"
|
||||
#t
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
(let ((channel (make-channel session)))
|
||||
(channel-open-session channel)
|
||||
(channel-request-exec
|
||||
channel
|
||||
(string-append
|
||||
"mkdir -p /root/.guix-profile/bin && "
|
||||
"touch /root/.guix-profile/bin/path-witness && "
|
||||
"chmod 755 /root/.guix-profile/bin/path-witness"))
|
||||
(zero? (channel-get-exit-status channel))))))
|
||||
;; Connect to the guest over SSH. Make sure we can run commands
|
||||
;; from the system profile.
|
||||
(test-equal "run executables from system profile"
|
||||
#t
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
(let ((channel (make-channel session)))
|
||||
(channel-open-session channel)
|
||||
(channel-request-exec
|
||||
channel
|
||||
(string-append
|
||||
"mkdir -p /root/.guix-profile/bin && "
|
||||
"touch /root/.guix-profile/bin/path-witness && "
|
||||
"chmod 755 /root/.guix-profile/bin/path-witness"))
|
||||
(zero? (channel-get-exit-status channel))))))
|
||||
|
||||
;; Connect to the guest over SSH. Make sure we can run commands
|
||||
;; from the user profile.
|
||||
(test-equal "run executable from user profile"
|
||||
#t
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
(let ((channel (make-channel session)))
|
||||
(channel-open-session channel)
|
||||
(channel-request-exec channel "path-witness")
|
||||
(zero? (channel-get-exit-status channel))))))
|
||||
;; Connect to the guest over SSH. Make sure we can run commands
|
||||
;; from the user profile.
|
||||
(test-equal "run executable from user profile"
|
||||
#t
|
||||
(call-with-connected-session/auth
|
||||
(lambda (session)
|
||||
(let ((channel (make-channel session)))
|
||||
(channel-open-session channel)
|
||||
(channel-request-exec channel "path-witness")
|
||||
(zero? (channel-get-exit-status channel))))))
|
||||
|
||||
(test-end)
|
||||
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))
|
||||
(test-end)
|
||||
(exit (= (test-runner-fail-count (test-runner-current)) 0))))))
|
||||
|
||||
(gexp->derivation name test))
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017 Christopher Baines <mail@cbaines.net>
|
||||
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
|
||||
;;; Copyright © 2018 Pierre-Antoine Rouby <pierre-antoine.rouby@inria.fr>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -31,7 +32,8 @@ (define-module (gnu tests web)
|
||||
#:use-module (guix store)
|
||||
#:export (%test-httpd
|
||||
%test-nginx
|
||||
%test-php-fpm))
|
||||
%test-php-fpm
|
||||
%test-hpcguix-web))
|
||||
|
||||
(define %index.html-contents
|
||||
;; Contents of the /index.html file.
|
||||
@ -281,3 +283,81 @@ (define %test-php-fpm
|
||||
(name "php-fpm")
|
||||
(description "Test PHP-FPM through nginx.")
|
||||
(value (run-php-fpm-test))))
|
||||
|
||||
|
||||
;;;
|
||||
;;; hpcguix-web
|
||||
;;;
|
||||
|
||||
(define* (run-hpcguix-web-server-test name test-os)
|
||||
"Run tests in %HPCGUIX-WEB-OS, which has hpcguix-web running."
|
||||
(define os
|
||||
(marionette-operating-system
|
||||
test-os
|
||||
#:imported-modules '((gnu services herd)
|
||||
(guix combinators))))
|
||||
|
||||
(define vm
|
||||
(virtual-machine
|
||||
(operating-system os)
|
||||
(port-forwardings '((8080 . 5000)))))
|
||||
|
||||
(define test
|
||||
(with-imported-modules '((gnu build marionette))
|
||||
#~(begin
|
||||
(use-modules (srfi srfi-11) (srfi srfi-64)
|
||||
(gnu build marionette)
|
||||
(web uri)
|
||||
(web client)
|
||||
(web response))
|
||||
|
||||
(define marionette
|
||||
(make-marionette (list #$vm)))
|
||||
|
||||
(mkdir #$output)
|
||||
(chdir #$output)
|
||||
|
||||
(test-begin #$name)
|
||||
|
||||
(test-assert "hpcguix-web running"
|
||||
(marionette-eval
|
||||
'(begin
|
||||
(use-modules (gnu services herd))
|
||||
(match (start-service 'hpcguix-web)
|
||||
(#f #f)
|
||||
(('service response-parts ...)
|
||||
(match (assq-ref response-parts 'running)
|
||||
((pid) (number? pid))))))
|
||||
marionette))
|
||||
|
||||
(test-equal "http-get"
|
||||
200
|
||||
(begin
|
||||
(wait-for-tcp-port 5000 marionette)
|
||||
(let-values (((response text)
|
||||
(http-get "http://localhost:8080")))
|
||||
(response-code response))))
|
||||
|
||||
(test-end)
|
||||
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))
|
||||
|
||||
(gexp->derivation (string-append name "-test") test))
|
||||
|
||||
(define %hpcguix-web-specs
|
||||
;; Server config gexp.
|
||||
#~(define site-config
|
||||
(hpcweb-configuration
|
||||
(title-prefix "[TEST] HPCGUIX-WEB"))))
|
||||
|
||||
(define %hpcguix-web-os
|
||||
(simple-operating-system
|
||||
(dhcp-client-service)
|
||||
(service hpcguix-web-service-type
|
||||
(hpcguix-web-configuration
|
||||
(specs %hpcguix-web-specs)))))
|
||||
|
||||
(define %test-hpcguix-web
|
||||
(system-test
|
||||
(name "hpcguix-web")
|
||||
(description "Connect to a running hpcguix-web server.")
|
||||
(value (run-hpcguix-web-server-test name %hpcguix-web-os))))
|
||||
|
@ -1,5 +1,6 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017 Caleb Ristvedt <caleb.ristvedt@cune.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -29,6 +30,7 @@ (define-module (guix config)
|
||||
|
||||
%store-directory
|
||||
%state-directory
|
||||
%store-database-directory
|
||||
%config-directory
|
||||
%guix-register-program
|
||||
|
||||
@ -80,6 +82,10 @@ (define %state-directory
|
||||
(or (getenv "NIX_STATE_DIR")
|
||||
(string-append %localstatedir "/guix")))
|
||||
|
||||
(define %store-database-directory
|
||||
(or (and=> (getenv "NIX_DB_DIR") canonicalize-path)
|
||||
(string-append %state-directory "/db")))
|
||||
|
||||
(define %config-directory
|
||||
;; This must match `GUIX_CONFIGURATION_DIRECTORY' as defined in `nix/local.mk'.
|
||||
(or (getenv "GUIX_CONFIGURATION_DIRECTORY")
|
||||
|
@ -1,6 +1,6 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
|
||||
;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
@ -26,6 +26,7 @@ (define-module (guix docker)
|
||||
delete-file-recursively
|
||||
with-directory-excursion
|
||||
invoke))
|
||||
#:use-module (json) ;guile-json
|
||||
#:use-module (srfi srfi-19)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module ((texinfo string-utils)
|
||||
@ -34,9 +35,6 @@ (define-module (guix docker)
|
||||
#:use-module (ice-9 match)
|
||||
#:export (build-docker-image))
|
||||
|
||||
;; Load Guile-JSON at run time to simplify the job of 'imported-modules' & co.
|
||||
(module-use! (current-module) (resolve-interface '(json)))
|
||||
|
||||
;; Generate a 256-bit identifier in hexadecimal encoding for the Docker image.
|
||||
(define docker-id
|
||||
(compose bytevector->base16-string sha256 string->utf8))
|
||||
|
196
guix/gexp.scm
196
guix/gexp.scm
@ -33,6 +33,7 @@ (define-module (guix gexp)
|
||||
#:export (gexp
|
||||
gexp?
|
||||
with-imported-modules
|
||||
with-extensions
|
||||
|
||||
gexp-input
|
||||
gexp-input?
|
||||
@ -118,10 +119,11 @@ (define-module (guix gexp)
|
||||
|
||||
;; "G expressions".
|
||||
(define-record-type <gexp>
|
||||
(make-gexp references modules proc)
|
||||
(make-gexp references modules extensions proc)
|
||||
gexp?
|
||||
(references gexp-references) ;list of <gexp-input>
|
||||
(modules gexp-self-modules) ;list of module names
|
||||
(extensions gexp-self-extensions) ;list of lowerable things
|
||||
(proc gexp-proc)) ;procedure
|
||||
|
||||
(define (write-gexp gexp port)
|
||||
@ -492,19 +494,20 @@ (define (write-gexp-output output port)
|
||||
|
||||
(set-record-type-printer! <gexp-output> write-gexp-output)
|
||||
|
||||
(define (gexp-modules gexp)
|
||||
"Return the list of Guile module names GEXP relies on. If (gexp? GEXP) is
|
||||
false, meaning that GEXP is a plain Scheme object, return the empty list."
|
||||
(define (gexp-attribute gexp self-attribute)
|
||||
"Recurse on GEXP and the expressions it refers to, summing the items
|
||||
returned by SELF-ATTRIBUTE, a procedure that takes a gexp."
|
||||
(if (gexp? gexp)
|
||||
(delete-duplicates
|
||||
(append (gexp-self-modules gexp)
|
||||
(append (self-attribute gexp)
|
||||
(append-map (match-lambda
|
||||
(($ <gexp-input> (? gexp? exp))
|
||||
(gexp-modules exp))
|
||||
(gexp-attribute exp self-attribute))
|
||||
(($ <gexp-input> (lst ...))
|
||||
(append-map (lambda (item)
|
||||
(if (gexp? item)
|
||||
(gexp-modules item)
|
||||
(gexp-attribute item
|
||||
self-attribute)
|
||||
'()))
|
||||
lst))
|
||||
(_
|
||||
@ -512,6 +515,17 @@ (define (gexp-modules gexp)
|
||||
(gexp-references gexp))))
|
||||
'())) ;plain Scheme data type
|
||||
|
||||
(define (gexp-modules gexp)
|
||||
"Return the list of Guile module names GEXP relies on. If (gexp? GEXP) is
|
||||
false, meaning that GEXP is a plain Scheme object, return the empty list."
|
||||
(gexp-attribute gexp gexp-self-modules))
|
||||
|
||||
(define (gexp-extensions gexp)
|
||||
"Return the list of Guile extensions (packages) GEXP relies on. If (gexp?
|
||||
GEXP) is false, meaning that GEXP is a plain Scheme object, return the empty
|
||||
list."
|
||||
(gexp-attribute gexp gexp-self-extensions))
|
||||
|
||||
(define* (lower-inputs inputs
|
||||
#:key system target)
|
||||
"Turn any package from INPUTS into a derivation for SYSTEM; return the
|
||||
@ -577,6 +591,7 @@ (define* (gexp->derivation name exp
|
||||
(modules '())
|
||||
(module-path %load-path)
|
||||
(guile-for-build (%guile-for-build))
|
||||
(effective-version "2.2")
|
||||
(graft? (%graft?))
|
||||
references-graphs
|
||||
allowed-references disallowed-references
|
||||
@ -595,6 +610,9 @@ (define* (gexp->derivation name exp
|
||||
compiled, and made available in the load path during the execution of
|
||||
EXP---e.g., '((guix build utils) (guix build gnu-build-system)).
|
||||
|
||||
EFFECTIVE-VERSION determines the string to use when adding extensions of
|
||||
EXP (see 'with-extensions') to the search path---e.g., \"2.2\".
|
||||
|
||||
GRAFT? determines whether packages referred to by EXP should be grafted when
|
||||
applicable.
|
||||
|
||||
@ -630,7 +648,7 @@ (define outputs (gexp-outputs exp))
|
||||
(define (graphs-file-names graphs)
|
||||
;; Return a list of (FILE-NAME . STORE-PATH) pairs made from GRAPHS.
|
||||
(map (match-lambda
|
||||
;; TODO: Remove 'derivation?' special cases.
|
||||
;; TODO: Remove 'derivation?' special cases.
|
||||
((file-name (? derivation? drv))
|
||||
(cons file-name (derivation->output-path drv)))
|
||||
((file-name (? derivation? drv) sub-drv)
|
||||
@ -639,7 +657,13 @@ (define (graphs-file-names graphs)
|
||||
(cons file-name thing)))
|
||||
graphs))
|
||||
|
||||
(mlet* %store-monad (;; The following binding forces '%current-system' and
|
||||
(define (extension-flags extension)
|
||||
`("-L" ,(string-append (derivation->output-path extension)
|
||||
"/share/guile/site/" effective-version)
|
||||
"-C" ,(string-append (derivation->output-path extension)
|
||||
"/lib/guile/" effective-version "/site-ccache")))
|
||||
|
||||
(mlet* %store-monad ( ;; The following binding forces '%current-system' and
|
||||
;; '%current-target-system' to be looked up at >>=
|
||||
;; time.
|
||||
(graft? (set-grafting graft?))
|
||||
@ -660,6 +684,11 @@ (define (graphs-file-names graphs)
|
||||
#:target target))
|
||||
(builder (text-file script-name
|
||||
(object->string sexp)))
|
||||
(extensions -> (gexp-extensions exp))
|
||||
(exts (mapm %store-monad
|
||||
(lambda (obj)
|
||||
(lower-object obj system))
|
||||
extensions))
|
||||
(modules (if (pair? %modules)
|
||||
(imported-modules %modules
|
||||
#:system system
|
||||
@ -672,6 +701,7 @@ (define (graphs-file-names graphs)
|
||||
(compiled-modules %modules
|
||||
#:system system
|
||||
#:module-path module-path
|
||||
#:extensions extensions
|
||||
#:guile guile-for-build
|
||||
#:deprecation-warnings
|
||||
deprecation-warnings)
|
||||
@ -704,6 +734,7 @@ (define (graphs-file-names graphs)
|
||||
`("-L" ,(derivation->output-path modules)
|
||||
"-C" ,(derivation->output-path compiled))
|
||||
'())
|
||||
,@(append-map extension-flags exts)
|
||||
,builder)
|
||||
#:outputs outputs
|
||||
#:env-vars env-vars
|
||||
@ -713,6 +744,7 @@ (define (graphs-file-names graphs)
|
||||
,@(if modules
|
||||
`((,modules) (,compiled) ,@inputs)
|
||||
inputs)
|
||||
,@(map list exts)
|
||||
,@(match graphs
|
||||
(((_ . inputs) ...) inputs)
|
||||
(_ '())))
|
||||
@ -861,6 +893,17 @@ (define-syntax-rule (with-imported-modules modules body ...)
|
||||
(identifier-syntax modules)))
|
||||
body ...))
|
||||
|
||||
(define-syntax-parameter current-imported-extensions
|
||||
;; Current list of extensions.
|
||||
(identifier-syntax '()))
|
||||
|
||||
(define-syntax-rule (with-extensions extensions body ...)
|
||||
"Mark the gexps defined in BODY... as requiring EXTENSIONS in their
|
||||
execution environment."
|
||||
(syntax-parameterize ((current-imported-extensions
|
||||
(identifier-syntax extensions)))
|
||||
body ...))
|
||||
|
||||
(define-syntax gexp
|
||||
(lambda (s)
|
||||
(define (collect-escapes exp)
|
||||
@ -957,6 +1000,7 @@ (define (substitute-references exp substs)
|
||||
(refs (map escape->ref escapes)))
|
||||
#`(make-gexp (list #,@refs)
|
||||
current-imported-modules
|
||||
current-imported-extensions
|
||||
(lambda #,formals
|
||||
#,sexp)))))))
|
||||
|
||||
@ -1071,12 +1115,21 @@ (define* (compiled-modules modules
|
||||
(system (%current-system))
|
||||
(guile (%guile-for-build))
|
||||
(module-path %load-path)
|
||||
(extensions '())
|
||||
(deprecation-warnings #f))
|
||||
"Return a derivation that builds a tree containing the `.go' files
|
||||
corresponding to MODULES. All the MODULES are built in a context where
|
||||
they can refer to each other."
|
||||
(define total (length modules))
|
||||
|
||||
(define build-utils-hack?
|
||||
;; To avoid a full rebuild, we limit the fix below to the case where
|
||||
;; MODULE-PATH is different from %LOAD-PATH. This happens when building
|
||||
;; modules for 'compute-guix-derivation' upon 'guix pull'. TODO: Make
|
||||
;; this unconditional on the next rebuild cycle.
|
||||
(and (member '(guix build utils) modules)
|
||||
(not (equal? module-path %load-path))))
|
||||
|
||||
(mlet %store-monad ((modules (imported-modules modules
|
||||
#:system system
|
||||
#:guile guile
|
||||
@ -1122,7 +1175,47 @@ (define (process-directory directory output processed)
|
||||
(setvbuf (current-output-port)
|
||||
(cond-expand (guile-2.2 'line) (else _IOLBF)))
|
||||
|
||||
(ungexp-splicing
|
||||
(if build-utils-hack?
|
||||
(gexp ((define mkdir-p
|
||||
;; Capture 'mkdir-p'.
|
||||
(@ (guix build utils) mkdir-p))))
|
||||
'()))
|
||||
|
||||
;; Add EXTENSIONS to the search path.
|
||||
;; TODO: Remove the outer 'ungexp-splicing' on the next rebuild cycle.
|
||||
(ungexp-splicing
|
||||
(if (null? extensions)
|
||||
'()
|
||||
(gexp ((set! %load-path
|
||||
(append (map (lambda (extension)
|
||||
(string-append extension
|
||||
"/share/guile/site/"
|
||||
(effective-version)))
|
||||
'((ungexp-native-splicing extensions)))
|
||||
%load-path))
|
||||
(set! %load-compiled-path
|
||||
(append (map (lambda (extension)
|
||||
(string-append extension "/lib/guile/"
|
||||
(effective-version)
|
||||
"/site-ccache"))
|
||||
'((ungexp-native-splicing extensions)))
|
||||
%load-compiled-path))))))
|
||||
|
||||
(set! %load-path (cons (ungexp modules) %load-path))
|
||||
|
||||
(ungexp-splicing
|
||||
(if build-utils-hack?
|
||||
;; Above we loaded our own (guix build utils) but now we may
|
||||
;; need to load a compile a different one. Thus, force a
|
||||
;; reload.
|
||||
(gexp ((let ((utils (ungexp
|
||||
(file-append modules
|
||||
"/guix/build/utils.scm"))))
|
||||
(when (file-exists? utils)
|
||||
(load utils)))))
|
||||
'()))
|
||||
|
||||
(mkdir (ungexp output))
|
||||
(chdir (ungexp modules))
|
||||
(process-directory "." (ungexp output) 0))))
|
||||
@ -1154,20 +1247,34 @@ (define (default-guile)
|
||||
(module-ref (resolve-interface '(gnu packages guile))
|
||||
'guile-2.2))
|
||||
|
||||
(define* (load-path-expression modules #:optional (path %load-path))
|
||||
(define* (load-path-expression modules #:optional (path %load-path)
|
||||
#:key (extensions '()))
|
||||
"Return as a monadic value a gexp that sets '%load-path' and
|
||||
'%load-compiled-path' to point to MODULES, a list of module names. MODULES
|
||||
are searched for in PATH."
|
||||
(mlet %store-monad ((modules (imported-modules modules
|
||||
#:module-path path))
|
||||
(compiled (compiled-modules modules
|
||||
#:extensions extensions
|
||||
#:module-path path)))
|
||||
(return (gexp (eval-when (expand load eval)
|
||||
(set! %load-path
|
||||
(cons (ungexp modules) %load-path))
|
||||
(cons (ungexp modules)
|
||||
(append (map (lambda (extension)
|
||||
(string-append extension
|
||||
"/share/guile/site/"
|
||||
(effective-version)))
|
||||
'((ungexp-native-splicing extensions)))
|
||||
%load-path)))
|
||||
(set! %load-compiled-path
|
||||
(cons (ungexp compiled)
|
||||
%load-compiled-path)))))))
|
||||
(append (map (lambda (extension)
|
||||
(string-append extension
|
||||
"/lib/guile/"
|
||||
(effective-version)
|
||||
"/site-ccache"))
|
||||
'((ungexp-native-splicing extensions)))
|
||||
%load-compiled-path))))))))
|
||||
|
||||
(define* (gexp->script name exp
|
||||
#:key (guile (default-guile))
|
||||
@ -1176,7 +1283,9 @@ (define* (gexp->script name exp
|
||||
imported modules in its search path. Look up EXP's modules in MODULE-PATH."
|
||||
(mlet %store-monad ((set-load-path
|
||||
(load-path-expression (gexp-modules exp)
|
||||
module-path)))
|
||||
module-path
|
||||
#:extensions
|
||||
(gexp-extensions exp))))
|
||||
(gexp->derivation name
|
||||
(gexp
|
||||
(call-with-output-file (ungexp output)
|
||||
@ -1205,35 +1314,38 @@ (define* (gexp->file name exp #:key
|
||||
When SET-LOAD-PATH? is true, emit code in the resulting file to set
|
||||
'%load-path' and '%load-compiled-path' to honor EXP's imported modules.
|
||||
Lookup EXP's modules in MODULE-PATH."
|
||||
(match (if set-load-path? (gexp-modules exp) '())
|
||||
(() ;zero modules
|
||||
(gexp->derivation name
|
||||
(gexp
|
||||
(call-with-output-file (ungexp output)
|
||||
(lambda (port)
|
||||
(for-each (lambda (exp)
|
||||
(write exp port))
|
||||
'(ungexp (if splice?
|
||||
exp
|
||||
(gexp ((ungexp exp)))))))))
|
||||
#:local-build? #t
|
||||
#:substitutable? #f))
|
||||
((modules ...)
|
||||
(mlet %store-monad ((set-load-path (load-path-expression modules
|
||||
module-path)))
|
||||
(gexp->derivation name
|
||||
(gexp
|
||||
(call-with-output-file (ungexp output)
|
||||
(lambda (port)
|
||||
(write '(ungexp set-load-path) port)
|
||||
(for-each (lambda (exp)
|
||||
(write exp port))
|
||||
'(ungexp (if splice?
|
||||
exp
|
||||
(gexp ((ungexp exp)))))))))
|
||||
#:module-path module-path
|
||||
#:local-build? #t
|
||||
#:substitutable? #f)))))
|
||||
(define modules (gexp-modules exp))
|
||||
(define extensions (gexp-extensions exp))
|
||||
|
||||
(if (or (not set-load-path?)
|
||||
(and (null? modules) (null? extensions)))
|
||||
(gexp->derivation name
|
||||
(gexp
|
||||
(call-with-output-file (ungexp output)
|
||||
(lambda (port)
|
||||
(for-each (lambda (exp)
|
||||
(write exp port))
|
||||
'(ungexp (if splice?
|
||||
exp
|
||||
(gexp ((ungexp exp)))))))))
|
||||
#:local-build? #t
|
||||
#:substitutable? #f)
|
||||
(mlet %store-monad ((set-load-path
|
||||
(load-path-expression modules module-path
|
||||
#:extensions extensions)))
|
||||
(gexp->derivation name
|
||||
(gexp
|
||||
(call-with-output-file (ungexp output)
|
||||
(lambda (port)
|
||||
(write '(ungexp set-load-path) port)
|
||||
(for-each (lambda (exp)
|
||||
(write exp port))
|
||||
'(ungexp (if splice?
|
||||
exp
|
||||
(gexp ((ungexp exp)))))))))
|
||||
#:module-path module-path
|
||||
#:local-build? #t
|
||||
#:substitutable? #f))))
|
||||
|
||||
(define* (text-file* name #:rest text)
|
||||
"Return as a monadic value a derivation that builds a text file containing
|
||||
|
@ -1,5 +1,5 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
@ -19,6 +19,7 @@
|
||||
(define-module (guix man-db)
|
||||
#:use-module (guix zlib)
|
||||
#:use-module ((guix build utils) #:select (find-files))
|
||||
#:use-module (gdbm) ;gdbm-ffi
|
||||
#:use-module (srfi srfi-9)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (ice-9 match)
|
||||
@ -44,9 +45,6 @@ (define-module (guix man-db)
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
;; Load 'gdbm-ffi' at run time to simplify the job of 'imported-modules' & co.
|
||||
(module-autoload! (current-module) '(gdbm) '(gdbm-open GDBM_WRCREAT))
|
||||
|
||||
(define-record-type <mandb-entry>
|
||||
(mandb-entry file-name name section synopsis kind)
|
||||
mandb-entry?
|
||||
|
@ -1196,41 +1196,39 @@ (define modules
|
||||
|
||||
(define build
|
||||
(with-imported-modules modules
|
||||
#~(begin
|
||||
(add-to-load-path (string-append #$gdbm-ffi "/share/guile/site/"
|
||||
(effective-version)))
|
||||
(with-extensions (list gdbm-ffi) ;for (guix man-db)
|
||||
#~(begin
|
||||
(use-modules (guix man-db)
|
||||
(guix build utils)
|
||||
(srfi srfi-1)
|
||||
(srfi srfi-19))
|
||||
|
||||
(use-modules (guix man-db)
|
||||
(guix build utils)
|
||||
(srfi srfi-1)
|
||||
(srfi srfi-19))
|
||||
(define (compute-entries)
|
||||
(append-map (lambda (directory)
|
||||
(let ((man (string-append directory "/share/man")))
|
||||
(if (directory-exists? man)
|
||||
(mandb-entries man)
|
||||
'())))
|
||||
'#$(manifest-inputs manifest)))
|
||||
|
||||
(define (compute-entries)
|
||||
(append-map (lambda (directory)
|
||||
(let ((man (string-append directory "/share/man")))
|
||||
(if (directory-exists? man)
|
||||
(mandb-entries man)
|
||||
'())))
|
||||
'#$(manifest-inputs manifest)))
|
||||
(define man-directory
|
||||
(string-append #$output "/share/man"))
|
||||
|
||||
(define man-directory
|
||||
(string-append #$output "/share/man"))
|
||||
(mkdir-p man-directory)
|
||||
|
||||
(mkdir-p man-directory)
|
||||
|
||||
(format #t "Creating manual page database...~%")
|
||||
(force-output)
|
||||
(let* ((start (current-time))
|
||||
(entries (compute-entries))
|
||||
(_ (write-mandb-database (string-append man-directory
|
||||
"/index.db")
|
||||
entries))
|
||||
(duration (time-difference (current-time) start)))
|
||||
(format #t "~a entries processed in ~,1f s~%"
|
||||
(length entries)
|
||||
(+ (time-second duration)
|
||||
(* (time-nanosecond duration) (expt 10 -9))))
|
||||
(force-output)))))
|
||||
(format #t "Creating manual page database...~%")
|
||||
(force-output)
|
||||
(let* ((start (current-time))
|
||||
(entries (compute-entries))
|
||||
(_ (write-mandb-database (string-append man-directory
|
||||
"/index.db")
|
||||
entries))
|
||||
(duration (time-difference (current-time) start)))
|
||||
(format #t "~a entries processed in ~,1f s~%"
|
||||
(length entries)
|
||||
(+ (time-second duration)
|
||||
(* (time-nanosecond duration) (expt 10 -9))))
|
||||
(force-output))))))
|
||||
|
||||
(gexp->derivation "manual-database" build
|
||||
|
||||
|
@ -63,22 +63,25 @@ (define (print-record-abi-mismatch-error port key args
|
||||
(set-exception-printer! 'record-abi-mismatch-error
|
||||
print-record-abi-mismatch-error)
|
||||
|
||||
(define (current-abi-identifier type)
|
||||
"Return an identifier unhygienically derived from TYPE for use as its
|
||||
\"current ABI\" variable."
|
||||
(let ((type-name (syntax->datum type)))
|
||||
(datum->syntax
|
||||
type
|
||||
(string->symbol
|
||||
(string-append "% " (symbol->string type-name)
|
||||
" abi-cookie")))))
|
||||
(eval-when (expand load eval)
|
||||
;; The procedures below are needed both at run time and at expansion time.
|
||||
|
||||
(define (abi-check type cookie)
|
||||
"Return syntax that checks that the current \"application binary
|
||||
(define (current-abi-identifier type)
|
||||
"Return an identifier unhygienically derived from TYPE for use as its
|
||||
\"current ABI\" variable."
|
||||
(let ((type-name (syntax->datum type)))
|
||||
(datum->syntax
|
||||
type
|
||||
(string->symbol
|
||||
(string-append "% " (symbol->string type-name)
|
||||
" abi-cookie")))))
|
||||
|
||||
(define (abi-check type cookie)
|
||||
"Return syntax that checks that the current \"application binary
|
||||
interface\" (ABI) for TYPE is equal to COOKIE."
|
||||
(with-syntax ((current-abi (current-abi-identifier type)))
|
||||
#`(unless (eq? current-abi #,cookie)
|
||||
(throw 'record-abi-mismatch-error #,type))))
|
||||
(with-syntax ((current-abi (current-abi-identifier type)))
|
||||
#`(unless (eq? current-abi #,cookie)
|
||||
(throw 'record-abi-mismatch-error #,type)))))
|
||||
|
||||
(define-syntax make-syntactic-constructor
|
||||
(syntax-rules ()
|
||||
|
@ -340,28 +340,25 @@ (define json
|
||||
guile-json))
|
||||
|
||||
(define build
|
||||
(with-imported-modules `(,@(source-module-closure '((guix docker))
|
||||
#:select? not-config?)
|
||||
(guix build store-copy)
|
||||
((guix config) => ,config))
|
||||
#~(begin
|
||||
;; Guile-JSON is required by (guix docker).
|
||||
(add-to-load-path
|
||||
(string-append #+json "/share/guile/site/"
|
||||
(effective-version)))
|
||||
;; Guile-JSON is required by (guix docker).
|
||||
(with-extensions (list json)
|
||||
(with-imported-modules `(,@(source-module-closure '((guix docker))
|
||||
#:select? not-config?)
|
||||
(guix build store-copy)
|
||||
((guix config) => ,config))
|
||||
#~(begin
|
||||
(use-modules (guix docker) (srfi srfi-19) (guix build store-copy))
|
||||
|
||||
(use-modules (guix docker) (srfi srfi-19) (guix build store-copy))
|
||||
(setenv "PATH" (string-append #$archiver "/bin"))
|
||||
|
||||
(setenv "PATH" (string-append #$archiver "/bin"))
|
||||
|
||||
(build-docker-image #$output
|
||||
(call-with-input-file "profile"
|
||||
read-reference-graph)
|
||||
#$profile
|
||||
#:system (or #$target (utsname:machine (uname)))
|
||||
#:symlinks '#$symlinks
|
||||
#:compressor '#$(compressor-command compressor)
|
||||
#:creation-time (make-time time-utc 0 1)))))
|
||||
(build-docker-image #$output
|
||||
(call-with-input-file "profile"
|
||||
read-reference-graph)
|
||||
#$profile
|
||||
#:system (or #$target (utsname:machine (uname)))
|
||||
#:symlinks '#$symlinks
|
||||
#:compressor '#$(compressor-command compressor)
|
||||
#:creation-time (make-time time-utc 0 1))))))
|
||||
|
||||
(gexp->derivation (string-append name ".tar"
|
||||
(compressor-extension compressor))
|
||||
|
@ -393,9 +393,11 @@ (define (seconds->string seconds)
|
||||
"~Y-~m-~d ~H:~M")))
|
||||
|
||||
(define* (profile-boot-parameters #:optional (profile %system-profile)
|
||||
(numbers (generation-numbers profile)))
|
||||
"Return a list of 'boot-parameters' for the generations of PROFILE specified by
|
||||
NUMBERS, which is a list of generation numbers."
|
||||
(numbers
|
||||
(reverse (generation-numbers profile))))
|
||||
"Return a list of 'boot-parameters' for the generations of PROFILE specified
|
||||
by NUMBERS, which is a list of generation numbers. The list is ordered from
|
||||
the most recent to the oldest profiles."
|
||||
(define (system->boot-parameters system number time)
|
||||
(unless-file-not-found
|
||||
(let* ((params (read-boot-parameters-file system))
|
||||
|
@ -82,6 +82,8 @@ (define specification->package
|
||||
("guile-json" (ref '(gnu packages guile) 'guile-json))
|
||||
("guile-ssh" (ref '(gnu packages ssh) 'guile-ssh))
|
||||
("guile-git" (ref '(gnu packages guile) 'guile-git))
|
||||
("guile-gdbm-ffi" (ref '(gnu packages guile) 'guile-gdbm-ffi))
|
||||
("guile-sqlite3" (ref '(gnu packages guile) 'guile-sqlite3))
|
||||
("libgcrypt" (ref '(gnu packages gnupg) 'libgcrypt))
|
||||
("zlib" (ref '(gnu packages compression) 'zlib))
|
||||
("gzip" (ref '(gnu packages compression) 'gzip))
|
||||
@ -92,6 +94,8 @@ (define specification->package
|
||||
("guile2.0-json" (ref '(gnu packages guile) 'guile2.0-json))
|
||||
("guile2.0-ssh" (ref '(gnu packages ssh) 'guile2.0-ssh))
|
||||
("guile2.0-git" (ref '(gnu packages guile) 'guile2.0-git))
|
||||
("guile2.0-gdbm-ffi" (ref '(gnu packages guile) 'guile2.0-gdbm-ffi))
|
||||
;; XXX: No "guile2.0-sqlite3".
|
||||
(_ #f)))) ;no such package
|
||||
|
||||
|
||||
@ -215,12 +219,23 @@ (define guile-git
|
||||
"guile-git"
|
||||
"guile2.0-git"))
|
||||
|
||||
(define guile-gdbm-ffi
|
||||
(package-for-guile guile-version
|
||||
"guile-gdbm-ffi"
|
||||
"guile2.0-gdbm-ffi"))
|
||||
|
||||
|
||||
(define guile-sqlite3
|
||||
(package-for-guile guile-version
|
||||
"guile-sqlite3"
|
||||
"guile2.0-sqlite3"))
|
||||
|
||||
(define dependencies
|
||||
(match (append-map (lambda (package)
|
||||
(cons (list "x" package)
|
||||
(package-transitive-inputs package)))
|
||||
(list guile-git guile-json guile-ssh))
|
||||
(package-transitive-propagated-inputs package)))
|
||||
(list guile-git guile-json guile-ssh
|
||||
guile-gdbm-ffi guile-sqlite3))
|
||||
(((labels packages _ ...) ...)
|
||||
packages)))
|
||||
|
||||
@ -573,7 +588,11 @@ (define (process-directory directory output)
|
||||
`(#:local-build? #f ;allow substitutes
|
||||
|
||||
;; Don't annoy people about _IONBF deprecation.
|
||||
#:env-vars (("GUILE_WARN_DEPRECATED" . "no")))))
|
||||
;; Initialize 'terminal-width' in (system repl debug)
|
||||
;; to a large-enough value to make backtrace more
|
||||
;; verbose.
|
||||
#:env-vars (("GUILE_WARN_DEPRECATED" . "no")
|
||||
("COLUMNS" . "200")))))
|
||||
|
||||
|
||||
;;;
|
||||
|
234
guix/store/database.scm
Normal file
234
guix/store/database.scm
Normal file
@ -0,0 +1,234 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017 Caleb Ristvedt <caleb.ristvedt@cune.org>
|
||||
;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;; 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 store database)
|
||||
#:use-module (sqlite3)
|
||||
#:use-module (guix config)
|
||||
#:use-module (guix serialization)
|
||||
#:use-module (guix store deduplication)
|
||||
#:use-module (guix base16)
|
||||
#:use-module (guix build syscalls)
|
||||
#:use-module (srfi srfi-11)
|
||||
#:use-module (srfi srfi-19)
|
||||
#:use-module (ice-9 match)
|
||||
#:export (sqlite-register
|
||||
register-path
|
||||
reset-timestamps))
|
||||
|
||||
;;; Code for working with the store database directly.
|
||||
|
||||
|
||||
(define-syntax-rule (with-database file db exp ...)
|
||||
"Open DB from FILE and close it when the dynamic extent of EXP... is left."
|
||||
(let ((db (sqlite-open file)))
|
||||
(dynamic-wind noop
|
||||
(lambda ()
|
||||
exp ...)
|
||||
(lambda ()
|
||||
(sqlite-close db)))))
|
||||
|
||||
(define (last-insert-row-id db)
|
||||
;; XXX: (sqlite3) currently lacks bindings for 'sqlite3_last_insert_rowid'.
|
||||
;; Work around that.
|
||||
(let* ((stmt (sqlite-prepare db "SELECT last_insert_rowid();"
|
||||
#:cache? #t))
|
||||
(result (sqlite-fold cons '() stmt)))
|
||||
(sqlite-finalize stmt)
|
||||
(match result
|
||||
((#(id)) id)
|
||||
(_ #f))))
|
||||
|
||||
(define path-id-sql
|
||||
"SELECT id FROM ValidPaths WHERE path = :path")
|
||||
|
||||
(define* (path-id db path)
|
||||
"If PATH exists in the 'ValidPaths' table, return its numerical
|
||||
identifier. Otherwise, return #f."
|
||||
(let ((stmt (sqlite-prepare db path-id-sql #:cache? #t)))
|
||||
(sqlite-bind-arguments stmt #:path path)
|
||||
(let ((result (sqlite-fold cons '() stmt)))
|
||||
(sqlite-finalize stmt)
|
||||
(match result
|
||||
((#(id) . _) id)
|
||||
(_ #f)))))
|
||||
|
||||
(define update-sql
|
||||
"UPDATE ValidPaths SET hash = :hash, registrationTime = :time, deriver =
|
||||
:deriver, narSize = :size WHERE id = :id")
|
||||
|
||||
(define insert-sql
|
||||
"INSERT INTO ValidPaths (path, hash, registrationTime, deriver, narSize)
|
||||
VALUES (:path, :hash, :time, :deriver, :size)")
|
||||
|
||||
(define* (update-or-insert db #:key path deriver hash nar-size time)
|
||||
"The classic update-if-exists and insert-if-doesn't feature that sqlite
|
||||
doesn't exactly have... they've got something close, but it involves deleting
|
||||
and re-inserting instead of updating, which causes problems with foreign keys,
|
||||
of course. Returns the row id of the row that was modified or inserted."
|
||||
(let ((id (path-id db path)))
|
||||
(if id
|
||||
(let ((stmt (sqlite-prepare db update-sql #:cache? #t)))
|
||||
(sqlite-bind-arguments stmt #:id id
|
||||
#:path path #:deriver deriver
|
||||
#:hash hash #:size nar-size #:time time)
|
||||
(sqlite-fold cons '() stmt)
|
||||
(sqlite-finalize stmt)
|
||||
(last-insert-row-id db))
|
||||
(let ((stmt (sqlite-prepare db insert-sql #:cache? #t)))
|
||||
(sqlite-bind-arguments stmt
|
||||
#:path path #:deriver deriver
|
||||
#:hash hash #:size nar-size #:time time)
|
||||
(sqlite-fold cons '() stmt) ;execute it
|
||||
(sqlite-finalize stmt)
|
||||
(last-insert-row-id db)))))
|
||||
|
||||
(define add-reference-sql
|
||||
"INSERT OR IGNORE INTO Refs (referrer, reference) SELECT :referrer, id
|
||||
FROM ValidPaths WHERE path = :reference")
|
||||
|
||||
(define (add-references db referrer references)
|
||||
"REFERRER is the id of the referring store item, REFERENCES is a list
|
||||
containing store items being referred to. Note that all of the store items in
|
||||
REFERENCES must already be registered."
|
||||
(let ((stmt (sqlite-prepare db add-reference-sql #:cache? #t)))
|
||||
(for-each (lambda (reference)
|
||||
(sqlite-reset stmt)
|
||||
(sqlite-bind-arguments stmt #:referrer referrer
|
||||
#:reference reference)
|
||||
(sqlite-fold cons '() stmt) ;execute it
|
||||
(sqlite-finalize stmt)
|
||||
(last-insert-row-id db))
|
||||
references)))
|
||||
|
||||
;; XXX figure out caching of statement and database objects... later
|
||||
(define* (sqlite-register #:key db-file path (references '())
|
||||
deriver hash nar-size)
|
||||
"Registers this stuff in a database specified by DB-FILE. PATH is the string
|
||||
path of some store item, REFERENCES is a list of string paths which the store
|
||||
item PATH refers to (they need to be already registered!), DERIVER is a string
|
||||
path of the derivation that created the store item PATH, HASH is the
|
||||
base16-encoded sha256 hash of the store item denoted by PATH (prefixed with
|
||||
\"sha256:\") after being converted to nar form, and nar-size is the size in
|
||||
bytes of the store item denoted by PATH after being converted to nar form."
|
||||
(with-database db-file db
|
||||
(let ((id (update-or-insert db #:path path
|
||||
#:deriver deriver
|
||||
#:hash hash
|
||||
#:nar-size nar-size
|
||||
#:time (time-second (current-time time-utc)))))
|
||||
(add-references db id references))))
|
||||
|
||||
|
||||
;;;
|
||||
;;; High-level interface.
|
||||
;;;
|
||||
|
||||
;; TODO: Factorize with that in (gnu build install).
|
||||
(define (reset-timestamps file)
|
||||
"Reset the modification time on FILE and on all the files it contains, if
|
||||
it's a directory."
|
||||
(let loop ((file file)
|
||||
(type (stat:type (lstat file))))
|
||||
(case type
|
||||
((directory)
|
||||
(utime file 0 0 0 0)
|
||||
(let ((parent file))
|
||||
(for-each (match-lambda
|
||||
(("." . _) #f)
|
||||
((".." . _) #f)
|
||||
((file . properties)
|
||||
(let ((file (string-append parent "/" file)))
|
||||
(loop file
|
||||
(match (assoc-ref properties 'type)
|
||||
((or 'unknown #f)
|
||||
(stat:type (lstat file)))
|
||||
(type type))))))
|
||||
(scandir* parent))))
|
||||
((symlink)
|
||||
;; FIXME: Implement bindings for 'futime' to reset the timestamps on
|
||||
;; symlinks.
|
||||
#f)
|
||||
(else
|
||||
(utime file 0 0 0 0)))))
|
||||
|
||||
;; TODO: make this canonicalize store items that are registered. This involves
|
||||
;; setting permissions and timestamps, I think. Also, run a "deduplication
|
||||
;; pass", whatever that involves. Also, handle databases not existing yet
|
||||
;; (what should the default behavior be? Figuring out how the C++ stuff
|
||||
;; currently does it sounds like a lot of grepping for global
|
||||
;; variables...). Also, return #t on success like the documentation says we
|
||||
;; should.
|
||||
|
||||
(define* (register-path path
|
||||
#:key (references '()) deriver prefix
|
||||
state-directory (deduplicate? #t))
|
||||
;; Priority for options: first what is given, then environment variables,
|
||||
;; then defaults. %state-directory, %store-directory, and
|
||||
;; %store-database-directory already handle the "environment variables /
|
||||
;; defaults" question, so we only need to choose between what is given and
|
||||
;; those.
|
||||
"Register PATH as a valid store file, with REFERENCES as its list of
|
||||
references, and DERIVER as its deriver (.drv that led to it.) If PREFIX is
|
||||
given, it must be the name of the directory containing the new store to
|
||||
initialize; if STATE-DIRECTORY is given, it must be a string containing the
|
||||
absolute file name to the state directory of the store being initialized.
|
||||
Return #t on success.
|
||||
|
||||
Use with care as it directly modifies the store! This is primarily meant to
|
||||
be used internally by the daemon's build hook."
|
||||
(let* ((db-dir (cond
|
||||
(state-directory
|
||||
(string-append state-directory "/db"))
|
||||
(prefix
|
||||
;; If prefix is specified, the value of NIX_STATE_DIR
|
||||
;; (which affects %state-directory) isn't supposed to
|
||||
;; affect db-dir, only the compile-time-customized
|
||||
;; default should.
|
||||
(string-append prefix %localstatedir "/guix/db"))
|
||||
(else
|
||||
%store-database-directory)))
|
||||
(store-dir (if prefix
|
||||
;; same situation as above
|
||||
(string-append prefix %storedir)
|
||||
%store-directory))
|
||||
(to-register (if prefix
|
||||
(string-append %storedir "/" (basename path))
|
||||
;; note: we assume here that if path is, for
|
||||
;; example, /foo/bar/gnu/store/thing.txt and prefix
|
||||
;; isn't given, then an environment variable has
|
||||
;; been used to change the store directory to
|
||||
;; /foo/bar/gnu/store, since otherwise real-path
|
||||
;; would end up being /gnu/store/thing.txt, which is
|
||||
;; probably not the right file in this case.
|
||||
path))
|
||||
(real-path (string-append store-dir "/" (basename path))))
|
||||
(let-values (((hash nar-size)
|
||||
(nar-sha256 real-path)))
|
||||
(reset-timestamps real-path)
|
||||
(sqlite-register
|
||||
#:db-file (string-append db-dir "/db.sqlite")
|
||||
#:path to-register
|
||||
#:references references
|
||||
#:deriver deriver
|
||||
#:hash (string-append "sha256:"
|
||||
(bytevector->base16-string hash))
|
||||
#:nar-size nar-size)
|
||||
|
||||
(when deduplicate?
|
||||
(deduplicate real-path hash #:store store-dir)))))
|
148
guix/store/deduplication.scm
Normal file
148
guix/store/deduplication.scm
Normal file
@ -0,0 +1,148 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017 Caleb Ristvedt <caleb.ristvedt@cune.org>
|
||||
;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;; 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/>.
|
||||
|
||||
;;; This houses stuff we do to files when they arrive at the store - resetting
|
||||
;;; timestamps, deduplicating, etc.
|
||||
|
||||
(define-module (guix store deduplication)
|
||||
#:use-module (guix hash)
|
||||
#:use-module (guix build utils)
|
||||
#:use-module (guix base16)
|
||||
#:use-module (srfi srfi-11)
|
||||
#:use-module (rnrs io ports)
|
||||
#:use-module (ice-9 ftw)
|
||||
#:use-module (guix serialization)
|
||||
#:export (nar-sha256
|
||||
deduplicate))
|
||||
|
||||
;; Would it be better to just make WRITE-FILE give size as well? I question
|
||||
;; the general utility of this approach.
|
||||
(define (counting-wrapper-port output-port)
|
||||
"Some custom ports don't implement GET-POSITION at all. But if we want to
|
||||
figure out how many bytes are being written, we will want to use that. So this
|
||||
makes a wrapper around a port which implements GET-POSITION."
|
||||
(let ((byte-count 0))
|
||||
(make-custom-binary-output-port "counting-wrapper"
|
||||
(lambda (bytes offset count)
|
||||
(set! byte-count
|
||||
(+ byte-count count))
|
||||
(put-bytevector output-port bytes
|
||||
offset count)
|
||||
count)
|
||||
(lambda ()
|
||||
byte-count)
|
||||
#f
|
||||
(lambda ()
|
||||
(close-port output-port)))))
|
||||
|
||||
(define (nar-sha256 file)
|
||||
"Gives the sha256 hash of a file and the size of the file in nar form."
|
||||
(let-values (((port get-hash) (open-sha256-port)))
|
||||
(let ((wrapper (counting-wrapper-port port)))
|
||||
(write-file file wrapper)
|
||||
(force-output wrapper)
|
||||
(force-output port)
|
||||
(let ((hash (get-hash))
|
||||
(size (port-position wrapper)))
|
||||
(close-port wrapper)
|
||||
(values hash size)))))
|
||||
|
||||
(define (tempname-in directory)
|
||||
"Gives an unused temporary name under DIRECTORY. Not guaranteed to still be
|
||||
unused by the time you create anything with that name, but a good shot."
|
||||
(let ((const-part (string-append directory "/.tmp-link-"
|
||||
(number->string (getpid)))))
|
||||
(let try ((guess-part
|
||||
(number->string (random most-positive-fixnum) 16)))
|
||||
(if (file-exists? (string-append const-part "-" guess-part))
|
||||
(try (number->string (random most-positive-fixnum) 16))
|
||||
(string-append const-part "-" guess-part)))))
|
||||
|
||||
(define* (get-temp-link target #:optional (link-prefix (dirname target)))
|
||||
"Like mkstemp!, but instead of creating a new file and giving you the name,
|
||||
it creates a new hardlink to TARGET and gives you the name. Since
|
||||
cross-filesystem hardlinks don't work, the temp link must be created on the
|
||||
same filesystem - where in that filesystem it is can be controlled by
|
||||
LINK-PREFIX."
|
||||
(let try ((tempname (tempname-in link-prefix)))
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
(link target tempname)
|
||||
tempname)
|
||||
(lambda (args)
|
||||
(if (= (system-error-errno args) EEXIST)
|
||||
(try (tempname-in link-prefix))
|
||||
(throw 'system-error args))))))
|
||||
|
||||
;; There are 3 main kinds of errors we can get from hardlinking: "Too many
|
||||
;; things link to this" (EMLINK), "this link already exists" (EEXIST), and
|
||||
;; "can't fit more stuff in this directory" (ENOSPC).
|
||||
|
||||
(define (replace-with-link target to-replace)
|
||||
"Atomically replace the file TO-REPLACE with a link to TARGET. Note: TARGET
|
||||
and TO-REPLACE must be on the same file system."
|
||||
(let ((temp-link (get-temp-link target (dirname to-replace))))
|
||||
(rename-file temp-link to-replace)))
|
||||
|
||||
(define-syntax-rule (false-if-system-error (errors ...) exp ...)
|
||||
"Given ERRORS, a list of system error codes to ignore, evaluates EXP... and
|
||||
return #f if any of the system error codes in the given list are thrown."
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
exp ...)
|
||||
(lambda args
|
||||
(if (member (system-error-errno args) (list errors ...))
|
||||
#f
|
||||
(apply throw args)))))
|
||||
|
||||
(define* (deduplicate path hash #:key (store %store-directory))
|
||||
"Check if a store item with sha256 hash HASH already exists. If so,
|
||||
replace PATH with a hardlink to the already-existing one. If not, register
|
||||
PATH so that future duplicates can hardlink to it. PATH is assumed to be
|
||||
under STORE."
|
||||
(let* ((links-directory (string-append store "/.links"))
|
||||
(link-file (string-append links-directory "/"
|
||||
(bytevector->base16-string hash))))
|
||||
(mkdir-p links-directory)
|
||||
(if (file-is-directory? path)
|
||||
;; Can't hardlink directories, so hardlink their atoms.
|
||||
(for-each (lambda (file)
|
||||
(unless (member file '("." ".."))
|
||||
(deduplicate file (nar-sha256 file)
|
||||
#:store store)))
|
||||
(scandir path))
|
||||
(if (file-exists? link-file)
|
||||
(false-if-system-error (EMLINK)
|
||||
(replace-with-link link-file path))
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
(link path link-file))
|
||||
(lambda args
|
||||
(let ((errno (system-error-errno args)))
|
||||
(cond ((= errno EEXIST)
|
||||
;; Someone else put an entry for PATH in
|
||||
;; LINKS-DIRECTORY before we could. Let's use it.
|
||||
(false-if-system-error (EMLINK)
|
||||
(replace-with-link path link-file)))
|
||||
((= errno ENOSPC)
|
||||
;; There's not enough room in the directory index for
|
||||
;; more entries in .links, but that's fine: we can
|
||||
;; just stop.
|
||||
#f)
|
||||
(else (apply throw args))))))))))
|
18
m4/guix.m4
18
m4/guix.m4
@ -174,6 +174,24 @@ AC_DEFUN([GUIX_CHECK_GUILE_SSH], [
|
||||
fi])
|
||||
])
|
||||
|
||||
dnl GUIX_CHECK_GUILE_SQLITE3
|
||||
dnl
|
||||
dnl Check whether a recent-enough Guile-Sqlite3 is available.
|
||||
AC_DEFUN([GUIX_CHECK_GUILE_SQLITE3], [
|
||||
dnl Check whether 'sqlite-bind-arguments' is available. It was introduced
|
||||
dnl in February 2018:
|
||||
dnl <https://notabug.org/civodul/guile-sqlite3/commit/1cd1dec96a9999db48c0ff45bab907efc637247f>.
|
||||
AC_CACHE_CHECK([whether Guile-Sqlite3 is available and recent enough],
|
||||
[guix_cv_have_recent_guile_sqlite3],
|
||||
[GUILE_CHECK([retval],
|
||||
[(@ (sqlite3) sqlite-bind-arguments)])
|
||||
if test "$retval" = 0; then
|
||||
guix_cv_have_recent_guile_sqlite3="yes"
|
||||
else
|
||||
guix_cv_have_recent_guile_sqlite3="no"
|
||||
fi])
|
||||
])
|
||||
|
||||
dnl GUIX_TEST_ROOT_DIRECTORY
|
||||
AC_DEFUN([GUIX_TEST_ROOT_DIRECTORY], [
|
||||
AC_CACHE_CHECK([for unit test root directory],
|
||||
|
@ -23,6 +23,7 @@ (define-module (test-gexp)
|
||||
#:use-module (guix grafts)
|
||||
#:use-module (guix derivations)
|
||||
#:use-module (guix packages)
|
||||
#:use-module (guix build-system trivial)
|
||||
#:use-module (guix tests)
|
||||
#:use-module ((guix build utils) #:select (with-directory-excursion))
|
||||
#:use-module ((guix utils) #:select (call-with-temporary-directory))
|
||||
@ -66,6 +67,27 @@ (define-syntax-rule (test-assertm name exp)
|
||||
(run-with-store %store exp
|
||||
#:guile-for-build (%guile-for-build))))
|
||||
|
||||
(define %extension-package
|
||||
;; Example of a package to use when testing 'with-extensions'.
|
||||
(dummy-package "extension"
|
||||
(build-system trivial-build-system)
|
||||
(arguments
|
||||
`(#:guile ,%bootstrap-guile
|
||||
#:modules ((guix build utils))
|
||||
#:builder
|
||||
(begin
|
||||
(use-modules (guix build utils))
|
||||
(let* ((out (string-append (assoc-ref %outputs "out")
|
||||
"/share/guile/site/"
|
||||
(effective-version))))
|
||||
(mkdir-p out)
|
||||
(call-with-output-file (string-append out "/hg2g.scm")
|
||||
(lambda (port)
|
||||
(write '(define-module (hg2g)
|
||||
#:export (the-answer))
|
||||
port)
|
||||
(write '(define the-answer 42) port)))))))))
|
||||
|
||||
|
||||
(test-begin "gexp")
|
||||
|
||||
@ -739,6 +761,54 @@ (define the-answer 42))
|
||||
(built-derivations (list drv))
|
||||
(return (= 42 (call-with-input-file out read))))))
|
||||
|
||||
(test-equal "gexp-extensions & ungexp"
|
||||
(list sed grep)
|
||||
((@@ (guix gexp) gexp-extensions)
|
||||
#~(foo #$(with-extensions (list grep) #~+)
|
||||
#+(with-extensions (list sed) #~-))))
|
||||
|
||||
(test-equal "gexp-extensions & ungexp-splicing"
|
||||
(list grep sed)
|
||||
((@@ (guix gexp) gexp-extensions)
|
||||
#~(foo #$@(list (with-extensions (list grep) #~+)
|
||||
(with-imported-modules '((foo))
|
||||
(with-extensions (list sed) #~-))))))
|
||||
|
||||
(test-equal "gexp-extensions and literal Scheme object"
|
||||
'()
|
||||
((@@ (guix gexp) gexp-extensions) #t))
|
||||
|
||||
(test-assertm "gexp->derivation & with-extensions"
|
||||
;; Create a fake Guile extension and make sure it is accessible both to the
|
||||
;; imported modules and to the derivation build script.
|
||||
(mlet* %store-monad
|
||||
((extension -> %extension-package)
|
||||
(module -> (scheme-file "x" #~( ;; splice!
|
||||
(define-module (foo)
|
||||
#:use-module (hg2g)
|
||||
#:export (multiply))
|
||||
|
||||
(define (multiply x)
|
||||
(* the-answer x)))
|
||||
#:splice? #t))
|
||||
(build -> (with-extensions (list extension)
|
||||
(with-imported-modules `((guix build utils)
|
||||
((foo) => ,module))
|
||||
#~(begin
|
||||
(use-modules (guix build utils)
|
||||
(hg2g) (foo))
|
||||
(call-with-output-file #$output
|
||||
(lambda (port)
|
||||
(write (list the-answer (multiply 2))
|
||||
port)))))))
|
||||
(drv (gexp->derivation "thingie" build
|
||||
;; %BOOTSTRAP-GUILE is 2.0.
|
||||
#:effective-version "2.0"))
|
||||
(out -> (derivation->output-path drv)))
|
||||
(mbegin %store-monad
|
||||
(built-derivations (list drv))
|
||||
(return (equal? '(42 84) (call-with-input-file out read))))))
|
||||
|
||||
(test-assertm "gexp->derivation #:references-graphs"
|
||||
(mlet* %store-monad
|
||||
((one (text-file "one" (random-text)))
|
||||
@ -948,6 +1018,22 @@ (define-public %stupid-thing ,text))
|
||||
(return (and (zero? (close-pipe pipe))
|
||||
(string=? text str))))))))))
|
||||
|
||||
(test-assertm "program-file & with-extensions"
|
||||
(let* ((exp (with-extensions (list %extension-package)
|
||||
(gexp (begin
|
||||
(use-modules (hg2g))
|
||||
(display the-answer)))))
|
||||
(file (program-file "program" exp
|
||||
#:guile %bootstrap-guile)))
|
||||
(mlet* %store-monad ((drv (lower-object file))
|
||||
(out -> (derivation->output-path drv)))
|
||||
(mbegin %store-monad
|
||||
(built-derivations (list drv))
|
||||
(let* ((pipe (open-input-pipe out))
|
||||
(str (get-string-all pipe)))
|
||||
(return (and (zero? (close-pipe pipe))
|
||||
(= 42 (string->number str)))))))))
|
||||
|
||||
(test-assertm "scheme-file"
|
||||
(let* ((text (plain-file "foo" "Hello, world!"))
|
||||
(scheme (scheme-file "bar" #~(list "foo" #$text))))
|
||||
|
@ -1,5 +1,5 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
@ -65,17 +65,17 @@ (define %tar-bootstrap %bootstrap-coreutils&co)
|
||||
#:archiver %tar-bootstrap))
|
||||
(check (gexp->derivation
|
||||
"check-tarball"
|
||||
#~(let ((guile (string-append "." #$profile "/bin")))
|
||||
#~(let ((bin (string-append "." #$profile "/bin")))
|
||||
(setenv "PATH"
|
||||
(string-append #$%tar-bootstrap "/bin"))
|
||||
(system* "tar" "xvf" #$tarball)
|
||||
(mkdir #$output)
|
||||
(exit
|
||||
(and (file-exists? (string-append guile "/guile"))
|
||||
(and (file-exists? (string-append bin "/guile"))
|
||||
(string=? (string-append #$%bootstrap-guile "/bin")
|
||||
(readlink guile))
|
||||
(string=? (string-append (string-drop guile 1)
|
||||
"/guile")
|
||||
(readlink bin))
|
||||
(string=? (string-append ".." #$profile
|
||||
"/bin/guile")
|
||||
(readlink "bin/Guile"))))))))
|
||||
(built-derivations (list check))))
|
||||
|
||||
|
54
tests/store-database.scm
Normal file
54
tests/store-database.scm
Normal file
@ -0,0 +1,54 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;; 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 (test-store-database)
|
||||
#:use-module (guix tests)
|
||||
#:use-module ((guix store) #:hide (register-path))
|
||||
#:use-module (guix store database)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:use-module (srfi srfi-64))
|
||||
|
||||
;; Test the (guix store database) module.
|
||||
|
||||
(define %store
|
||||
(open-connection-for-tests))
|
||||
|
||||
|
||||
(test-begin "store-database")
|
||||
|
||||
(test-assert "register-path"
|
||||
(let ((file (string-append (%store-prefix) "/" (make-string 32 #\f)
|
||||
"-fake")))
|
||||
(when (valid-path? %store file)
|
||||
(delete-paths %store (list file)))
|
||||
(false-if-exception (delete-file file))
|
||||
|
||||
(let ((ref (add-text-to-store %store "ref-of-fake" (random-text)))
|
||||
(drv (string-append file ".drv")))
|
||||
(call-with-output-file file
|
||||
(cut display "This is a fake store item.\n" <>))
|
||||
(register-path file
|
||||
#:references (list ref)
|
||||
#:deriver drv)
|
||||
|
||||
(and (valid-path? %store file)
|
||||
(equal? (references %store file) (list ref))
|
||||
(null? (valid-derivers %store file))
|
||||
(null? (referrers %store file))))))
|
||||
|
||||
(test-end "store-database")
|
64
tests/store-deduplication.scm
Normal file
64
tests/store-deduplication.scm
Normal file
@ -0,0 +1,64 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2018 Ludovic Courtès <ludo@gnu.org>
|
||||
;;;
|
||||
;;; 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 (test-store-deduplication)
|
||||
#:use-module (guix tests)
|
||||
#:use-module (guix store deduplication)
|
||||
#:use-module (guix hash)
|
||||
#:use-module ((guix utils) #:select (call-with-temporary-directory))
|
||||
#:use-module (guix build utils)
|
||||
#:use-module (rnrs bytevectors)
|
||||
#:use-module (ice-9 binary-ports)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (srfi srfi-64))
|
||||
|
||||
(test-begin "store-deduplication")
|
||||
|
||||
(test-equal "deduplicate"
|
||||
(cons* #t #f ;inode comparisons
|
||||
2 (make-list 5 6)) ;'nlink' values
|
||||
|
||||
(call-with-temporary-directory
|
||||
(lambda (store)
|
||||
(let ((data (string->utf8 "Hello, world!"))
|
||||
(identical (map (lambda (n)
|
||||
(string-append store "/" (number->string n)))
|
||||
(iota 5)))
|
||||
(unique (string-append store "/unique")))
|
||||
(for-each (lambda (file)
|
||||
(call-with-output-file file
|
||||
(lambda (port)
|
||||
(put-bytevector port data))))
|
||||
identical)
|
||||
(call-with-output-file unique
|
||||
(lambda (port)
|
||||
(put-bytevector port (string->utf8 "This is unique."))))
|
||||
|
||||
(for-each (lambda (file)
|
||||
(deduplicate file (sha256 data) #:store store))
|
||||
identical)
|
||||
(deduplicate unique (nar-sha256 unique) #:store store)
|
||||
|
||||
;; (system (string-append "ls -lRia " store))
|
||||
(cons* (apply = (map (compose stat:ino stat) identical))
|
||||
(= (stat:ino (stat unique))
|
||||
(stat:ino (stat (car identical))))
|
||||
(stat:nlink (stat unique))
|
||||
(map (compose stat:nlink stat) identical))))))
|
||||
|
||||
(test-end "store-deduplication")
|
Loading…
Reference in New Issue
Block a user