summaryrefslogtreecommitdiff
path: root/etc
diff options
context:
space:
mode:
Diffstat (limited to 'etc')
-rwxr-xr-xetc/committer.scm.in134
-rw-r--r--etc/completion/bash/guix117
-rw-r--r--etc/completion/fish/guix.fish2
-rw-r--r--etc/completion/zsh/_guix410
-rw-r--r--etc/disarchive-manifest.scm112
-rw-r--r--etc/guix-daemon.cil.in7
-rw-r--r--etc/guix-daemon.conf.in2
-rw-r--r--etc/guix-daemon.service.in3
-rw-r--r--etc/guix-gc.service.in20
-rw-r--r--etc/guix-gc.timer15
-rwxr-xr-xetc/guix-install.sh196
-rwxr-xr-xetc/indent-code.el3
-rw-r--r--etc/init.d/guix-daemon.in2
-rw-r--r--etc/news.scm195
-rw-r--r--etc/openrc/guix-daemon.in2
-rw-r--r--etc/release-manifest.scm25
-rw-r--r--etc/snippets/scheme-mode/guix-origin4
-rw-r--r--etc/source-manifest.scm66
-rw-r--r--etc/substitutes/bordeaux.guix.gnu.org.pub6
19 files changed, 1070 insertions, 251 deletions
diff --git a/etc/committer.scm.in b/etc/committer.scm.in
index 1f19ccfd6d..1ad83e37d7 100755
--- a/etc/committer.scm.in
+++ b/etc/committer.scm.in
@@ -4,6 +4,8 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2020, 2021 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2021 Sarah Morgensen <iskarian@mgsn.dev>
+;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -36,7 +38,43 @@
(ice-9 popen)
(ice-9 match)
(ice-9 rdelim)
- (ice-9 textual-ports))
+ (ice-9 regex)
+ (ice-9 textual-ports)
+ (guix gexp))
+
+(define* (break-string str #:optional (max-line-length 70))
+ "Break the string STR into lines that are no longer than MAX-LINE-LENGTH.
+Return a single string."
+ (define (restore-line words)
+ (string-join (reverse words) " "))
+ (if (<= (string-length str) max-line-length)
+ str
+ (let ((words+lengths (map (lambda (word)
+ (cons word (string-length word)))
+ (string-tokenize str))))
+ (match (fold (match-lambda*
+ (((word . length)
+ (count current lines))
+ (let ((new-count (+ count length 1)))
+ (if (< new-count max-line-length)
+ (list new-count
+ (cons word current)
+ lines)
+ (list length
+ (list word)
+ (cons (restore-line current) lines))))))
+ '(0 () ())
+ words+lengths)
+ ((_ last-words lines)
+ (string-join (reverse (cons (restore-line last-words) lines))
+ "\n"))))))
+
+(define* (break-string-with-newlines str #:optional (max-line-length 70))
+ "Break the lines of string STR into lines that are no longer than
+MAX-LINE-LENGTH. Return a single string."
+ (string-join (map (cut break-string <> max-line-length)
+ (string-split str #\newline))
+ "\n"))
(define (read-excursion port)
"Read an expression from PORT and reset the port position before returning
@@ -204,18 +242,19 @@ corresponding to the top-level definition containing the staged changes."
(added (lset-difference equal? new-values old-values)))
(format port
"[~a]: ~a~%" field
- (match (list (map symbol->string removed)
- (map symbol->string added))
- ((() added)
- (format #f "Add ~a."
- (listify added)))
- ((removed ())
- (format #f "Remove ~a."
- (listify removed)))
- ((removed added)
- (format #f "Remove ~a; add ~a."
- (listify removed)
- (listify added)))))))))
+ (break-string
+ (match (list (map symbol->string removed)
+ (map symbol->string added))
+ ((() added)
+ (format #f "Add ~a."
+ (listify added)))
+ ((removed ())
+ (format #f "Remove ~a."
+ (listify removed)))
+ ((removed added)
+ (format #f "Remove ~a; add ~a."
+ (listify removed)
+ (listify added))))))))))
'(inputs propagated-inputs native-inputs)))
(define* (add-commit-message file-name variable-name #:optional (port (current-output-port)))
@@ -224,6 +263,41 @@ corresponding to the top-level definition containing the staged changes."
"gnu: Add ~a.~%~%* ~a (~a): New variable.~%"
variable-name file-name variable-name))
+(define* (custom-commit-message file-name variable-name message changelog
+ #:optional (port (current-output-port)))
+ "Print custom commit message for a change to VARIABLE-NAME in FILE-NAME, using
+MESSAGE as the commit message and CHANGELOG as the body of the ChangeLog
+entry. If CHANGELOG is #f, the commit message is reused. If CHANGELOG already
+contains ': ', no colon is inserted between the location and body of the
+ChangeLog entry."
+ (define (trim msg)
+ (string-trim-right (string-trim-both msg) (char-set #\.)))
+
+ (define (changelog-has-location? changelog)
+ (->bool (string-match "^[[:graph:]]+:[[:blank:]]" changelog)))
+
+ (let* ((message (trim message))
+ (changelog (if changelog (trim changelog) message))
+ (message/f (format #f "gnu: ~a: ~a." variable-name message))
+ (changelog/f (if (changelog-has-location? changelog)
+ (format #f "* ~a (~a)~a."
+ file-name variable-name changelog)
+ (format #f "* ~a (~a): ~a."
+ file-name variable-name changelog))))
+ (format port
+ "~a~%~%~a~%"
+ (break-string-with-newlines message/f 72)
+ (break-string-with-newlines changelog/f 72))))
+
+(define (add-copyright-line line)
+ "Add the copyright line on LINE to the previous commit."
+ (let ((author (match:substring
+ (string-match "^\\+;;; Copyright ©[^[:alpha:]]+(.*)$" line)
+ 1)))
+ (format
+ (current-output-port) "Amend and add copyright line for ~a~%" author)
+ (system* "git" "commit" "--amend" "--no-edit")))
+
(define (group-hunks-by-sexp hunks)
"Return a list of pairs associating all hunks with the S-expression they are
modifying."
@@ -252,6 +326,15 @@ modifying."
(define %delay 1000)
(define (main . args)
+ (define* (change-commit-message* file-name old new #:rest rest)
+ (let ((changelog #f))
+ (match args
+ ((or (message changelog) (message))
+ (apply custom-commit-message
+ file-name (second old) message changelog rest))
+ (_
+ (apply change-commit-message file-name old new rest)))))
+
(match (diff-info)
(()
(display "Nothing to be done.\n" (current-error-port)))
@@ -297,18 +380,25 @@ modifying."
(error "Cannot apply")))
(usleep %delay))
hunks)
- (change-commit-message (hunk-file-name (first hunks))
- old new
- (current-output-port))
- (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-")))
- (change-commit-message (hunk-file-name (first hunks))
- old new
- port)
+ (define copyright-line
+ (any (lambda (line) (and=> (string-prefix? "+;;; Copyright ©" line)
+ (const line)))
+ (hunk-diff-lines (first hunks))))
+ (cond
+ (copyright-line
+ (add-copyright-line copyright-line))
+ (else
+ (let ((port (open-pipe* OPEN_WRITE "git" "commit" "-F" "-")))
+ (change-commit-message* (hunk-file-name (first hunks))
+ old new)
+ (change-commit-message* (hunk-file-name (first hunks))
+ old new
+ port)
(usleep %delay)
(unless (eqv? 0 (status:exit-val (close-pipe port)))
- (error "Cannot commit")))))
+ (error "Cannot commit")))))))
;; XXX: we recompute the hunks here because previous
;; insertions lead to offsets.
(new+old+hunks (diff-info)))))))
-(main)
+(apply main (cdr (command-line)))
diff --git a/etc/completion/bash/guix b/etc/completion/bash/guix
index 26480e5863..a9386e7794 100644
--- a/etc/completion/bash/guix
+++ b/etc/completion/bash/guix
@@ -1,5 +1,6 @@
# GNU Guix --- Functional package management for GNU
# Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+# Copyright © 2021 Tobias Geerinck-Rice <me@tobias.gr>
#
# This file is part of GNU Guix.
#
@@ -68,31 +69,29 @@ _guix_complete_installed_package ()
_guix_complete_option ()
{
- local subcommand
- case "${COMP_WORDS[2]}" in
- -*) subcommand="";;
- [a-z]*) subcommand="${COMP_WORDS[2]}";;
- esac
- local options="$(${COMP_WORDS[0]} ${COMP_WORDS[1]} $subcommand --help 2> /dev/null \
+ local command="${COMP_WORDS[$1]}"
+ local subcommand="${COMP_WORDS[$(($1 + 1))]}"
+ if _guix_is_option "$subcommand"
+ then
+ subcommand=""
+ fi
+ local options="$(${COMP_WORDS[0]} $command $subcommand --help 2> /dev/null \
| grep '^ \+-' \
| sed -e's/^.*--\([a-zA-Z0-9_-]\+\)\(=\?\).*/--\1\2/g')"
compopt -o nospace
- COMPREPLY=($(compgen -W "$options" -- "${COMP_WORDS[${#COMP_WORDS[*]} - 1]}"))
+ COMPREPLY=($(compgen -W "$options" -- "$2"))
}
-_guix_is_command ()
+_guix_is_option ()
{
- local word
- local result="false"
- for word in ${COMP_WORDS[*]}
- do
- if [ "$word" = "$1" ]
- then
- result=true
- break
- fi
- done
- $result
+ case "$1" in
+ -*)
+ true
+ ;;
+ *)
+ false
+ ;;
+ esac
}
_guix_is_removing ()
@@ -183,22 +182,43 @@ _guix_complete ()
local word_count=${#COMP_WORDS[*]}
local word_at_point="${COMP_WORDS[$COMP_CWORD]}"
- if [ "$COMP_CWORD" -gt 1 ]
- then
- case "$word_at_point" in
- -*)
- _guix_complete_option "$word_at_point"
- return
- ;;
- esac
- fi
+ # Find the innermost command at point, e.g. "build" in the case of
+ # "guix time-machine OPTIONS -- build<Tab>" -- but "time-machine" if
+ # point is moved before "build".
+ local command_index=0
+ local command
+ local word_index=0
+ local word
+ local expect_command="true"
+ while [[ $((++word_index)) -le COMP_CWORD ]]
+ do
+ word="${COMP_WORDS[$word_index]}"
+ if $expect_command
+ then
+ command_index=$word_index
+ command="$word"
+ expect_command="false"
+ continue
+ fi
+ if [[ "$word" = "--" ]]
+ then
+ case "$command" in
+ environment)
+ break
+ ;;
+ time-machine)
+ expect_command="true"
+ ;;
+ esac
+ fi
+ done
case $COMP_CWORD in
- 1)
+ $command_index)
_guix_complete_command
;;
*)
- if _guix_is_command "package"
+ if [[ "$command" = "package" ]]
then
if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p || _guix_is_dash_f
then
@@ -209,7 +229,7 @@ _guix_complete ()
else
_guix_complete_available_package "$word_at_point"
fi
- elif _guix_is_command "install"
+ elif [[ "$command" = "install" ]]
then
if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p
then
@@ -217,7 +237,7 @@ _guix_complete ()
else
_guix_complete_available_package "$word_at_point"
fi
- elif _guix_is_command "remove"
+ elif [[ "$command" = "remove" ]]
then
if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p
then
@@ -225,7 +245,7 @@ _guix_complete ()
else
_guix_complete_installed_package "$word_at_point"
fi
- elif _guix_is_command "upgrade"
+ elif [[ "$command" = "upgrade" ]]
then
if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p
then
@@ -233,7 +253,7 @@ _guix_complete ()
else
_guix_complete_installed_package "$word_at_point"
fi
- elif _guix_is_command "build"
+ elif [[ "$command" = "build" ]]
then
if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_f
then
@@ -241,51 +261,54 @@ _guix_complete ()
else
_guix_complete_available_package "$word_at_point"
fi
- elif _guix_is_command "environment"
+ elif [[ "$command" = "environment" ]]
then
if _guix_is_dash_L || _guix_is_dash_m || _guix_is_dash_p || _guix_is_dash_l
then
_guix_complete_file
+ elif _guix_is_option "$word_at_point"
+ then
+ _guix_complete_option "$command_index" "$word_at_point"
else
_guix_complete_available_package "$word_at_point"
fi
- elif _guix_is_command "download"
+ elif [[ "$command" = "download" ]]
then
_guix_complete_file
- elif _guix_is_command "system"
+ elif [[ "$command" = "system" ]]
then
case $COMP_CWORD in
2) _guix_complete_subcommand;;
*) _guix_complete_file;; # TODO: restrict to *.scm
esac
- elif _guix_is_command "pull"
+ elif [[ "$command" = "pull" ]]
then
if _guix_is_dash_C || _guix_is_dash_p
then
_guix_complete_file
fi
- elif _guix_is_command "time-machine"
+ elif [[ "$command" = "time-machine" ]]
then
if _guix_is_dash_C
then
_guix_complete_file
else
- _guix_complete_command
+ _guix_complete_option "$command_index" "$word_at_point"
fi
- elif _guix_is_command "container"
+ elif [[ "$command" = "container" ]]
then
case $COMP_CWORD in
2) _guix_complete_subcommand;;
3) _guix_complete_pid "$word_at_point";;
*) _guix_complete_file;;
esac
- elif _guix_is_command "import"
+ elif [[ "$command" = "import" ]]
then
_guix_complete_subcommand
- elif _guix_is_command "hash" || _guix_is_command "gc"
+ elif [[ "$command" = "hash" || "$command" = "gc" ]]
then
_guix_complete_file
- elif _guix_is_command "weather"
+ elif [[ "$command" = "weather" ]]
then
if _guix_is_dash_m
then
@@ -296,6 +319,12 @@ _guix_complete ()
fi
;;
esac
+
+ if [[ -z "$COMPREPLY" && COMP_CWORD -gt command_index ]] &&
+ _guix_is_option "$word_at_point"
+ then
+ _guix_complete_option "$command_index" "$word_at_point"
+ fi
}
complete -F _guix_complete guix
diff --git a/etc/completion/fish/guix.fish b/etc/completion/fish/guix.fish
index 422baab4bb..8d1a1eb1e9 100644
--- a/etc/completion/fish/guix.fish
+++ b/etc/completion/fish/guix.fish
@@ -322,8 +322,6 @@ complete -f -c guix -n '__fish_guix_needs_command' -a import -d 'Run IMPORTER wi
##### import gnu
complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a gnu -d 'Return a package declaration template for PACKAGE, a GNU package.'
complete -f -c guix -n '__fish_guix_using_command import; and __fish_seen_subcommand_from gnu' -a "--key-download=" -d 'handle missing OpenPGP keys according to POLICY: "always", "never", and "interactive", which is also used when "key-download" is not specified.'
-##### import nix
-complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a nix -d 'Import and convert the Nix expression ATTRIBUTE of NIXPKGS.'
##### import pypi
complete -f -c guix -n '__fish_guix_using_command import; and not __fish_seen_subcommand_from $remotecommands' -a pypi -d 'Import and convert the PyPI package for PACKAGE-NAME.'
##### import cpan
diff --git a/etc/completion/zsh/_guix b/etc/completion/zsh/_guix
index aa1a859e0d..bbc13c6ca1 100644
--- a/etc/completion/zsh/_guix
+++ b/etc/completion/zsh/_guix
@@ -2,6 +2,8 @@
#
# GNU Guix --- Functional package management for GNU
# Copyright © 2016 Eric Le Bihan <eric.le.bihan.dev@free.fr>
+# Copyright © 2021 Noah Evans <noah@nevans.me>
+# Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
#
# This file is part of GNU Guix.
#
@@ -68,21 +70,24 @@ _guix_list_installed_packages()
(( $+functions[_guix_build] )) || _guix_build()
{
_arguments \
- '--expression=[build the package matching EXPR]:EXPR' \
- '--file=[build the package matching code evaluated from FILE]:FILE:_files' \
- '--source[build the packages source derivations]' \
- '--sources=[build source derivations]:TYPE:(all package transitive)' \
- '--system=[attempt to build for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
+ {-e,--expression=}'[build the package or derivation EXPR evaluates to]:EXPR' \
+ {-f,--file=}'[build the package or derivation that the code within FILE evaluates to]:FILE:_files' \
+ {-m,--manifest=}'[build the packages that the manifest given in FILE evaluates to]:FILE:_files' \
+ {-S,--source}'[build the packages source derivations]' \
+ '--sources=[build source derivations]:TYPE:(package all transitive)' \
+ {-s,--system=}'[attempt to build for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
'--target=[cross-build for TRIPLET (e.g. "armel-linux-gnu")]:TRIPLET' \
- '--derivations[return the derivation paths of the given packages]' \
+ {-d,--derivations}'[return the derivation paths of the given packages]' \
'--check[rebuild items to check for non-determinism issues]' \
- '--root=[symlink result to FILE and register it as GC root]:FILE:_files' \
- '--quiet[do not show the build log]' \
+ '--repair[repair the specified items]' \
+ {-r,--root=}'[make FILE a symlink to the result, and register it as a GC root]:FILE:_files' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
+ {-q,--quiet}'[do not show the build log]' \
'--log-file[return the log file names for the given derivations]' \
- '--load-path=[prepend DIR to the package module search path]:DIR:_dirs' \
- '--keep-failed[keep build tree of failed builds]' \
- '--keep-going[keep going when some of the derivations fail]' \
- '--dry-run[do not build the derivations]' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -\' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
'--fallback[fall back to building when the substituter fails]' \
'--no-substitutes[build instead of resorting to pre-built substitutes]' \
'--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
@@ -90,12 +95,12 @@ _guix_list_installed_packages()
'--no-offload[do not attempt to offload builds]' \
'--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
'--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
- '--verbosity=[use the given verbosity LEVEL]:LEVEL' \
'--rounds=[build N times in a row to detect non-determinism]:N' \
- '--cores=[allow the use of up to N CPU cores for the build]:N' \
- '--max-jobs=[allow at most N build jobs]:N' \
- '--with-source=[use SOURCE when building the corresponding package]:SOURCE' \
- '--with-input=[replace dependency PACKAGE by REPLACEMENT]:PACKAGE=REPLACEMENT' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ '--help-transform[list package transformation options not shown here]' \
+ {-V,--version}'[display version information and exit]' \
'*:package:->packages'
if [[ "$state" = packages ]]; then
@@ -107,7 +112,10 @@ _guix_list_installed_packages()
(( $+functions[_guix_challenge] )) || _guix_challenge()
{
_arguments \
- '--substitute-urls=[fetch substitute from URLS if they are authorized]:URL:_urls' \
+ '--substitute-urls=[compare build results with those at URLS]:URLS:_urls' \
+ '--diff=[show differences according to MODE]:MODE' \
+ {-v,--verbose}'[show details about successful comparisons]' \
+ {-V,--version}'[display version information and exit]' \
'*:package:->packages'
if [[ "$state" = packages ]]; then
@@ -126,7 +134,11 @@ _guix_list_installed_packages()
(( $+functions[_guix_download] )) || _guix_download()
{
_arguments \
- '--format=[write the hash in the given format]:FMT:(nix-base32 base16 base32 hex)' \
+ {-f,--format=}'[write the hash in the given format]:FMT:(nix-base32 base16 base32 hex)' \
+ {-H,--hash=}'[use the given hash ALGORITHM]:ALGORITHM' \
+ '--no-check-certificate[do not validate the certificate of HTTPS servers ]' \
+ {-o,--output=}'[download to FILE]:FILE:_files' \
+ {-V,--version}'[display version information and exit]' \
'1:URL:_urls'
}
@@ -139,21 +151,29 @@ _guix_list_installed_packages()
(( $+functions[_guix_environment] )) || _guix_environment()
{
_arguments \
- '--expression=[create environment for the package evaluated from EXPR]:EXPR' \
- '--load=[create environment for the package evaluated from FILE]:FILE:_files' \
- '--ad-hoc[include all specified packages, not only their inputs]' \
+ {-e,--expression=}'[create environment for the package that EXPR evaluates to]:EXPR' \
+ {-l,--load=}'[create environment for the package that the code within FILE evaluates to]:FILE:_files' \
+ {-m,--manifest=}'[create environment with the manifest from FILE]:FILE:_files' \
+ {-p,--profile=}'[create environment from profile at PATH]:PATH:_files -/' \
+ '--ad-hoc[include all specified packages in the environment instead of only their inputs]' \
'--pure[unset existing environment variables]' \
+ {-E,--preserve=}'[preserve environment variables that match REGEXP]:REGEXP' \
'--search-paths[display needed environment variable definitions]' \
- '--system=[attempt to build for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
- '--container[run command within an isolated container]' \
- '--network[allow containers to access the network]' \
- '--share=[share writable host file system according to SPEC]:SPEC' \
- '--expose=[expose read-only host file system according to SPEC]:SPEC' \
+ {-s,--system=}'[attempt to build for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
+ {-r,--root=}'[make FILE a symlink to the result, and register it as a GC root]:FILE:_files' \
+ {-C,--container}'[run command within an isolated container]' \
+ {-N,--network}'[allow containers to access the network]' \
+ {-P,--link-profile}'[link environment profile to ~/.guix-profile within an isolated container]' \
+ {-u,--user=}'[instead of copying the name and home of the current user into an isolated container, use the name USER with home directory /home/USER]:USER:_users' \
+ '--no-cwd[do not share current working directory with an isolated container]' \
+ '--share=[for containers, share writable host file system according to SPEC]:SPEC' \
+ '--expose=[for containers, expose read-only host file system according to SPEC]:SPEC' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
'--bootstrap[use bootstrap binaries to build the environment]' \
- '--load-path=[prepend DIR to the package module search path]:DIR:_dirs' \
- '--keep-failed[keep build tree of failed builds]' \
- '--keep-going[keep going when some of the derivations fail]' \
- '--dry-run[do not build the derivations]' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
'--fallback[fall back to building when the substituter fails]' \
'--no-substitutes[build instead of resorting to pre-built substitutes]' \
'--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
@@ -161,10 +181,12 @@ _guix_list_installed_packages()
'--no-offload[do not attempt to offload builds]' \
'--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
'--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
- '--verbosity=[use the given verbosity LEVEL]:LEVEL' \
'--rounds=[build N times in a row to detect non-determinism]:N' \
- '--cores=[allow the use of up to N CPU cores for the build]:N' \
- '--max-jobs=[allow at most N build jobs]:N' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ '--help-transform[list package transformation options not shown here]' \
+ {-V,--version}'[display version information and exit]' \
'*:package:->packages'
if [[ "$state" = packages ]]; then
@@ -177,27 +199,39 @@ _guix_list_installed_packages()
(( $+functions[_guix_gc] )) || _guix_gc()
{
_arguments \
- '--collect-garbage=[collect at least MIN bytes of garbage]:MIN' \
- '--free-space=[attempt to reach FREE available space in the store]:FREE' \
- '--delete[attempt to delete PATHS]' \
+ {-C,--collect-garbage=}'[collect at least MIN bytes of garbage]:MIN' \
+ {-F,--free-space=}'[attempt to reach FREE available space in the store]:FREE' \
+ {-d,--delete-generations=}'[delete profile generations matching PATTERN]:PATTERN' \
+ {-D,--delete}'[attempt to delete PATHS]' \
+ '--list-roots[list the users GC roots]' \
+ '--list-busy[list store items used by running processes]' \
'--optimize[optimize the store by deduplicating identical files]' \
'--list-dead[list dead paths]' \
'--list-live[list live paths]' \
'--references[list the references of PATHS]' \
- '--requisites[list the requisites of PATHS]' \
+ {-R,--requisites}'[list the requisites of PATHS]' \
'--referrers[list the referrers of PATHS]' \
+ '--derivers[list the derivers of PATHS]' \
'--verify=[verify the integrity of the store]:OPTS:(contents repair)' \
'--list-failures[list cached build failures]' \
'--clear-failures[remove PATHS from the set of cached failures]' \
- '1:PATH:_dirs'
+ {-V,--version}'[display version information and exit]:V' \
+ '1:PATH:_files -/'
}
(( $+functions[_guix_graph] )) || _guix_graph()
{
_arguments \
- '--type=[represent nodes of the given TYPE]:TYPE:->types' \
+ {-b,--backend=}'[produce a graph with the given backend TYPE]:TYPE:->types' \
+ '--list-backends[list the available graph backends]' \
+ {-t,--type=}'[represent nodes of the given TYPE]:TYPE:->types' \
'--list-types[list the available graph types]' \
- '--expression=[consider the package EXPR evaluates to]:EXPR' \
+ '--path[display the shortest path between the given nodes]' \
+ {-e,--expression=}'[consider the package EXPR evaluates to]:EXPR' \
+ {-s,--system=}'[consider the graph for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ '--help-transform[list package transformation options not shown here]' \
+ {-V,--version}'[display version information and exit]' \
'1:PACKAGE:->packages'
case "$state" in
@@ -216,14 +250,18 @@ _guix_list_installed_packages()
(( $+functions[_guix_hash] )) || _guix_hash()
{
_arguments \
- '--format=[write the hash in the given format]:FMT:(nix-base32 base16 base32 hex)' \
- '--recursive[compute the hash on FILE recursively]'\
+ {-x,--exclude-vcs}'[exclude version control directories]' \
+ {-H,--hash=}'[use the given hash ALGORITHM]:ALGORITHM' \
+ {-f,--format=}'[write the hash in the given format]:FMT:(nix-base32 base16 base32 hex)' \
+ {-r,--recursive}'[compute the hash on FILE recursively]' \
+ {-V,--version}'[display version information and exit]' \
'1:FILE:_files'
}
(( $+functions[_guix_import] )) || _guix_import()
{
_arguments \
+ {-V,--version}'[display version information and exit]' \
'1:IMPORTER:->importer' \
'*:args:'
@@ -236,8 +274,12 @@ _guix_list_installed_packages()
(( $+functions[_guix_lint] )) || _guix_lint()
{
_arguments \
- '--checkers=[only run the specified checkers]:CHECKERS:->checkers' \
- '--list-checkers[display the list of available lint checkers]' \
+ {-c,--checkers=}'[only run the specified checkers]:CHECKERS:->checkers' \
+ {-x,--exclude=}'[exclude the specified checkers]:CHECKERSS:->checkers' \
+ {-n,--no-network}'[only run checkers that do not access the network]' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-l,--list-checkers}'[display the list of available lint checkers]' \
+ {-V,--version}'[display version information and exit]' \
'1:PACKAGE:->packages'
case "$state" in
@@ -255,29 +297,32 @@ _guix_list_installed_packages()
(( $+functions[_guix_package] )) || _guix_package()
{
_arguments \
- '--install[install one or more packages]: :->install' \
- '--install-from-expression=[install the package EXP evaluates to]:EXP' \
- '--install-from-file=[install the package evaluated from FILE]:FILE:_files' \
- '--remove[remove one or more packages]: :->remove' \
- '--upgrade=[upgrade all the installed packages matching REGEXP]:REGEXP' \
- '--manifest=[create a new profile generation from FILE]:FILE:_files' \
+ {-i,--install}'[install one or more packages]: :->install' \
+ {-e,--install-from-expression=}'[install the package EXP evaluates to]:EXP' \
+ {-f,--install-from-file=}'[install the package evaluated from FILE]:FILE:_files' \
+ {-r,--remove}'[remove one or more packages]: :->remove' \
+ {-u,--upgrade=}'[upgrade all the installed packages matching REGEXP]:REGEXP' \
+ {-m,--manifest=}'[create a new profile generation from FILE]:FILE:_files' \
'--do-not-upgrade=[do not upgrade any packages matching REGEXP]:REGEXP' \
'--roll-back[roll back to the previous generation]' \
'--search-paths=[display needed environment variable definitions]:KINDS' \
- '--list-generations=[list generations matching PATTERN]:PATTERN' \
- '--delete-generations=[delete generations matching PATTERN]:PATTERN' \
- '--switch-generation=[switch to a generation matching PATTERN]:PATTERN' \
- '--profile=[use PROFILE instead of the default profile]:PROFILE' \
+ {-l,--list-generations=}'[list generations matching PATTERN]:PATTERN' \
+ {-d,--delete-generations=}'[delete generations matching PATTERN]:PATTERN' \
+ {-S,--switch-generation=}'[switch to a generation matching PATTERN]:PATTERN' \
+ '--export-manifest[print a manifest for the chosen profile]' \
+ '--export-channels[print channels for the chosen profile]' \
+ {-p,--profile}'[use PROFILE instead of the default profile]:PROFILE:_files -/' \
+ '--list-profiles[list the profiles]' \
+ '--allow-collisions[do not treat collisions in the profile as an error]' \
'--bootstrap[use the bootstrap Guile to build the profile]' \
- '--verbose[produce verbose output]' \
- '--search=[search in synopsis and description using REGEXP]:REGEXP' \
- '--list-installed=[list installed packages matching REGEXP]:REGEXP' \
- '--list-available=[list available packages matching REGEXP]:REGEXP' \
+ {-s,--search=}'[search in synopsis and description using REGEXP]:REGEXP' \
+ {-I,--list-installed=}'[list installed packages matching REGEXP]:REGEXP' \
+ {-A,--list-available=}'[list available packages matching REGEXP]:REGEXP' \
'--show=[show details about a package]: :->show' \
- '--load-path=[prepend DIR to the package module search path]:DIR:_dirs' \
- '--keep-failed[keep build tree of failed builds]' \
- '--keep-going[keep going when some of the derivations fail]' \
- '--dry-run[do not build the derivations]' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
'--fallback[fall back to building when the substituter fails]' \
'--no-substitutes[build instead of resorting to pre-built substitutes]' \
'--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
@@ -285,12 +330,13 @@ _guix_list_installed_packages()
'--no-offload[do not attempt to offload builds]' \
'--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
'--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
- '--verbosity=[use the given verbosity LEVEL]:LEVEL' \
'--rounds=[build N times in a row to detect non-determinism]:N' \
- '--cores=[allow the use of up to N CPU cores for the build]:N' \
- '--max-jobs=[allow at most N build jobs]:N' \
- '--with-source=[use SOURCE when building the corresponding package]:SOURCE' \
- '--with-input=[replace dependency PACKAGE by REPLACEMENT]:PACKAGE=REPLACEMENT'
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]' \
+ '--help-transform[list package transformation options not shown here]' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]' \
+ {-V,--version}'[display version information and exit]'
case "$state" in
install|show)
@@ -304,37 +350,165 @@ _guix_list_installed_packages()
esac
}
+(( $+functions[_guix_install] )) || _guix_install()
+{
+ _arguments \
+ {-p,--profile=}'[use PROFILE instead of the users default profile]:PROFILE:_files -/' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
+ '--fallback[fall back to building when the substituter fails]' \
+ '--no-substitutes[build instead of resorting to pre-built substitutes]' \
+ '--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
+ '--no-grafts[do not graft packages]' \
+ '--no-offload[do not attempt to offload builds]' \
+ '--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
+ '--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
+ '--rounds=[build N times in a row to detect non-determinism]:N' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ '--help-transform[list package transformation options not shown here]' \
+ {-V,--version}'[display version information and exit]' \
+ '*:package:->packages'
+
+ if [[ "$state" = packages ]]; then
+ _guix_list_available_packages
+ compadd -a -- _guix_available_packages
+ fi
+}
+
+(( $+functions[_guix_remove] )) || _guix_remove()
+{
+ _arguments \
+ {-p,--profile=}'[use PROFILE instead of the users default profile]:PROFILE:_files -/' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
+ '--fallback[fall back to building when the substituter fails]' \
+ '--no-substitutes[build instead of resorting to pre-built substitutes]' \
+ '--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
+ '--no-grafts[do not graft packages]' \
+ '--no-offload[do not attempt to offload builds]' \
+ '--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
+ '--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
+ '--rounds=[build N times in a row to detect non-determinism]:N' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ {-V,--version}'[display version information and exit]' \
+ '*:package:->packages'
+
+ if [[ "$state" = packages ]]; then
+ _guix_list_installed_packages
+ compadd -a -- _guix_installed_packages
+ fi
+}
+
+(( $+functions[_guix_upgrade] )) || _guix_upgrade()
+{
+ _arguments \
+ {-p,--profile=}'[use PROFILE instead of the users default profile]:PROFILE:_files -/' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
+ '--do-not-upgrade=[do not upgrade any packages matching REGEXP]:REGEXP' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
+ '--fallback[fall back to building when the substituter fails]' \
+ '--no-substitutes[build instead of resorting to pre-built substitutes]' \
+ '--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
+ '--no-grafts[do not graft packages]' \
+ '--no-offload[do not attempt to offload builds]' \
+ '--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
+ '--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
+ '--rounds=[build N times in a row to detect non-determinism]:N' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ '--help-transform[list package transformation options not shown here]' \
+ {-V,--version}'[display version information and exit]' \
+ '*:regexp'
+}
+
(( $+functions[_guix_publish] )) || _guix_publish()
{
_arguments \
- '--port=[listen on PORT]:PORT:' \
- '--listen=[listen on the network interface for HOST]:HOST:_hosts' \
- '--user=[change privileges to USER as soon as possible]:USER:_users' \
- '--compression=[compress archives at LEVEL]:LEVEL' \
+ {-p,--port=}'[listen on PORT]:PORT' \
+ '--listen=[listen on the network interface for HOST]:HOST_hosts' \
+ {-u,--user=}'[change privileges to USER as soon as possible]:USER_users' \
+ {-a,--advertise}'[advertise on the local network]' \
+ {-C,--compression=}'[compress archives with METHOD at LEVEL]:METHOD' \
+ {-c,--cache=}'[cache published items to DIRECTORY]:DIRECTORY:_files -/' \
+ '--cache-bypass-threshold=[serve store items below SIZE even when not cached]:SIZE' \
+ '--workers=[use N workers to bake items]:N' \
'--ttl=[announce narinfos can be cached for TTL seconds]:TTL' \
- '--repl=[spawn REPL server on PORT]:PORT'
+ '--negative-ttl=[announce missing narinfos can be cached for TTL seconds]:TTL' \
+ '--nar-path=[use PATH as the prefix for nar URLs]:PATH' \
+ '--public-key=[use FILE as the public key for signatures]:FILE:_files' \
+ '--private-key=[use FILE as the private key for signatures]:FILE:_files' \
+ {-r,--repl=}'[spawn REPL server on PORT]:PORT' \
+ {-V,--version}'[display version information and exit]' \
}
(( $+functions[_guix_pull] )) || _guix_pull()
{
_arguments \
- '--verbose[produce verbose output]' \
- '--url=[download the Guix tarball from URL]:URL:_urls' \
- '--bootstrap[use the bootstrap Guile to build the new Guix]'
+ {-C,--channels=}'[deploy the channels defined in FILE]:FILE:_files' \
+ '--url=[download from the Git repository at URL]:URL:_urls' \
+ '--commit=[download the specified COMMIT]:COMMIT' \
+ '--branch=[download the tip of the specified BRANCH]:BRANCH' \
+ '--allow-downgrades[allow downgrades to earlier channel revisions]' \
+ '--disable-authentication[disable channel authentication]' \
+ {-N,--news}'[display news compared to the previous generation]' \
+ {-l,--list-generations=}'[list generations matching PATTERN]:PATTERN' \
+ '--roll-back[roll back to the previous generation]' \
+ {-d,--delete-generations=}'[delete generations matching PATTERN]:PATTERN' \
+ {-S,--switch-generation=}'[switch to a generation matching PATTERN]:PATTERN' \
+ {-p,--profile=}'[use PROFILE instead of ~/.config/guix/current]:PROFILE:_files -/' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
+ {-s,--system=}'[attempt to build for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
+ '--bootstrap[use the bootstrap Guile to build the new Guix]' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
+ '--fallback[fall back to building when the substituter fails]' \
+ '--no-substitutes[build instead of resorting to pre-built substitutes]' \
+ '--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
+ '--no-grafts[do not graft packages]' \
+ '--no-offload[do not attempt to offload builds]' \
+ '--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
+ '--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
+ '--rounds=[build N times in a row to detect non-determinism]:N' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ {-V,--version}'[display version information and exit]'
}
(( $+functions[_guix_refresh] )) || _guix_refresh()
{
_arguments \
- '--expression=[consider the package EXPR evaluates to]:EXPR' \
- '--update[update source files in place]' \
- '--select=[select all the packages in SUBSET]:SUBSET:(core non-core)' \
- '--type=[restrict to updates from the specified updaters]:UPDATER:->updaters' \
- '--list-updaters[list available updaters and exit]' \
- '--list-dependent[list top-level dependent packages]' \
- '--key-server=[use HOST as the OpenPGP key server]:HOST:_hosts' \
+ {-e,--expression=}'[consider the package EXPR evaluates to]:EXPR' \
+ {-u,--update}'[update source files in place]' \
+ {-s,--select=}'[select all the packages in SUBSET, one of]:SUBSET:(core non-core)' \
+ {-m,--manifest=}'[select all the packages from the manifest in FILE]:FILE:_files' \
+ {-t,--type=}'[restrict to updates from the specified updaters]:UPDATER:-.updaters' \
+ {-L,--list-updaters}'[list available updaters and exit]' \
+ {-l,--list-dependent}'[list top-level dependent packages that would need to be rebuilt as a result of upgrading PACKAGE...]' \
+ {-r,--recursive}'[check the PACKAGE and its inputs for upgrades]' \
+ '--list-transitive[list all the packages that PACKAGE depends on]' \
+ '--keyring=[use FILE as the keyring of upstream OpenPGP keys]:FILE:_files' \
+ '--key-server=[use HOST as the OpenPGP key server]:HOST_hosts' \
'--gpg=[use COMMAND as the GnuPG 2.x command]:COMMAND' \
- '--key-download=[policy to handle missing OpenPGP keys]:POLICY:(always interactive never)' \
+ '--key-download=[handle missing OpenPGP keys according to POLICY:]:POLICY:(always interactive never)' \
+ '--load-path=[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-V,--version}'[display version information and exit]' \
'*:package:->packages'
case "$state" in
@@ -352,9 +526,12 @@ _guix_list_installed_packages()
(( $+functions[_guix_size] )) || _guix_size()
{
_arguments \
- '--substitute-urls=[fetch substitute from URLS if they are authorized]:URL:_urls' \
- '-system=[consider packages for SYSTEM--e.g., "i686-linux"]:SYSTEM' \
- '--map-file=[write to FILE a graphical map of disk usage]:FILE:_files' \
+ '--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
+ {-s,--system=}'[consider packages for SYSTEM (e.g. "i686-linux")]:SYSTEM' \
+ '--sort=[sort according to KEY]:KEY:(closure self)' \
+ {-m,--map-file=}'[write to FILE a graphical map of disk usage]:FILE:_files' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-V,--version}'[display version information and exit]' \
'*:package:->packages'
if [[ "$state" = packages ]]; then
@@ -366,28 +543,42 @@ _guix_list_installed_packages()
(( $+functions[_guix_system] )) || _guix_system()
{
_arguments \
- '--load-path=[prepend DIR to the package module search path]:DIR:_dirs' \
- '--keep-failed[keep build tree of failed builds]' \
- '--keep-going[keep going when some of the derivations fail]' \
- '--dry-run[do not build the derivations]' \
+ {-L,--load-path=}'[prepend DIR to the package module search path]:DIR:_files -/' \
+ {-K,--keep-failed}'[keep build tree of failed builds]' \
+ {-k,--keep-going}'[keep going when some of the derivations fail]' \
+ {-n,--dry-run}'[do not build the derivations]' \
'--fallback[fall back to building when the substituter fails]' \
'--no-substitutes[build instead of resorting to pre-built substitutes]' \
- '--substitute-urls=[fetch substitute from URLS if they are authorized]:URL:_urls' \
+ '--substitute-urls=[fetch substitute from URLS if they are authorized]:URLS:_urls' \
'--no-grafts[do not graft packages]' \
'--no-offload[do not attempt to offload builds]' \
'--max-silent-time=[mark the build as failed after SECONDS of silence]:SECONDS' \
'--timeout=[mark the build as failed after SECONDS of activity]:SECONDS' \
- '--verbosity=[use the given verbosity LEVEL]:LEVEL' \
'--rounds=[build N times in a row to detect non-determinism]:N' \
- '--cores=[allow the use of up to N CPU cores for the build]:N' \
- '--max-jobs=[allow at most N build jobs]:N' \
- '--derivation[return the derivation of the given system]' \
- '--on-error=[apply STRATEGY when an error occurs while reading FILE]:STRATEGY' \
- '--image-size=[for "image", produce an image of SIZE]:SIZE' \
- '--no-grub[for "init", do not install GRUB]' \
- '--share=[for "vm", share host file system according to SPEC]:SPEC' \
- '--expose=[for "vm", expose host file system according to SPEC]:SPEC' \
- '--full-boot[for "vm", make a full boot sequence]' \
+ {-c,--cores=}'[allow the use of up to N CPU cores for the build]:N' \
+ {-M,--max-jobs=}'[allow at most N build jobs]:N' \
+ '--debug=[produce debugging output at LEVEL]:LEVEL' \
+ {-d,--derivation}'[return the derivation of the given system]' \
+ {-e,--expression=}'[consider the operating-system EXPR evaluates to instead of reading FILE, when applicable]:EXPR' \
+ '--allow-downgrades[for reconfigure, allow downgrades to earlier channel revisions]' \
+ '--on-error=[apply STRATEGY when an error occurs while reading FILE]:STRATEGY:(nothing-special backtrace debug)' \
+ '--list-image-types[list available image types]' \
+ {-t,--image-type=}'[for image, produce an image of TYPE]:TYPE' \
+ '--image-size=[for image, produce an image of SIZE]:SIZE' \
+ '--no-bootloader[for init, do not install a bootloader]' \
+ '--volatile[for image, make the root file system volatile]' \
+ '--label=[for image, label disk image with LABEL]:LABEL' \
+ '--save-provenance[save provenance information]' \
+ '--share=[for vm and container, share host file system with read/write access according to SPEC]:SPEC' \
+ '--expose=[for vm and container, expose host file system directory as read-only according to SPEC]:SPEC' \
+ {-N,--network}'[for container, allow containers to access the network]' \
+ {-r,--root=}'[for vm, image, container and build, make FILE a symlink to the result, and register it as a GC root]:FILE:_files' \
+ '--full-boot[for vm, make a full boot sequence]' \
+ '--skip-checks[skip file system and initrd module safety checks]' \
+ '--target=[cross-build for TRIPLET (e.g. "armel-linux-gnu")]:TRIPLET' \
+ {-v,--verbosity=}'[use the given verbosity LEVEL]:LEVEL' \
+ '--graph-backend=[use BACKEND for extension-graphs and shepherd-graph]:BACKEND' \
+ {-V,--version}'[display version information and exit]' \
'1:action:->actions' \
'*:file:_files'
@@ -405,20 +596,35 @@ _guix_list_installed_packages()
"build:Build a given package"
"challenge:Challenge the substitutes for a package"
"container:Build and manipulate Linux containers"
+ "copy:Copy store items remotely over SSH"
+ "deploy:Deploy operating systems on a set of machines"
+ "describe:Describe the channel revisions currently used"
"download:Download the file at given URL and add it to the store"
"edit:Edit the definitions of a package"
"environment:Build an environment with a package and its dependencies"
"gc:Invoke the garbage collector"
+ "git:Operate on Git repositories"
"graph:Emit a DOT representation of the dependencies of a package"
"hash:Return the cryptographic hash of a file"
"import:Run an importer"
+ "install:Install packages"
"lint:Run a set of checkers on a package"
+ "offload:Set up and operate build offloading"
+ "pack:Create application bundles"
"package:Install, remove, or upgrade packages"
+ "processes:List currently running sessions"
"publish:Publish /gnu/store over HTTP."
"pull:Download and deploy the latest version of Guix"
"refresh:Update package definitions to match the latest version"
+ "remove:Remove packages"
+ "repl:Read-eval-print loop (REPL) for interactive programming"
+ "search:Search for packages"
+ "show:Show information about packages"
"size:Report the size of a package and its dependencies"
"system:Build the operating system"
+ "time-machine:Run commands from a different revision"
+ "upgrade:Upgrade packages"
+ "weather:Report on the availability of pre-built package binaries"
)
if (( CURRENT == 1 )); then
diff --git a/etc/disarchive-manifest.scm b/etc/disarchive-manifest.scm
new file mode 100644
index 0000000000..5cc59f5e2a
--- /dev/null
+++ b/etc/disarchive-manifest.scm
@@ -0,0 +1,112 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 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 file returns a manifest that builds a directory containing Disarchive
+;;; metadata for all the tarballs packages refer to.
+
+(use-modules (srfi srfi-1) (ice-9 match)
+ (guix packages) (guix gexp) (guix profiles)
+ (guix base16)
+ (gnu packages))
+
+(include "source-manifest.scm")
+
+(define (tarball-origin? origin)
+ (match (origin-actual-file-name origin)
+ (#f #f)
+ ((? string? file)
+ ;; As of version 0.2.1, Disarchive can only deal with raw tarballs and
+ ;; gzip-compressed tarballs.
+ (and (origin-hash origin)
+ (or (string-suffix? ".tar.gz" file)
+ (string-suffix? ".tgz" file)
+ (string-suffix? ".tar" file))))))
+
+(define (origin->disarchive origin)
+ "Return a directory containing Disarchive metadata for ORIGIN, a tarball, or
+an empty directory if ORIGIN could not be disassembled."
+ (define file-name
+ (let ((hash (origin-hash origin)))
+ (string-append (symbol->string (content-hash-algorithm hash))
+ "/"
+ (bytevector->base16-string
+ (content-hash-value hash)))))
+
+ (define disarchive
+ (specification->package "disarchive"))
+
+ (define build
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils)
+ (srfi srfi-34))
+
+ (define tarball
+ #+(upstream-origin origin))
+
+ (define file-name
+ (string-append #$output "/" #$file-name))
+
+ (define profile
+ #+(profile (content (packages->manifest (list disarchive)))))
+
+ (mkdir-p (dirname file-name))
+ (setenv "PATH" (string-append profile "/bin"))
+ (setenv "GUILE_LOAD_PATH"
+ (string-append profile "/share/guile/site/"
+ (effective-version)))
+ (setenv "GUILE_LOAD_COMPILED_PATH"
+ (string-append profile "/lib/guile/" (effective-version)
+ "/site-ccache"))
+
+ (guard (c ((invoke-error? c)
+ ;; Sometimes Disarchive fails with "could not find Gzip
+ ;; compressor". When that happens, produce an empty
+ ;; directory instead of failing.
+ (report-invoke-error c)
+ (delete-file file-name)))
+ (with-output-to-file file-name
+ (lambda ()
+ ;; Disarchive records the tarball name in its output. Thus,
+ ;; strip the hash from TARBALL.
+ (let ((short-name (strip-store-file-name tarball)))
+ (symlink tarball short-name)
+ (invoke "disarchive" "disassemble" short-name))))))))
+
+ (computed-file (match (origin-actual-file-name origin)
+ ((? string? str) (string-append str ".dis"))
+ (#f "anonymous-tarball.dis"))
+ build))
+
+(define (disarchive-collection origins)
+ "Return a directory containing all the Disarchive metadata for ORIGINS."
+ (directory-union "disarchive-collection"
+ (filter-map (lambda (origin)
+ (and (tarball-origin? origin)
+ (origin->disarchive origin)))
+ origins)
+ #:copy? #t))
+
+
+;; The manifest containing Disarchive data.
+(let ((origins (all-origins)))
+ (manifest
+ (list (manifest-entry
+ (name "disarchive-collection")
+ (version (length origins))
+ (item (disarchive-collection origins))))))
diff --git a/etc/guix-daemon.cil.in b/etc/guix-daemon.cil.in
index 4f52157354..c9f4e3186d 100644
--- a/etc/guix-daemon.cil.in
+++ b/etc/guix-daemon.cil.in
@@ -301,7 +301,7 @@
open read write)))
(allow guix_daemon_t
guix_daemon_conf_t
- (lnk_file (create getattr rename unlink)))
+ (lnk_file (create getattr rename unlink read)))
(allow guix_daemon_t net_conf_t
(file (getattr open read)))
(allow guix_daemon_t net_conf_t
@@ -328,6 +328,9 @@
(allow guix_daemon_t
cache_home_t
(dir (search)))
+ (allow guix_daemon_t
+ cache_home_t
+ (lnk_file (getattr read)))
;; self upgrades
(allow guix_daemon_t
@@ -340,7 +343,7 @@
;; Socket operations
(allow guix_daemon_t
guix_daemon_socket_t
- (sock_file (unlink)))
+ (sock_file (unlink write)))
(allow guix_daemon_t
init_t
(fd (use)))
diff --git a/etc/guix-daemon.conf.in b/etc/guix-daemon.conf.in
index 755192d555..fb681d1f80 100644
--- a/etc/guix-daemon.conf.in
+++ b/etc/guix-daemon.conf.in
@@ -7,4 +7,4 @@ start on runlevel [2345]
stop on runlevel [016]
-exec @localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon --build-users-group=guixbuild
+exec @localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon --build-users-group=guixbuild --discover=no
diff --git a/etc/guix-daemon.service.in b/etc/guix-daemon.service.in
index 407cdd199c..17b54eaeb0 100644
--- a/etc/guix-daemon.service.in
+++ b/etc/guix-daemon.service.in
@@ -6,7 +6,8 @@
Description=Build daemon for GNU Guix
[Service]
-ExecStart=@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon --build-users-group=guixbuild
+ExecStart=@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon \
+ --build-users-group=guixbuild --discover=no
Environment='GUIX_LOCPATH=@localstatedir@/guix/profiles/per-user/root/guix-profile/lib/locale' LC_ALL=en_US.utf8
RemainAfterExit=yes
StandardOutput=syslog
diff --git a/etc/guix-gc.service.in b/etc/guix-gc.service.in
new file mode 100644
index 0000000000..2f1ca6584b
--- /dev/null
+++ b/etc/guix-gc.service.in
@@ -0,0 +1,20 @@
+# This is a "service unit file" for the systemd init system to perform a
+# one-shot 'guix gc' operation. It is meant to be triggered by a timer.
+# Drop it in /etc/systemd/system or similar together with 'guix-gc.timer'
+# to set it up.
+
+[Unit]
+Description=Discard unused Guix store items
+
+[Service]
+Type=oneshot
+# Customize the 'guix gc' arguments to fit your needs.
+ExecStart=@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix gc -d 1m -F 10G
+PrivateDevices=yes
+PrivateNetwork=yes
+PrivateUsers=no
+ProtectKernelTunables=yes
+ProtectKernelModules=yes
+ProtectControlGroups=yes
+MemoryDenyWriteExecute=yes
+SystemCallFilter=@default @file-system @basic-io @system-service
diff --git a/etc/guix-gc.timer b/etc/guix-gc.timer
new file mode 100644
index 0000000000..192132fbda
--- /dev/null
+++ b/etc/guix-gc.timer
@@ -0,0 +1,15 @@
+# This is a "timer unit file" for the systemd init system to trigger
+# 'guix-gc.service' periodically. Drop it in /etc/systemd/system or similar
+# together with 'guix-gc.service' to set it up.
+
+[Unit]
+Description=Discard unused Guix store items
+
+[Timer]
+OnCalendar=weekly
+AccuracySec=1h
+Persistent=true
+RandomizedDelaySec=6000
+
+[Install]
+WantedBy=timers.target
diff --git a/etc/guix-install.sh b/etc/guix-install.sh
index c84e7b7577..b0d4a8b95e 100755
--- a/etc/guix-install.sh
+++ b/etc/guix-install.sh
@@ -9,6 +9,7 @@
# Copyright © 2020 Daniel Brooks <db48x@db48x.net>
# Copyright © 2021 Jakub Kądziołka <kuba@kadziolka.net>
# Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
+# Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
#
# This file is part of GNU Guix.
#
@@ -64,12 +65,12 @@ INF="[ INFO ] "
DEBUG=0
GNU_URL="https://ftp.gnu.org/gnu/guix/"
#GNU_URL="https://alpha.gnu.org/gnu/guix/"
-OPENPGP_SIGNING_KEY_ID="3CE464558A84FDC69DB40CFB090B11993D9AEBB5"
-# This script needs to know where root's home directory is. However, we
-# cannot simply use the HOME environment variable, since there is no guarantee
-# that it points to root's home directory.
-ROOT_HOME="$(echo ~root)"
+# The following associative array holds set of GPG keys used to sign the
+# releases, keyed by their corresponding Savannah user ID.
+declare -A GPG_SIGNING_KEYS
+GPG_SIGNING_KEYS[15145]=3CE464558A84FDC69DB40CFB090B11993D9AEBB5 # ludo
+GPG_SIGNING_KEYS[127547]=27D586A4F8900854329FF09F1260E46482E63562 # maxim
# ------------------------------------------------------------------------------
#+UTILITIES
@@ -91,13 +92,25 @@ _debug()
fi
}
+# Return true if user answered yes, false otherwise.
+# $1: The prompt question.
+prompt_yes_no() {
+ while true; do
+ read -rp "$1 " yn
+ case $yn in
+ [Yy]*) return 0;;
+ [Nn]*) return 1;;
+ *) _msg "Please answer yes or no."
+ esac
+ done
+}
chk_require()
{ # Check that every required command is available.
declare -a warn
local c
- _debug "--- [ $FUNCNAME ] ---"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
for c in "$@"; do
command -v "$c" &>/dev/null || warn+=("$c")
@@ -112,29 +125,44 @@ chk_require()
chk_gpg_keyring()
{ # Check whether the Guix release signing public key is present.
- _debug "--- [ $FUNCNAME ] ---"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
+ local user_id
+ local gpg_key_id
+ local exit_flag
- # Without --dry-run this command will create a ~/.gnupg owned by root on
- # systems where gpg has never been used, causing errors and confusion.
- gpg --dry-run --list-keys ${OPENPGP_SIGNING_KEY_ID} >/dev/null 2>&1 || (
- _err "${ERR}Missing OpenPGP public key. Fetch it with this command:"
- echo " wget 'https://sv.gnu.org/people/viewgpg.php?user_id=15145' -qO - | sudo -i gpg --import -"
+ for user_id in "${!GPG_SIGNING_KEYS[@]}"; do
+ gpg_key_id=${GPG_SIGNING_KEYS[$user_id]}
+ # Without --dry-run this command will create a ~/.gnupg owned by root on
+ # systems where gpg has never been used, causing errors and confusion.
+ if ! gpg --dry-run --list-keys "$gpg_key_id" >/dev/null 2>&1; then
+ if prompt_yes_no "${INF}The following OpenPGP public key is \
+required to verify the Guix binary signature: $gpg_key_id.
+Would you like me to fetch it for you? (yes/no)"; then
+ wget "https://sv.gnu.org/people/viewgpg.php?user_id=$user_id" \
+ --no-verbose -O- | gpg --import -
+ else
+ _err "${ERR}Missing OpenPGP public key ($gpg_key_id).
+Fetch it with this command:
+
+ wget \"https://sv.gnu.org/people/viewgpg.php?user_id=$user_id\" -O - | \
+sudo -i gpg --import -"
+ exit_flag=yes
+ fi
+ fi
+ done
+ if [ "$exit_flag" = yes ]; then
exit 1
- )
+ fi
}
chk_term()
{ # Check for ANSI terminal for color printing.
- local ansi_term
-
if [ -t 2 ]; then
if [ "${TERM+set}" = 'set' ]; then
case "$TERM" in
xterm*|rxvt*|urxvt*|linux*|vt*|eterm*|screen*)
- ansi_term=true
;;
*)
- ansi_term=false
ERR="[ FAIL ] "
PAS="[ PASS ] "
;;
@@ -221,6 +249,16 @@ chk_sys_nscd()
fi
}
+# Configure substitute discovery according to user's preferences.
+# $1 is the installed service file to edit.
+configure_substitute_discovery() {
+ if grep -q -- '--discover=no' "$1" && \
+ prompt_yes_no "Would you like the Guix daemon to automatically \
+discover substitute servers on the local network? (yes/no)"; then
+ sed -i 's/--discover=no/--discover=yes/' "$1"
+ fi
+}
+
# ------------------------------------------------------------------------------
#+MAIN
@@ -231,10 +269,10 @@ guix_get_bin_list()
local latest_ver
local default_ver
- _debug "--- [ $FUNCNAME ] ---"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
# Filter only version and architecture
- bin_ver_ls=("$(wget -qO- "$gnu_url" \
+ bin_ver_ls=("$(wget "$gnu_url" --no-verbose -O- \
| sed -n -e 's/.*guix-binary-\([0-9.]*[a-z0-9]*\)\..*.tar.xz.*/\1/p' \
| sort -Vu)")
@@ -260,25 +298,25 @@ guix_get_bin()
local url="$1"
local bin_ver="$2"
local dl_path="$3"
+ local wget_args=()
- _debug "--- [ $FUNCNAME ] ---"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
_msg "${INF}Downloading Guix release archive"
- wget --help | grep -q '\--show-progress' && \
- _PROGRESS_OPT="-q --show-progress" || _PROGRESS_OPT=""
- wget $_PROGRESS_OPT -P "$dl_path" "${url}/${bin_ver}.tar.xz" "${url}/${bin_ver}.tar.xz.sig"
+ wget --help | grep -q '\--show-progress' \
+ && wget_args=("--no-verbose" "--show-progress")
- if [[ "$?" -eq 0 ]]; then
- _msg "${PAS}download completed."
+ if wget "${wget_args[@]}" -P "$dl_path" \
+ "${url}/${bin_ver}.tar.xz" "${url}/${bin_ver}.tar.xz.sig"; then
+ _msg "${PAS}download completed."
else
_err "${ERR}could not download ${url}/${bin_ver}.tar.xz."
exit 1
fi
pushd "${dl_path}" >/dev/null
- gpg --verify "${bin_ver}.tar.xz.sig" >/dev/null 2>&1
- if [[ "$?" -eq 0 ]]; then
+ if gpg --verify "${bin_ver}.tar.xz.sig" >/dev/null 2>&1; then
_msg "${PAS}Signature is valid."
popd >/dev/null
else
@@ -292,53 +330,57 @@ sys_create_store()
local pkg="$1"
local tmp_path="$2"
- _debug "--- [ $FUNCNAME ] ---"
-
- cd "$tmp_path"
- tar --extract \
- --file "$pkg" &&
- _msg "${PAS}unpacked archive"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
if [[ -e "/var/guix" || -e "/gnu" ]]; then
_err "${ERR}A previous Guix installation was found. Refusing to overwrite."
exit 1
- else
- _msg "${INF}Installing /var/guix and /gnu..."
- mv "${tmp_path}/var/guix" /var/
- mv "${tmp_path}/gnu" /
fi
+ cd "$tmp_path"
+ tar --extract --file "$pkg" && _msg "${PAS}unpacked archive"
+
+ _msg "${INF}Installing /var/guix and /gnu..."
+ mv "${tmp_path}/var/guix" /var/
+ mv "${tmp_path}/gnu" /
+
_msg "${INF}Linking the root user's profile"
- mkdir -p "${ROOT_HOME}/.config/guix"
+ mkdir -p "~root/.config/guix"
ln -sf /var/guix/profiles/per-user/root/current-guix \
- "${ROOT_HOME}/.config/guix/current"
+ "~root/.config/guix/current"
- GUIX_PROFILE="${ROOT_HOME}/.config/guix/current"
+ GUIX_PROFILE="~root/.config/guix/current"
+ # shellcheck disable=SC1090
source "${GUIX_PROFILE}/etc/profile"
- _msg "${PAS}activated root profile at ${ROOT_HOME}/.config/guix/current"
+ _msg "${PAS}activated root profile at ${GUIX_PROFILE}"
}
sys_create_build_user()
{ # Create the group and user accounts for build users.
- _debug "--- [ $FUNCNAME ] ---"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
- if [ $(getent group guixbuild) ]; then
+ if getent group guixbuild > /dev/null; then
_msg "${INF}group guixbuild exists"
else
groupadd --system guixbuild
_msg "${PAS}group <guixbuild> created"
fi
+ if getent group kvm > /dev/null; then
+ _msg "${INF}group kvm exists and build users will be added to it"
+ local KVMGROUP=,kvm
+ fi
+
for i in $(seq -w 1 10); do
if id "guixbuilder${i}" &>/dev/null; then
_msg "${INF}user is already in the system, reset"
- usermod -g guixbuild -G guixbuild \
+ usermod -g guixbuild -G guixbuild${KVMGROUP} \
-d /var/empty -s "$(which nologin)" \
-c "Guix build user $i" \
"guixbuilder${i}";
else
- useradd -g guixbuild -G guixbuild \
+ useradd -g guixbuild -G guixbuild${KVMGROUP} \
-d /var/empty -s "$(which nologin)" \
-c "Guix build user $i" --system \
"guixbuilder${i}";
@@ -354,7 +396,7 @@ sys_enable_guix_daemon()
local local_bin
local var_guix
- _debug "--- [ $FUNCNAME ] ---"
+ _debug "--- [ ${FUNCNAME[0]} ] ---"
info_path="/usr/local/share/info"
local_bin="/usr/local/bin"
@@ -363,8 +405,9 @@ sys_enable_guix_daemon()
case "$INIT_SYS" in
upstart)
{ initctl reload-configuration;
- cp "${ROOT_HOME}/.config/guix/current/lib/upstart/system/guix-daemon.conf" \
+ cp "~root/.config/guix/current/lib/upstart/system/guix-daemon.conf" \
/etc/init/ &&
+ configure_substitute_discovery /etc/init/guix-daemon.conf &&
start guix-daemon; } &&
_msg "${PAS}enabled Guix daemon via upstart"
;;
@@ -372,15 +415,15 @@ sys_enable_guix_daemon()
{ # systemd .mount units must be named after the target directory.
# Here we assume a hard-coded name of /gnu/store.
# XXX Work around <https://issues.guix.gnu.org/41356> until next release.
- if [ -f "${ROOT_HOME}/.config/guix/current/lib/systemd/system/gnu-store.mount" ]; then
- cp "${ROOT_HOME}/.config/guix/current/lib/systemd/system/gnu-store.mount" \
+ if [ -f "~root/.config/guix/current/lib/systemd/system/gnu-store.mount" ]; then
+ cp "~root/.config/guix/current/lib/systemd/system/gnu-store.mount" \
/etc/systemd/system/;
chmod 664 /etc/systemd/system/gnu-store.mount;
systemctl daemon-reload &&
systemctl enable gnu-store.mount;
fi
- cp "${ROOT_HOME}/.config/guix/current/lib/systemd/system/guix-daemon.service" \
+ cp "~root/.config/guix/current/lib/systemd/system/guix-daemon.service" \
/etc/systemd/system/;
chmod 664 /etc/systemd/system/guix-daemon.service;
@@ -394,6 +437,9 @@ sys_enable_guix_daemon()
-e 's/^Environment=\(.*\)$/Environment=\1 LC_ALL=en_US.UTF-8';
fi;
+ configure_substitute_discovery \
+ /etc/systemd/system/guix-daemon.service
+
systemctl daemon-reload &&
systemctl enable guix-daemon &&
systemctl start guix-daemon; } &&
@@ -401,10 +447,12 @@ sys_enable_guix_daemon()
;;
sysv-init)
{ mkdir -p /etc/init.d;
- cp "${ROOT_HOME}/.config/guix/current/etc/init.d/guix-daemon" \
+ cp "~root/.config/guix/current/etc/init.d/guix-daemon" \
/etc/init.d/guix-daemon;
chmod 775 /etc/init.d/guix-daemon;
+ configure_substitute_discovery /etc/init.d/guix-daemon
+
update-rc.d guix-daemon defaults &&
update-rc.d guix-daemon enable &&
service guix-daemon start; } &&
@@ -412,17 +460,19 @@ sys_enable_guix_daemon()
;;
openrc)
{ mkdir -p /etc/init.d;
- cp "${ROOT_HOME}/.config/guix/current/etc/openrc/guix-daemon" \
+ cp "~root/.config/guix/current/etc/openrc/guix-daemon" \
/etc/init.d/guix-daemon;
chmod 775 /etc/init.d/guix-daemon;
+ configure_substitute_discovery /etc/init.d/guix-daemon
+
rc-update add guix-daemon default &&
rc-service guix-daemon start; } &&
_msg "${PAS}enabled Guix daemon via OpenRC"
;;
NA|*)
_msg "${ERR}unsupported init system; run the daemon manually:"
- echo " ${ROOT_HOME}/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild"
+ echo " ~root/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild"
;;
esac
@@ -439,21 +489,18 @@ sys_enable_guix_daemon()
sys_authorize_build_farms()
{ # authorize the public key of the build farm
- while true; do
- read -p "Permit downloading pre-built package binaries from the project's build farm? (yes/no) " yn
- case $yn in
- [Yy]*) guix archive --authorize < "${ROOT_HOME}/.config/guix/current/share/guix/ci.guix.gnu.org.pub" &&
- _msg "${PAS}Authorized public key for ci.guix.gnu.org";
- break;;
- [Nn]*) _msg "${INF}Skipped authorizing build farm public keys"
- break;;
- *) _msg "Please answer yes or no.";
- esac
- done
+ if prompt_yes_no "Permit downloading pre-built package binaries from the \
+project's build farm? (yes/no)"; then
+ guix archive --authorize \
+ < "~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub" \
+ && _msg "${PAS}Authorized public key for ci.guix.gnu.org"
+ else
+ _msg "${INF}Skipped authorizing build farm public keys"
+ fi
}
sys_create_init_profile()
-{ # Create /etc/profile.d/guix.sh for better desktop integration
+{ # Define for better desktop integration
# This will not take effect until the next shell or desktop session!
[ -d "/etc/profile.d" ] || mkdir /etc/profile.d # Just in case
cat <<"EOF" > /etc/profile.d/guix.sh
@@ -470,7 +517,7 @@ export INFOPATH="$_GUIX_PROFILE/share/info:$INFOPATH"
GUIX_PROFILE="$HOME/.guix-profile"
[ -L $GUIX_PROFILE ] || return
GUIX_LOCPATH="$GUIX_PROFILE/lib/locale"
-export GUIX_PROFILE GUIX_LOCPATH
+export GUIX_LOCPATH
[ -f "$GUIX_PROFILE/etc/profile" ] && . "$GUIX_PROFILE/etc/profile"
@@ -527,7 +574,7 @@ This script installs GNU Guix on your system
https://www.gnu.org/software/guix/
EOF
echo -n "Press return to continue..."
- read -r ANSWER
+ read -r
}
main()
@@ -549,10 +596,19 @@ main()
umask 0022
tmp_path="$(mktemp -t -d guix.XXX)"
- guix_get_bin_list "${GNU_URL}"
- guix_get_bin "${GNU_URL}" "${BIN_VER}" "$tmp_path"
+ if [ -z "${GUIX_BINARY_FILE_NAME}" ]; then
+ guix_get_bin_list "${GNU_URL}"
+ guix_get_bin "${GNU_URL}" "${BIN_VER}" "$tmp_path"
+ GUIX_BINARY_FILE_NAME=${BIN_VER}.tar.xz
+ else
+ if ! [[ $GUIX_BINARY_FILE_NAME =~ $ARCH_OS ]]; then
+ _err "$ARCH_OS not in ${GUIX_BINARY_FILE_NAME}; aborting"
+ fi
+ _msg "${INF}Using manually provided binary ${GUIX_BINARY_FILE_NAME}"
+ GUIX_BINARY_FILE_NAME=$(realpath "$GUIX_BINARY_FILE_NAME")
+ fi
- sys_create_store "${BIN_VER}.tar.xz" "${tmp_path}"
+ sys_create_store "${GUIX_BINARY_FILE_NAME}" "${tmp_path}"
sys_create_build_user
sys_enable_guix_daemon
sys_authorize_build_farms
diff --git a/etc/indent-code.el b/etc/indent-code.el
index 84b15b356f..bdea8ee8bf 100755
--- a/etc/indent-code.el
+++ b/etc/indent-code.el
@@ -99,6 +99,8 @@
nil t)
(let ((indent-tabs-mode nil))
(beginning-of-defun)
+ (mark-sexp)
+ (untabify (point) (mark))
(indent-sexp)
(save-buffer)
(message "Done!"))
@@ -108,6 +110,7 @@
;; Indent all of FILE-NAME.
(find-file file-name)
(let ((indent-tabs-mode nil))
+ (untabify (point-min) (point-max))
(indent-region (point-min) (point-max))
(save-buffer)
(message "Done!")))
diff --git a/etc/init.d/guix-daemon.in b/etc/init.d/guix-daemon.in
index 1cc49fed89..b7d4bb72bb 100644
--- a/etc/init.d/guix-daemon.in
+++ b/etc/init.d/guix-daemon.in
@@ -36,7 +36,7 @@ start)
-E LC_ALL=en_US.utf8 \
-p "/var/run/guix-daemon.pid" \
@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon \
- --build-users-group=guixbuild
+ --build-users-group=guixbuild --discover=no
fi
;;
stop)
diff --git a/etc/news.scm b/etc/news.scm
index 65d83061df..47b4437426 100644
--- a/etc/news.scm
+++ b/etc/news.scm
@@ -14,6 +14,8 @@
;; Copyright © 2021 Zhu Zihao <all_but_last@163.com>
;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
+;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
+;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;
;; Copying and distribution of this file, with or without modification, are
;; permitted in any medium without royalty provided the copyright notice and
@@ -21,6 +23,199 @@
(channel-news
(version 0)
+(entry (commit "a2324d8b56eabf8117bca220a507cc791edffd2e")
+ (title
+ (en "Guix Home is a part of GNU Guix")
+ (de "Guix Home ist jetzt Teil von GNU Guix")
+ (ru "Guix Home теперь поставляется в составе GNU Guix"))
+ (body
+ (en "Guix Home splitted out from rde project and now is a part of
+Guix proper. It is available as a @emph{technology preview} and thus subject
+to change.
+
+The new @command{guix home} command with its actions allows users to
+manage their packages and configurations (aka. dotfiles) in a declarative way,
+similar to how many people manage their system with @command{guix system}.
+
+Take a look at available actions and arguments:
+@example
+guix home --help
+@end example
+
+See @command{info \"(guix) Home Configuration\"} for more information.")
+ (de "Guix Home ist aus dem rde-Projekt ins offizielle Guix übernommen
+worden. Es ist als @emph{Technologievorschau} bereits verfügbar, aber die
+Schnittstelle kann sich in Zukunft noch ändern.
+
+Der neue Befehl @command{guix home} ermöglicht es, die Pakete und
+Konfigurationsdateien (Dotfiles) für ein Benutzerkonto im deklarativen Stil zu
+verwalten. Es ist analog dazu, wie man @command{guix system} benutzen kann, um
+sein System zu verwalten.
+
+Werfen Sie einen Blick auf die verfügbaren Aktionen und Argumente:
+@example
+guix home --help
+@end example
+
+Führen Sie für mehr Informationen @command{info \"(guix) Home Configuration\"}
+aus.")
+ (ru "Guix Home отделился от проекта rde и теперь является частью
+Guix. Новая команда @command{guix home} даёт возможность пользователям
+управлять их пакетами и конфигурациями (дотфайлами) для них в декларативном
+стиле, аналогично тому, как многие люди управляют своими системами с помощью
+@command{guix system}.
+
+Чтобы получить список доступных действий и аргументов:
+@example
+guix home --help
+@end example
+
+Смотрите @command{info \"(guix) Home Configuration\"} для получения более
+детальных сведений.")))
+
+ (entry (commit "5b32ad4f6f555d305659cee825879df075b06331")
+ (title
+ (en "New @option{--max-depth} option for @command{guix graph}")
+ (de "Neue Option @option{--max-depth} für @command{guix graph}")
+ (fr "Nouvelle option @option{--max-depth} pour @command{guix graph}"))
+ (body
+ (en "The @command{guix graph} command has a new @option{--max-depth}
+(or @option{-M}) option, which allows you to restrict a graph to the given
+depth---very useful when visualizing large graphs. For example, the command
+below displays, using the @code{xdot} package, the dependency graph of
+LibreOffice, including only nodes that are at most at distance 2 of
+LibreOffice itself:
+
+@example
+guix graph -M 2 libreoffice | xdot -
+@end example
+
+See @command{info \"(guix) Invoking guix graph\"} for more information.")
+ (de "Der Befehl @command{guix graph} verfügt über eine neue
+Befehlszeilenoption @option{--max-depth} (oder @option{-M}), mit der
+Sie einen Graphen auf die angegebene Tiefe einschränken. Das ist vor
+allem bei großen Graphen nützlich; zum Beispiel zeigt der folgende
+Befehl, unter Verwendung des Pakets @code{xdot}, den
+Abhängigkeitsgraphen von LibreOffice unter Ausschluss der Knoten, die
+eine Distanz größer als 2 von LibreOffice selbst haben:
+
+@example
+guix graph -M 2 libreoffice | xdot -
+@end example
+
+Führen Sie @code{info \"(guix.de) Aufruf von guix graph\"} aus, um mehr zu
+erfahren.")
+ (fr "La commande @command{guix graph} dispose d'une nouvelle option
+@option{--max-depth} (ou @option{-M}) pour restreindre la profondeur d'un
+graphe---très utile pour visualiser des gros graphes. Par exemple, la
+commande ci-dessous affiche, en utilisant @code{xdot}, le graphe de dépendance
+de LibreOffice en n'incluant que les nœuds qui sont au plus à distance 2 de
+LibreOffice soi-même :
+
+@example
+guix graph -M 2 libreoffice | xdot -
+@end example
+
+Voir @command{info \"(guix.fr) Invoquer guix graph\"} pour plus
+d'informations.")))
+
+ (entry (commit "05f44c2d858a1e7b13c90362c35fa86bdc4d5a24")
+ (title
+ (en "Channel clones fall back to Software Heritage")
+ (de "Zum Klonen von Kanälen wird notfalls auf Software Heritage zurückgegriffen")
+ (fr "Les clones de canaux peuvent recourir à Software Heritage"))
+ (body
+ (en "When @command{guix time-machine} or @command{guix pull} fetches
+a channel pinned to a specific commit, it now automatically falls back to
+cloning it from the Software Heritage archive if the original URL is
+unreachable. This contributes to long-term reproducibility. See
+@command{info \"(guix) Replicating Guix\"}.
+
+Automatic fallback also works for other Git clones made on your behalf, such
+as when using @option{--with-commit} and related package transformation
+options.")
+ (de "Wenn bei @command{guix time-machine} oder @command{guix
+pull} ein bestimmter Commit eines Kanals bezogen werden soll, wird
+jetzt für den Fall, dass die ursprüngliche URL unerreichbar ist,
+automatisch vom Software-Heritage-Archiv geklont. Das trägt zur
+langfristigen Reproduzierbarkeit bei. Siehe @command{info \"(guix.de)
+Guix nachbilden\"}.
+
+Der automatische Rückgriff auf Software Heritage findet auch
+Verwendung bei anderen Arten von Git-Klon, die Guix durchführt, z.B.@:
+wenn Sie @option{--with-commit} und ähnliche Paketumwandlungsoptionen
+einsetzen.")
+ (fr "Quand la commande @command{guix time-machine} ou @command{guix
+pull} récupère un canal fixé à une révision spécifique, elle est maintenant
+capable de le cloner depuis l'archive Software Heritage si l'URL initiale
+n'est plus disponible. Cela contribue à la reproductibilité à long terme.
+Voir @command{info \"(guix.fr) Répliquer Guix\"}.
+
+Ce recours à Software Heritage fonctionne aussi pour les autres clones Git que
+Guix peut faire, comme lorsqu'on utilise @option{--with-commit} et les options
+de transformation de paquet similaires.")))
+
+ (entry (commit "82daab42811a2e3c7684ebdf12af75ff0fa67b99")
+ (title
+ (en "New @samp{deb} format for the @command{guix pack} command")
+ (de "Neues Format @samp{deb} für den Befehl @command{guix pack}"))
+ (body
+ (en "Debian archives (with the .deb file extension) can now be
+produced via the @command{guix pack --format=deb} command, providing an
+alternative distribution path for software built with Guix. Here is a simple
+example that generates a Debian archive for the @code{hello} package:
+
+@example
+guix pack --format=deb --symlink=/usr/bin/hello=bin/hello hello
+@end example
+
+See @command{info \"(guix) Invoking guix pack\"} for more information.")
+ (de "Debian-Archive (mit der Dateinamenserweiterung .deb) können
+jetzt auch mit dem Befehl @command{guix pack --format=deb} erzeugt werden, um
+mit Guix erstellte Software auf andere Art anzubieten. Hier sehen Sie ein
+einfaches Beispiel, wie ein Debian-Archiv für das Paket @code{hello} angelegt
+wird:
+
+@example
+guix pack --format=deb --symlink=/usr/bin/hello=bin/hello hello
+@end example
+
+Siehe @command{info \"(guix.de) Aufruf von guix pack\"} für mehr
+Informationen.")))
+
+ (entry (commit "bdc298ecee15283451d3aa20a849dd7bb22c8538")
+ (title
+ (en "New @command{guix import egg} command")
+ (de "Neuer Befehl @command{guix import egg}")
+ (zh "新的 @command{guix import egg} 命令"))
+ (body
+ (en "The new @command{guix import egg} command allows packagers to
+generate a package definition or a template thereof given the name of a
+CHICKEN egg package, like so:
+
+@example
+guix import egg sourcehut
+@end example
+
+Run @command{info \"(guix) Invoking guix import\"} for more info.")
+ (de "Mit dem neuen Befehl @command{guix import egg} können
+Paketautoren eine Paketdefinition oder eine Vorlage dafür anhand des Namens
+eines „Egg“-Pakets für CHICKEN erzeugen, etwa so:
+
+@example
+guix import egg sourcehut
+@end example
+
+Führen Sie @command{info \"(guix.de) Aufruf von guix import\"} aus, um mehr
+Informationen zu bekommen.")
+ (zh "新的 @command{guix import egg} 命令能让贡献者从一个CHICKEN egg生
+成一个包装或包装样板。
+
+@example
+guix import egg sourcehut
+@end example
+
+想了解更多可以运行 @command{info \"(guix) Invoking guix import\"}。")))
(entry (commit "2161820ebbbab62a5ce76c9101ebaec54dc61586")
(title
diff --git a/etc/openrc/guix-daemon.in b/etc/openrc/guix-daemon.in
index 110a58b88d..eeedc2a840 100644
--- a/etc/openrc/guix-daemon.in
+++ b/etc/openrc/guix-daemon.in
@@ -20,7 +20,7 @@
export GUIX_LOCPATH=@localstatedir@/guix/profiles/per-user/root/guix-profile/lib/locale
export LC_ALL=en_US.utf8
command="@localstatedir@/guix/profiles/per-user/root/current-guix/bin/guix-daemon"
-command_args="--build-users-group=guixbuild"
+command_args="--build-users-group=guixbuild --discover=no"
command_background="yes"
pidfile="/var/run/guix-daemon.pid"
diff --git a/etc/release-manifest.scm b/etc/release-manifest.scm
index a1f731a945..4375c9bf8b 100644
--- a/etc/release-manifest.scm
+++ b/etc/release-manifest.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2020, 2021 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of GNU Guix.
@@ -49,6 +49,14 @@ TARGET."
'("bootstrap-tarballs" "gcc-toolchain" "nss-certs"
"openssh" "emacs" "vim" "python" "guile" "guix")))
+(define %base-packages/armhf
+ ;; XXX: Relax requirements for armhf-linux for lack of enough build power.
+ (map (lambda (package)
+ (if (string=? (package-name package) "emacs")
+ (specification->package "emacs-no-x")
+ package))
+ %base-packages))
+
(define %base-packages/hurd
;; XXX: For now we are less demanding of "i586-gnu".
(map specification->package
@@ -100,9 +108,18 @@ TARGET."
(manifest
(append-map (lambda (system)
(map (cut package->manifest-entry* <> system)
- (if (string=? system "i586-gnu")
- %base-packages/hurd
- %base-packages)))
+ (cond ((string=? system "i586-gnu")
+ %base-packages/hurd)
+ ((string=? system "armhf-linux")
+ ;; FIXME: Drop special case when ci.guix.gnu.org
+ ;; has more ARMv7 build power.
+ %base-packages/armhf)
+ ((string=? system "powerpc64le-linux")
+ ;; FIXME: Drop 'bootstrap-tarballs' until
+ ;; <https://bugs.gnu.org/48055> is fixed.
+ (drop %base-packages 1))
+ (else
+ %base-packages))))
%cuirass-supported-systems)))
(define %system-manifest
diff --git a/etc/snippets/scheme-mode/guix-origin b/etc/snippets/scheme-mode/guix-origin
index 2820a369f3..eb0cdc8242 100644
--- a/etc/snippets/scheme-mode/guix-origin
+++ b/etc/snippets/scheme-mode/guix-origin
@@ -19,7 +19,9 @@
(t "(string-append \\"https://\\" version \\".tar.gz\\")"))}$0)
${1:$(cond ((equal yas-text "git-fetch")
"(file-name (git-file-name name version))")
- ((member yas-text '("svn-fetch" "hg-fetch" "cvs-fetch" "bzr-fetch"))
+ ((equal yas-text "hg-fetch")
+ "(file-name (hg-file-name name version))")
+ ((member yas-text '("svn-fetch" "cvs-fetch" "bzr-fetch"))
"(file-name (string-append name \\"-\\" version \\"-checkout\\"))")
(t ""))}
(sha256
diff --git a/etc/source-manifest.scm b/etc/source-manifest.scm
new file mode 100644
index 0000000000..f96a5da6f7
--- /dev/null
+++ b/etc/source-manifest.scm
@@ -0,0 +1,66 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2021 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 file returns a manifest containing origins of all the packages. The
+;;; main purpose is to allow continuous integration services to keep upstream
+;;; source code around. It can also be passed to 'guix weather -m'.
+
+(use-modules (srfi srfi-1) (srfi srfi-26)
+ (ice-9 match) (ice-9 vlist)
+ (guix packages) (guix profiles)
+ (gnu packages))
+
+(define (all-packages)
+ "Return the list of all the packages, public or private, omitting only
+superseded packages."
+ (fold-packages (lambda (package lst)
+ (match (package-replacement package)
+ (#f (cons package lst))
+ (replacement
+ (append (list replacement package) lst))))
+ '()
+ #:select? (negate package-superseded)))
+
+(define (upstream-origin source)
+ "Return SOURCE without any patches or snippet."
+ (origin (inherit source)
+ (snippet #f) (patches '())))
+
+(define (all-origins)
+ "Return the list of origins referred to by all the packages."
+ (let loop ((packages (all-packages))
+ (origins '())
+ (visited vlist-null))
+ (match packages
+ ((head . tail)
+ (let ((new (remove (cut vhash-assq <> visited)
+ (package-direct-sources head))))
+ (loop tail (append new origins)
+ (fold (cut vhash-consq <> #t <>)
+ visited new))))
+ (()
+ origins))))
+
+;; Return a manifest containing all the origins.
+(manifest (map (lambda (origin)
+ (manifest-entry
+ (name (or (origin-actual-file-name origin)
+ "origin"))
+ (version "0")
+ (item (upstream-origin origin))))
+ (all-origins)))
diff --git a/etc/substitutes/bordeaux.guix.gnu.org.pub b/etc/substitutes/bordeaux.guix.gnu.org.pub
new file mode 100644
index 0000000000..67085c4498
--- /dev/null
+++ b/etc/substitutes/bordeaux.guix.gnu.org.pub
@@ -0,0 +1,6 @@
+(public-key
+ (ecc
+ (curve Ed25519)
+ (q #7D602902D3A2DBB83F8A0FB98602A754C5493B0B778C8D1DD4E0F41DE14DE34F#)
+ )
+ )