diff options
Diffstat (limited to 'nixos/modules/installer')
-rw-r--r-- | nixos/modules/installer/tools/nixos-option.sh | 123 |
1 files changed, 113 insertions, 10 deletions
diff --git a/nixos/modules/installer/tools/nixos-option.sh b/nixos/modules/installer/tools/nixos-option.sh index 96d09c3a6058..17c17d05e288 100644 --- a/nixos/modules/installer/tools/nixos-option.sh +++ b/nixos/modules/installer/tools/nixos-option.sh @@ -13,6 +13,7 @@ usage () { xml=false verbose=false +nixPath="" option="" @@ -26,6 +27,7 @@ for arg; do while test "$sarg" != "-"; do case $sarg in --*) longarg=$arg; sarg="--";; + -I) argfun="include_nixpath";; -*) usage;; esac # remove the first letter option @@ -53,6 +55,9 @@ for arg; do var=$(echo $argfun | sed 's,^set_,,') eval $var=$arg ;; + include_nixpath) + nixPath="-I $arg $nixPath" + ;; esac argfun="" fi @@ -69,18 +74,114 @@ fi ############################# evalNix(){ - nix-instantiate - --eval-only "$@" + result=$(nix-instantiate ${nixPath:+$nixPath} - --eval-only "$@" 2>&1) + if test $? -eq 0; then + cat <<EOF +$result +EOF + return 0; + else + sed -n ' + /^error/ { s/, at (string):[0-9]*:[0-9]*//; p; }; + /^warning: Nix search path/ { p; }; +' <<EOF +$result +EOF + return 1; + fi +} + +header="let + nixos = import <nixpkgs/nixos> {}; + nixpkgs = import <nixpkgs> {}; +in with nixpkgs.lib; +" + +# This function is used for converting the option definition path given by +# the user into accessors for reaching the definition and the declaration +# corresponding to this option. +generateAccessors(){ + if result=$(evalNix --strict --show-trace <<EOF +$header + +let + path = "${option:+$option}"; + pathList = splitString "." path; + + walkOptions = attrsNames: result: + if attrsNames == [] then + result + else + let name = head attrsNames; rest = tail attrsNames; in + if isOption result.options then + walkOptions rest { + options = result.options.type.getSubOptions ""; + opt = ''(\${result.opt}.type.getSubOptions "")''; + cfg = ''\${result.cfg}."\${name}"''; + } + else + walkOptions rest { + options = result.options.\${name}; + opt = ''\${result.opt}."\${name}"''; + cfg = ''\${result.cfg}."\${name}"''; + } + ; + + walkResult = (if path == "" then x: x else walkOptions pathList) { + options = nixos.options; + opt = ''nixos.options''; + cfg = ''nixos.config''; + }; + +in + ''let option = \${walkResult.opt}; config = \${walkResult.cfg}; in'' +EOF +) + then + echo $result + else + # In case of error we want to ignore the error message roduced by the + # script above, as it is iterating over each attribute, which does not + # produce a nice error message. The following code is a fallback + # solution which is cause a nicer error message in the next + # evaluation. + echo "\"let option = nixos.options${option:+.$option}; config = nixos.config${option:+.$option}; in\"" + fi } +header="$header +$(eval echo $(generateAccessors)) +" + evalAttr(){ local prefix="$1" local strict="$2" local suffix="$3" - echo "(import <nixos> {}).$prefix${option:+.$option}${suffix:+.$suffix}" | evalNix ${strict:+--strict} + + # If strict is set, then set it to "true". + test -n "$strict" && strict=true + + evalNix ${strict:+--strict} <<EOF +$header + +let + value = $prefix${suffix:+.$suffix}; + strict = ${strict:-false}; + cleanOutput = x: with nixpkgs.lib; + if isDerivation x then x.outPath + else if isFunction x then "<CODE>" + else if strict then + if isAttrs x then mapAttrs (n: cleanOutput) x + else if isList x then map cleanOutput x + else x + else x; +in + cleanOutput value +EOF } evalOpt(){ - evalAttr "options" "" "$@" + evalAttr "option" "" "$@" } evalCfg(){ @@ -90,8 +191,11 @@ evalCfg(){ findSources(){ local suffix=$1 - echo "(import <nixos> {}).options${option:+.$option}.$suffix" | - evalNix --strict + evalNix --strict <<EOF +$header + +option.$suffix +EOF } # Given a result from nix-instantiate, recover the list of attributes it @@ -121,13 +225,12 @@ nixMap() { # the output of nixos-option with other tools such as nixos-gui. if $xml; then evalNix --xml --no-location <<EOF +$header + let - reach = attrs: attrs${option:+.$option}; - nixos = import <nixos> {}; - nixpkgs = import <nixpkgs> {}; sources = builtins.map (f: f.source); - opt = reach nixos.options; - cfg = reach nixos.config; + opt = option; + cfg = config; in with nixpkgs.lib; |