diff options
Diffstat (limited to 'etc')
-rwxr-xr-x | etc/committer.scm.in | 134 | ||||
-rw-r--r-- | etc/completion/bash/guix | 117 | ||||
-rw-r--r-- | etc/completion/fish/guix.fish | 2 | ||||
-rw-r--r-- | etc/completion/zsh/_guix | 410 | ||||
-rw-r--r-- | etc/disarchive-manifest.scm | 112 | ||||
-rw-r--r-- | etc/guix-daemon.cil.in | 7 | ||||
-rw-r--r-- | etc/guix-daemon.conf.in | 2 | ||||
-rw-r--r-- | etc/guix-daemon.service.in | 3 | ||||
-rw-r--r-- | etc/guix-gc.service.in | 20 | ||||
-rw-r--r-- | etc/guix-gc.timer | 15 | ||||
-rwxr-xr-x | etc/guix-install.sh | 196 | ||||
-rwxr-xr-x | etc/indent-code.el | 3 | ||||
-rw-r--r-- | etc/init.d/guix-daemon.in | 2 | ||||
-rw-r--r-- | etc/news.scm | 195 | ||||
-rw-r--r-- | etc/openrc/guix-daemon.in | 2 | ||||
-rw-r--r-- | etc/release-manifest.scm | 25 | ||||
-rw-r--r-- | etc/snippets/scheme-mode/guix-origin | 4 | ||||
-rw-r--r-- | etc/source-manifest.scm | 66 | ||||
-rw-r--r-- | etc/substitutes/bordeaux.guix.gnu.org.pub | 6 |
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#) + ) + ) |