diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/attrsets.nix | 9 | ||||
-rw-r--r-- | lib/composable-derivation.nix | 113 | ||||
-rw-r--r-- | lib/default.nix | 16 | ||||
-rw-r--r-- | lib/deprecated.nix | 126 | ||||
-rw-r--r-- | lib/fixed-points.nix | 10 | ||||
-rw-r--r-- | lib/licenses.nix | 61 | ||||
-rw-r--r-- | lib/meta.nix | 11 | ||||
-rw-r--r-- | lib/modules.nix | 34 | ||||
-rw-r--r-- | lib/strings.nix | 20 | ||||
-rw-r--r-- | lib/systems/default.nix | 2 | ||||
-rw-r--r-- | lib/systems/examples.nix | 6 | ||||
-rw-r--r-- | lib/systems/parse.nix | 13 | ||||
-rw-r--r-- | lib/tests/misc.nix | 38 | ||||
-rwxr-xr-x | lib/tests/modules.sh | 6 | ||||
-rw-r--r-- | lib/tests/modules/alias-with-priority-can-override.nix | 52 | ||||
-rw-r--r-- | lib/tests/modules/alias-with-priority.nix | 52 |
16 files changed, 228 insertions, 341 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix index 2a1b866dbc5e..d374d229f597 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -94,6 +94,15 @@ rec { attrValues = builtins.attrValues or (attrs: attrVals (attrNames attrs) attrs); + /* Given a set of attribute names, return the set of the corresponding + attributes from the given set. + + Example: + getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; } + => { a = 1; b = 2; } + */ + getAttrs = names: attrs: genAttrs names (name: attrs.${name}); + /* Collect each attribute named `attr' from a list of attribute sets. Sets that don't contain the named attribute are ignored. diff --git a/lib/composable-derivation.nix b/lib/composable-derivation.nix deleted file mode 100644 index cb1fdc121e11..000000000000 --- a/lib/composable-derivation.nix +++ /dev/null @@ -1,113 +0,0 @@ -{lib, pkgs}: -let inherit (lib) nvs; in -{ - - # composableDerivation basically mixes these features: - # - fix function - # - mergeAttrBy - # - provides shortcuts for "options" such as "--enable-foo" and adding - # buildInputs, see php example - # - # It predates styles which are common today, such as - # * the config attr - # * mkDerivation.override feature - # * overrideDerivation (lib/customization.nix) - # - # Some of the most more important usage examples (which could be rewritten if it was important): - # * php - # * postgis - # * vim_configurable - # - # A minimal example illustrating most features would look like this: - # let base = composableDerivation { (fixed: let inherit (fixed.fixed) name in { - # src = fetchurl { - # } - # buildInputs = [A]; - # preConfigre = "echo ${name}"; - # # attention, "name" attr is missing, thus you cannot instantiate "base". - # } - # in { - # # These all add name attribute, thus you can instantiate those: - # v1 = base.merge ({ name = "foo-add-B"; buildInputs = [B]; }); // B gets merged into buildInputs - # v2 = base.merge ({ name = "mix-in-pre-configure-lines" preConfigre = ""; }); - # v3 = base.replace ({ name = "foo-no-A-only-B;" buildInputs = [B]; }); - # } - # - # So yes, you can think about it being something like nixos modules, and - # you'd be merging "features" in one at a time using .merge or .replace - # Thanks Shea for telling me that I rethink the documentation .. - # - # issues: - # * its complicated to understand - # * some "features" such as exact merge behaviour are buried in mergeAttrBy - # and defaultOverridableDelayableArgs assuming the default behaviour does - # the right thing in the common case - # * Eelco once said using such fix style functions are slow to evaluate - # * Too quick & dirty. Hard to understand for others. The benefit was that - # you were able to create a kernel builder like base derivation and replace - # / add patches the way you want without having to declare function arguments - # - # nice features: - # declaring "optional features" is modular. For instance: - # flags.curl = { - # configureFlags = ["--with-curl=${curl.dev}" "--with-curlwrappers"]; - # buildInputs = [curl openssl]; - # }; - # flags.other = { .. } - # (Example taken from PHP) - # - # alternative styles / related features: - # * Eg see function supporting building the kernel - # * versionedDerivation (discussion about this is still going on - or ended) - # * composedArgsAndFun - # * mkDerivation.override - # * overrideDerivation - # * using { .., *Support ? false }: like configurable options. - # To find those examples use grep - # - # To sum up: It exists for historical reasons - and for most commonly used - # tasks the alternatives should be used - # - # If you have questions about this code ping Marc Weber. - composableDerivation = { - mkDerivation ? pkgs.stdenv.mkDerivation, - - # list of functions to be applied before defaultOverridableDelayableArgs removes removeAttrs names - # prepareDerivationArgs handles derivation configurations - applyPreTidy ? [ lib.prepareDerivationArgs ], - - # consider adding addtional elements by derivation.merge { removeAttrs = ["elem"]; }; - removeAttrs ? ["cfg" "flags"] - - }: (lib.defaultOverridableDelayableArgs ( a: mkDerivation a) - { - inherit applyPreTidy removeAttrs; - }).merge; - - # some utility functions - # use this function to generate flag attrs for prepareDerivationArgs - # E nable D isable F eature - edf = {name, feat ? name, enable ? {}, disable ? {} , value ? ""}: - nvs name { - set = { - configureFlags = ["--enable-${feat}${if value == "" then "" else "="}${value}"]; - } // enable; - unset = { - configureFlags = ["--disable-${feat}"]; - } // disable; - }; - - # same for --with and --without- - # W ith or W ithout F eature - wwf = {name, feat ? name, enable ? {}, disable ? {}, value ? ""}: - nvs name { - set = enable // { - configureFlags = ["--with-${feat}${if value == "" then "" else "="}${value}"] - ++ lib.maybeAttr "configureFlags" [] enable; - }; - unset = disable // { - configureFlags = ["--without-${feat}"] - ++ lib.maybeAttr "configureFlags" [] disable; - }; - }; -} diff --git a/lib/default.nix b/lib/default.nix index d7a05fec8338..d400907ebb0c 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -61,10 +61,10 @@ let boolToString mergeAttrs flip mapNullable inNixShell min max importJSON warn info nixpkgsVersion version mod compare splitByAndCompare functionArgs setFunctionArgs isFunction; - inherit (fixedPoints) fix fix' extends composeExtensions + inherit (fixedPoints) fix fix' converge extends composeExtensions makeExtensible makeExtensibleWithCustomName; inherit (attrsets) attrByPath hasAttrByPath setAttrByPath - getAttrFromPath attrVals attrValues catAttrs filterAttrs + getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond genAttrs isDerivation toDerivation optionalAttrs @@ -80,7 +80,7 @@ let inherit (strings) concatStrings concatMapStrings concatImapStrings intersperse concatStringsSep concatMapStringsSep concatImapStringsSep makeSearchPath makeSearchPathOutput - makeLibraryPath makeBinPath makePerlPath makeFullPerlPath optionalString + makeLibraryPath makeBinPath optionalString hasPrefix hasSuffix stringToCharacters stringAsChars escape escapeShellArg escapeShellArgs replaceChars lowerChars upperChars toLower toUpper addContextFrom splitString @@ -94,7 +94,7 @@ let callPackageWith callPackagesWith extendDerivation hydraJob makeScope; inherit (meta) addMetaAttrs dontDistribute setName updateName - appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio + appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio hiPrioSet; inherit (sources) pathType pathIsDirectory cleanSourceFilter cleanSource sourceByRegex sourceFilesBySuffices @@ -109,7 +109,7 @@ let mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule - mkAliasOptionModule doRename filterModules; + mkAliasOptionModule mkAliasOptionModuleWithPriority doRename filterModules; inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions mergeDefaultOption mergeOneOption mergeEqualOption getValues getFiles optionAttrSetToDocList optionAttrSetToDocList' @@ -125,14 +125,14 @@ let traceShowValMarked showVal traceCall traceCall2 traceCall3 traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr; inherit (misc) maybeEnv defaultMergeArg defaultMerge foldArgs - defaultOverridableDelayableArgs composedArgsAndFun maybeAttrNullable maybeAttr ifEnable checkFlag getValue checkReqs uniqList uniqListExt condConcat lazyGenericClosure innerModifySumArgs modifySumArgs innerClosePropagation closePropagation mapAttrsFlatten nvs setAttr setAttrMerge mergeAttrsWithFunc mergeAttrsConcatenateValues mergeAttrsNoOverride mergeAttrByFunc mergeAttrsByFuncDefaults - mergeAttrsByFuncDefaultsClean mergeAttrBy prepareDerivationArgs - nixType imap overridableDelayableArgs; + mergeAttrsByFuncDefaultsClean mergeAttrBy + fakeSha256 fakeSha512 + nixType imap; }); in lib diff --git a/lib/deprecated.nix b/lib/deprecated.nix index 34cf336d1f42..15de50456612 100644 --- a/lib/deprecated.nix +++ b/lib/deprecated.nix @@ -35,74 +35,6 @@ rec { withStdOverrides; - # predecessors: proposed replacement for applyAndFun (which has a bug cause it merges twice) - # the naming "overridableDelayableArgs" tries to express that you can - # - override attr values which have been supplied earlier - # - use attr values before they have been supplied by accessing the fix point - # name "fixed" - # f: the (delayed overridden) arguments are applied to this - # - # initial: initial attrs arguments and settings. see defaultOverridableDelayableArgs - # - # returns: f applied to the arguments // special attributes attrs - # a) merge: merge applied args with new args. Wether an argument is overridden depends on the merge settings - # b) replace: this let's you replace and remove names no matter which merge function has been set - # - # examples: see test cases "res" below; - overridableDelayableArgs = - f: # the function applied to the arguments - initial: # you pass attrs, the functions below are passing a function taking the fix argument - let - takeFixed = if lib.isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument - tidy = args: - let # apply all functions given in "applyPreTidy" in sequence - applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args); - in removeAttrs (applyPreTidyFun args) ( ["applyPreTidy"] ++ (maybeAttr "removeAttrs" [] args) ); # tidy up args before applying them - fun = n: x: - let newArgs = fixed: - let args = takeFixed fixed; - mergeFun = args.${n}; - in if isAttrs x then (mergeFun args x) - else assert lib.isFunction x; - mergeFun args (x ( args // { inherit fixed; })); - in overridableDelayableArgs f newArgs; - in - (f (tidy (lib.fix takeFixed))) // { - merge = fun "mergeFun"; - replace = fun "keepFun"; - }; - defaultOverridableDelayableArgs = f: - let defaults = { - mergeFun = mergeAttrByFunc; # default merge function. merge strategie (concatenate lists, strings) is given by mergeAttrBy - keepFun = a: b: { inherit (a) removeAttrs mergeFun keepFun mergeAttrBy; } // b; # even when using replace preserve these values - applyPreTidy = []; # list of functions applied to args before args are tidied up (usage case : prepareDerivationArgs) - mergeAttrBy = mergeAttrBy // { - applyPreTidy = a: b: a ++ b; - removeAttrs = a: b: a ++ b; - }; - removeAttrs = ["mergeFun" "keepFun" "mergeAttrBy" "removeAttrs" "fixed" ]; # before applying the arguments to the function make sure these names are gone - }; - in (overridableDelayableArgs f defaults).merge; - - - - # rec { # an example of how composedArgsAndFun can be used - # a = composedArgsAndFun (x: x) { a = ["2"]; meta = { d = "bar";}; }; - # # meta.d will be lost ! It's your task to preserve it (eg using a merge function) - # b = a.passthru.function { a = [ "3" ]; meta = { d2 = "bar2";}; }; - # # instead of passing/ overriding values you can use a merge function: - # c = b.passthru.function ( x: { a = x.a ++ ["4"]; }); # consider using (maybeAttr "a" [] x) - # } - # result: - # { - # a = { a = ["2"]; meta = { d = "bar"; }; passthru = { function = .. }; }; - # b = { a = ["3"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; }; - # c = { a = ["3" "4"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; }; - # # c2 is equal to c - # } - composedArgsAndFun = f: foldArgs defaultMerge f {}; - - # shortcut for attrByPath ["name"] default attrs maybeAttrNullable = maybeAttr; @@ -285,7 +217,7 @@ rec { # }; # will result in # { mergeAttrsBy = [...]; buildInputs = [ a b c d ]; } - # is used by prepareDerivationArgs, defaultOverridableDelayableArgs and can be used when composing using + # is used by defaultOverridableDelayableArgs and can be used when composing using # foldArgs, composedArgsAndFun or applyAndFun. Example: composableDerivation in all-packages.nix mergeAttrByFunc = x: y: let @@ -318,58 +250,6 @@ rec { // listToAttrs (map (n: nameValuePair n (a: b: "${a}\n${b}") ) [ "preConfigure" "postInstall" ]) ; - # prepareDerivationArgs tries to make writing configurable derivations easier - # example: - # prepareDerivationArgs { - # mergeAttrBy = { - # myScript = x: y: x ++ "\n" ++ y; - # }; - # cfg = { - # readlineSupport = true; - # }; - # flags = { - # readline = { - # set = { - # configureFlags = [ "--with-compiler=${compiler}" ]; - # buildInputs = [ compiler ]; - # pass = { inherit compiler; READLINE=1; }; - # assertion = compiler.dllSupport; - # myScript = "foo"; - # }; - # unset = { configureFlags = ["--without-compiler"]; }; - # }; - # }; - # src = ... - # buildPhase = '' ... ''; - # name = ... - # myScript = "bar"; - # }; - # if you don't have need for unset you can omit the surrounding set = { .. } attr - # all attrs except flags cfg and mergeAttrBy will be merged with the - # additional data from flags depending on config settings - # It's used in composableDerivation in all-packages.nix. It's also used - # heavily in the new python and libs implementation - # - # should we check for misspelled cfg options? - # TODO use args.mergeFun here as well? - prepareDerivationArgs = args: - let args2 = { cfg = {}; flags = {}; } // args; - flagName = name: "${name}Support"; - cfgWithDefaults = (listToAttrs (map (n: nameValuePair (flagName n) false) (attrNames args2.flags))) - // args2.cfg; - opts = attrValues (mapAttrs (a: v: - let v2 = if v ? set || v ? unset then v else { set = v; }; - n = if cfgWithDefaults.${flagName a} then "set" else "unset"; - attr = maybeAttr n {} v2; in - if (maybeAttr "assertion" true attr) - then attr - else throw "assertion of flag ${a} of derivation ${args.name} failed" - ) args2.flags ); - in removeAttrs - (mergeAttrsByFuncDefaults ([args] ++ opts ++ [{ passthru = cfgWithDefaults; }])) - ["flags" "cfg" "mergeAttrBy" ]; - - nixType = x: if isAttrs x then if x ? outPath then "derivation" @@ -390,4 +270,8 @@ rec { starting at zero. */ imap = imap1; + + # Fake hashes. Can be used as hash placeholders, when computing hash ahead isn't trivial + fakeSha256 = "0000000000000000000000000000000000000000000000000000000000000000"; + fakeSha512 = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; } diff --git a/lib/fixed-points.nix b/lib/fixed-points.nix index 7169c46fcbbc..2f818c88de5d 100644 --- a/lib/fixed-points.nix +++ b/lib/fixed-points.nix @@ -24,6 +24,16 @@ rec { # for a concrete example. fix' = f: let x = f x // { __unfix__ = f; }; in x; + # Return the fixpoint that `f` converges to when called recursively, starting + # with the input `x`. + # + # nix-repl> converge (x: x / 2) 16 + # 0 + converge = f: x: + if (f x) == x + then x + else converge f (f x); + # Modify the contents of an explicitly recursive attribute set in a way that # honors `self`-references. This is accomplished with a function # diff --git a/lib/licenses.nix b/lib/licenses.nix index ed91b5adedbf..fc9cb42621d4 100644 --- a/lib/licenses.nix +++ b/lib/licenses.nix @@ -29,13 +29,13 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { }; agpl3 = spdx { - spdxId = "AGPL-3.0"; - fullName = "GNU Affero General Public License v3.0"; + spdxId = "AGPL-3.0-only"; + fullName = "GNU Affero General Public License v3.0 only"; }; - agpl3Plus = { + agpl3Plus = spdx { + spdxId = "AGPL-3.0-or-later"; fullName = "GNU Affero General Public License v3.0 or later"; - inherit (agpl3) url; }; amazonsl = { @@ -266,13 +266,23 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { }; fdl12 = spdx { - spdxId = "GFDL-1.2"; - fullName = "GNU Free Documentation License v1.2"; + spdxId = "GFDL-1.2-only"; + fullName = "GNU Free Documentation License v1.2 only"; + }; + + fdl12Plus = spdx { + spdxId = "GFDL-1.2-or-later"; + fullName = "GNU Free Documentation License v1.2 or later"; }; fdl13 = spdx { - spdxId = "GFDL-1.3"; - fullName = "GNU Free Documentation License v1.3"; + spdxId = "GFDL-1.3-only"; + fullName = "GNU Free Documentation License v1.3 only"; + }; + + fdl13Plus = spdx { + spdxId = "GFDL-1.3-or-later"; + fullName = "GNU Free Documentation License v1.3 or later"; }; ffsl = { @@ -297,24 +307,23 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { }; gpl1 = spdx { - spdxId = "GPL-1.0"; + spdxId = "GPL-1.0-only"; fullName = "GNU General Public License v1.0 only"; }; gpl1Plus = spdx { - spdxId = "GPL-1.0+"; + spdxId = "GPL-1.0-or-later"; fullName = "GNU General Public License v1.0 or later"; }; gpl2 = spdx { - spdxId = "GPL-2.0"; + spdxId = "GPL-2.0-only"; fullName = "GNU General Public License v2.0 only"; }; - gpl2Classpath = { + gpl2Classpath = spdx { spdxId = "GPL-2.0-with-classpath-exception"; fullName = "GNU General Public License v2.0 only (with Classpath exception)"; - url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception; }; gpl2ClasspathPlus = { @@ -328,17 +337,17 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { }; gpl2Plus = spdx { - spdxId = "GPL-2.0+"; + spdxId = "GPL-2.0-or-later"; fullName = "GNU General Public License v2.0 or later"; }; gpl3 = spdx { - spdxId = "GPL-3.0"; + spdxId = "GPL-3.0-only"; fullName = "GNU General Public License v3.0 only"; }; gpl3Plus = spdx { - spdxId = "GPL-3.0+"; + spdxId = "GPL-3.0-or-later"; fullName = "GNU General Public License v3.0 or later"; }; @@ -408,32 +417,32 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { }; lgpl2 = spdx { - spdxId = "LGPL-2.0"; + spdxId = "LGPL-2.0-only"; fullName = "GNU Library General Public License v2 only"; }; lgpl2Plus = spdx { - spdxId = "LGPL-2.0+"; + spdxId = "LGPL-2.0-or-later"; fullName = "GNU Library General Public License v2 or later"; }; lgpl21 = spdx { - spdxId = "LGPL-2.1"; + spdxId = "LGPL-2.1-only"; fullName = "GNU Library General Public License v2.1 only"; }; lgpl21Plus = spdx { - spdxId = "LGPL-2.1+"; + spdxId = "LGPL-2.1-or-later"; fullName = "GNU Library General Public License v2.1 or later"; }; lgpl3 = spdx { - spdxId = "LGPL-3.0"; + spdxId = "LGPL-3.0-only"; fullName = "GNU Lesser General Public License v3.0 only"; }; lgpl3Plus = spdx { - spdxId = "LGPL-3.0+"; + spdxId = "LGPL-3.0-or-later"; fullName = "GNU Lesser General Public License v3.0 or later"; }; @@ -505,6 +514,12 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { free = false; }; + nasa13 = spdx { + spdxId = "NASA-1.3"; + fullName = "NASA Open Source Agreement 1.3"; + free = false; + }; + ncsa = spdx { spdxId = "NCSA"; fullName = "University of Illinois/NCSA Open Source License"; @@ -691,7 +706,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec { }; wxWindows = spdx { - spdxId = "WXwindows"; + spdxId = "wxWindows"; fullName = "wxWindows Library Licence, Version 3.1"; }; diff --git a/lib/meta.nix b/lib/meta.nix index 199030c103af..2e83c4247ddf 100644 --- a/lib/meta.nix +++ b/lib/meta.nix @@ -41,16 +41,18 @@ rec { let x = builtins.parseDrvName name; in "${x.name}-${suffix}-${x.version}"); - /* Apply a function to each derivation and only to derivations in an attrset + /* Apply a function to each derivation and only to derivations in an attrset. */ mapDerivationAttrset = f: set: lib.mapAttrs (name: pkg: if lib.isDerivation pkg then (f pkg) else pkg) set; + /* Set the nix-env priority of the package. + */ + setPrio = priority: addMetaAttrs { inherit priority; }; /* Decrease the nix-env priority of the package, i.e., other versions/variants of the package will be preferred. */ - lowPrio = drv: addMetaAttrs { priority = 10; } drv; - + lowPrio = setPrio 10; /* Apply lowPrio to an attrset with derivations */ @@ -60,8 +62,7 @@ rec { /* Increase the nix-env priority of the package, i.e., this version/variant of the package will be preferred. */ - hiPrio = drv: addMetaAttrs { priority = -10; } drv; - + hiPrio = setPrio (-10); /* Apply hiPrio to an attrset with derivations */ diff --git a/lib/modules.nix b/lib/modules.nix index 5fb83a4a538c..9f8e196ee0f7 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -450,8 +450,7 @@ rec { filterOverrides' = defs: let - defaultPrio = 100; - getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPrio; + getPrio = def: if def.value._type or "" == "override" then def.value.priority else defaultPriority; highestPrio = foldl' (prio: def: min (getPrio def) prio) 9999 defs; strip = def: if def.value._type or "" == "override" then def // { value = def.value.content; } else def; in { @@ -534,6 +533,8 @@ rec { mkBefore = mkOrder 500; mkAfter = mkOrder 1500; + # The default priority for things that don't have a priority specified. + defaultPriority = 100; # Convenient property used to transfer all definitions and their # properties from one option to another. This property is useful for @@ -556,8 +557,20 @@ rec { # mkAliasDefinitions = mkAliasAndWrapDefinitions id; mkAliasAndWrapDefinitions = wrap: option: - mkIf (isOption option && option.isDefined) (wrap (mkMerge option.definitions)); + mkAliasIfDef option (wrap (mkMerge option.definitions)); + # Similar to mkAliasAndWrapDefinitions but copies over the priority from the + # option as well. + # + # If a priority is not set, it assumes a priority of defaultPriority. + mkAliasAndWrapDefsWithPriority = wrap: option: + let + prio = option.highestPrio or defaultPriority; + defsWithPrio = map (mkOverride prio) option.definitions; + in mkAliasIfDef option (wrap (mkMerge defsWithPrio)); + + mkAliasIfDef = option: + mkIf (isOption option && option.isDefined); /* Compatibility. */ fixMergeModules = modules: args: evalModules { inherit modules args; check = false; }; @@ -690,7 +703,16 @@ rec { use = id; }; - doRename = { from, to, visible, warn, use }: + /* Like ‘mkAliasOptionModule’, but copy over the priority of the option as well. */ + mkAliasOptionModuleWithPriority = from: to: doRename { + inherit from to; + visible = true; + warn = false; + use = id; + withPriority = true; + }; + + doRename = { from, to, visible, warn, use, withPriority ? false }: { config, options, ... }: let fromOpt = getAttrFromPath from options; @@ -708,7 +730,9 @@ rec { warnings = optional (warn && fromOpt.isDefined) "The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'."; } - (mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt) + (if withPriority + then mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt + else mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt) ]; }; diff --git a/lib/strings.nix b/lib/strings.nix index 48420a367815..47c881cfbc7c 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -162,26 +162,6 @@ rec { */ makeBinPath = makeSearchPathOutput "bin" "bin"; - - /* Construct a perl search path (such as $PERL5LIB) - - Example: - pkgs = import <nixpkgs> { } - makePerlPath [ pkgs.perlPackages.libnet ] - => "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl" - */ - # FIXME(zimbatm): this should be moved in perl-specific code - makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl"; - - /* Construct a perl search path recursively including all dependencies (such as $PERL5LIB) - - Example: - pkgs = import <nixpkgs> { } - makeFullPerlPath [ pkgs.perlPackages.CGI ] - => "/nix/store/fddivfrdc1xql02h9q500fpnqy12c74n-perl-CGI-4.38/lib/perl5/site_perl:/nix/store/8hsvdalmsxqkjg0c5ifigpf31vc4vsy2-perl-HTML-Parser-3.72/lib/perl5/site_perl:/nix/store/zhc7wh0xl8hz3y3f71nhlw1559iyvzld-perl-HTML-Tagset-3.20/lib/perl5/site_perl" - */ - makeFullPerlPath = deps: makePerlPath (lib.misc.closePropagation deps); - /* Depending on the boolean `cond', return either the given string or the empty string. Useful to concatenate against a bigger string. diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 25df5e174069..9b25052ab88d 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -98,7 +98,7 @@ rec { in if final.parsed.kernel.name == pkgs.stdenv.hostPlatform.parsed.kernel.name && (final.parsed.cpu.name == pkgs.stdenv.hostPlatform.parsed.cpu.name || - (final.platform.isi686 && pkgs.stdenv.hostPlatform.isx86_64)) + (final.isi686 && pkgs.stdenv.hostPlatform.isx86_64)) then pkgs.runtimeShell else if final.isWindows then "${wine}/bin/${wine-name}" diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix index 608db00a9683..ac1633a1a15f 100644 --- a/lib/systems/examples.nix +++ b/lib/systems/examples.nix @@ -47,7 +47,7 @@ rec { armv5te-android-prebuilt = rec { config = "armv5tel-unknown-linux-androideabi"; sdkVer = "21"; - ndkVer = "10e"; + ndkVer = "18b"; platform = platforms.armv5te-android; useAndroidPrebuilt = true; }; @@ -55,7 +55,7 @@ rec { armv7a-android-prebuilt = rec { config = "armv7a-unknown-linux-androideabi"; sdkVer = "24"; - ndkVer = "17c"; + ndkVer = "18b"; platform = platforms.armv7a-android; useAndroidPrebuilt = true; }; @@ -63,7 +63,7 @@ rec { aarch64-android-prebuilt = rec { config = "aarch64-unknown-linux-android"; sdkVer = "24"; - ndkVer = "17c"; + ndkVer = "18b"; platform = platforms.aarch64-multiplatform; useAndroidPrebuilt = true; }; diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 7db09fc550e2..6947d41419e3 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -279,8 +279,14 @@ rec { "2" = # We only do 2-part hacks for things Nix already supports if elemAt l 1 == "cygwin" then { cpu = elemAt l 0; kernel = "windows"; abi = "cygnus"; } + # MSVC ought to be the default ABI so this case isn't needed. But then it + # becomes difficult to handle the gnu* variants for Aarch32 correctly for + # minGW. So it's easier to make gnu* the default for the MinGW, but + # hack-in MSVC for the non-MinGW case right here. + else if elemAt l 1 == "windows" + then { cpu = elemAt l 0; kernel = "windows"; abi = "msvc"; } else if (elemAt l 1) == "elf" - then { cpu = elemAt l 0; vendor = "unknown"; kernel = "none"; abi = elemAt l 1; } + then { cpu = elemAt l 0; vendor = "unknown"; kernel = "none"; abi = elemAt l 1; } else { cpu = elemAt l 0; kernel = elemAt l 1; }; "3" = # Awkwards hacks, beware! if elemAt l 1 == "apple" @@ -288,7 +294,7 @@ rec { else if (elemAt l 1 == "linux") || (elemAt l 2 == "gnu") then { cpu = elemAt l 0; kernel = elemAt l 1; abi = elemAt l 2; } else if (elemAt l 2 == "mingw32") # autotools breaks on -gnu for window - then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; abi = "gnu"; } + then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = "windows"; } else if hasPrefix "netbsd" (elemAt l 2) then { cpu = elemAt l 0; vendor = elemAt l 1; kernel = elemAt l 2; } else if (elem (elemAt l 2) ["eabi" "eabihf" "elf"]) @@ -324,13 +330,12 @@ rec { else getKernel args.kernel; abi = /**/ if args ? abi then getAbi args.abi - else if isLinux parsed then + else if isLinux parsed || isWindows parsed then if isAarch32 parsed then if lib.versionAtLeast (parsed.cpu.version or "0") "6" then abis.gnueabihf else abis.gnueabi else abis.gnu - else if isWindows parsed then abis.gnu else abis.unknown; }; diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 1604fbb39cbb..d8f412d3fc49 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -401,42 +401,4 @@ runTests { expected = "«foo»"; }; - -# MISC - - testOverridableDelayableArgsTest = { - expr = - let res1 = defaultOverridableDelayableArgs id {}; - res2 = defaultOverridableDelayableArgs id { a = 7; }; - res3 = let x = defaultOverridableDelayableArgs id { a = 7; }; - in (x.merge) { b = 10; }; - res4 = let x = defaultOverridableDelayableArgs id { a = 7; }; - in (x.merge) ( x: { b = 10; }); - res5 = let x = defaultOverridableDelayableArgs id { a = 7; }; - in (x.merge) ( x: { a = builtins.add x.a 3; }); - res6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = builtins.add; }; }; - y = x.merge {}; - in (y.merge) { a = 10; }; - - resRem7 = res6.replace (a: removeAttrs a ["a"]); - - # fixed tests (delayed args): (when using them add some comments, please) - resFixed1 = - let x = defaultOverridableDelayableArgs id ( x: { a = 7; c = x.fixed.b; }); - y = x.merge (x: { name = "name-${builtins.toString x.fixed.c}"; }); - in (y.merge) { b = 10; }; - strip = attrs: removeAttrs attrs ["merge" "replace"]; - in all id - [ ((strip res1) == { }) - ((strip res2) == { a = 7; }) - ((strip res3) == { a = 7; b = 10; }) - ((strip res4) == { a = 7; b = 10; }) - ((strip res5) == { a = 10; }) - ((strip res6) == { a = 17; }) - ((strip resRem7) == {}) - ((strip resFixed1) == { a = 7; b = 10; c =10; name = "name-10"; }) - ]; - expected = true; - }; - } diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index b83e1eb7d82d..a72777cbf2a6 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -149,6 +149,12 @@ checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-long-list.ni # Check loaOf with many merges of lists. checkConfigOutput "1 2 3 4 5 6 7 8 9 10" config.result ./loaOf-with-many-list-merges.nix +# Check mkAliasOptionModuleWithPriority. +checkConfigOutput "true" config.enable ./alias-with-priority.nix +checkConfigOutput "true" config.enableAlias ./alias-with-priority.nix +checkConfigOutput "false" config.enable ./alias-with-priority-can-override.nix +checkConfigOutput "false" config.enableAlias ./alias-with-priority-can-override.nix + cat <<EOF ====== module tests ====== $pass Pass diff --git a/lib/tests/modules/alias-with-priority-can-override.nix b/lib/tests/modules/alias-with-priority-can-override.nix new file mode 100644 index 000000000000..a6b26895f3a8 --- /dev/null +++ b/lib/tests/modules/alias-with-priority-can-override.nix @@ -0,0 +1,52 @@ +# This is a test to show that mkAliasOptionModule sets the priority correctly +# for aliased options. + +{ config, lib, ... }: + +with lib; + +{ + options = { + # A simple boolean option that can be enabled or disabled. + enable = lib.mkOption { + type = types.nullOr types.bool; + default = null; + example = true; + description = '' + Some descriptive text + ''; + }; + + # mkAliasOptionModule sets warnings, so this has to be defined. + warnings = mkOption { + internal = true; + default = []; + type = types.listOf types.str; + example = [ "The `foo' service is deprecated and will go away soon!" ]; + description = '' + This option allows modules to show warnings to users during + the evaluation of the system configuration. + ''; + }; + }; + + imports = [ + # Create an alias for the "enable" option. + (mkAliasOptionModuleWithPriority [ "enableAlias" ] [ "enable" ]) + + # Disable the aliased option, but with a default (low) priority so it + # should be able to be overridden by the next import. + ( { config, lib, ... }: + { + enableAlias = lib.mkForce false; + } + ) + + # Enable the normal (non-aliased) option. + ( { config, lib, ... }: + { + enable = true; + } + ) + ]; +} diff --git a/lib/tests/modules/alias-with-priority.nix b/lib/tests/modules/alias-with-priority.nix new file mode 100644 index 000000000000..923483684cb1 --- /dev/null +++ b/lib/tests/modules/alias-with-priority.nix @@ -0,0 +1,52 @@ +# This is a test to show that mkAliasOptionModule sets the priority correctly +# for aliased options. + +{ config, lib, ... }: + +with lib; + +{ + options = { + # A simple boolean option that can be enabled or disabled. + enable = lib.mkOption { + type = types.nullOr types.bool; + default = null; + example = true; + description = '' + Some descriptive text + ''; + }; + + # mkAliasOptionModule sets warnings, so this has to be defined. + warnings = mkOption { + internal = true; + default = []; + type = types.listOf types.str; + example = [ "The `foo' service is deprecated and will go away soon!" ]; + description = '' + This option allows modules to show warnings to users during + the evaluation of the system configuration. + ''; + }; + }; + + imports = [ + # Create an alias for the "enable" option. + (mkAliasOptionModuleWithPriority [ "enableAlias" ] [ "enable" ]) + + # Disable the aliased option, but with a default (low) priority so it + # should be able to be overridden by the next import. + ( { config, lib, ... }: + { + enableAlias = lib.mkDefault false; + } + ) + + # Enable the normal (non-aliased) option. + ( { config, lib, ... }: + { + enable = true; + } + ) + ]; +} |