Convert libs to a fixed-point

This does break the API of being able to import any lib file and get
its libs, however I'm not sure people did this.

I made this while exploring being able to swap out docFn with a stub
in #2305, to avoid functor performance problems. I don't know if that
is going to move forward (or if it is a problem or not,) but after
doing all this work figured I'd put it up anyway :)

Two notable advantages to this approach:

1. when a lib inherits another lib's functions, it doesn't
   automatically get put in to the scope of lib
2. when a lib implements a new obscure functions, it doesn't
   automatically get put in to the scope of lib

Using the test script (later in this commit) I got the following diff
on the API:

  + diff master fixed-lib
  11764a11765,11766
  > .types.defaultFunctor
  > .types.defaultTypeMerge
  11774a11777,11778
  > .types.isOptionType
  > .types.isType
  11781a11786
  > .types.mkOptionType
  11788a11794
  > .types.setType
  11795a11802
  > .types.types

This means that this commit _adds_ to the API, however I can't find a
way to fix these last remaining discrepancies. At least none are
_removed_.

Test script (run with nix-repl in the PATH):

  #!/bin/sh

  set -eux

  repl() {
      suff=${1:-}
      echo "(import ./lib)$suff" \
          | nix-repl 2>&1
  }

  attrs_to_check() {
      repl "${1:-}" \
          | tr ';'  $'\n' \
          | grep "\.\.\." \
          | cut -d' ' -f2 \
          | sed -e "s/^/${1:-}./" \
          | sort
  }

  summ() {
      repl "${1:-}" \
          | tr ' ' $'\n' \
          | sort \
          | uniq
  }

  deep_summ() {
      suff="${1:-}"
      depth="${2:-4}"
      depth=$((depth - 1))
      summ "$suff"

      for attr in $(attrs_to_check "$suff" | grep -v "types.types"); do
          if [ $depth -eq 0 ]; then
              summ "$attr" | sed -e "s/^/$attr./"
          else
              deep_summ "$attr" "$depth" | sed -e "s/^/$attr./"
          fi
      done
  }

  (
      cd nixpkgs

      #git add .
      #git commit -m "Auto-commit, sorry" || true
      git checkout fixed-lib
      deep_summ > ../fixed-lib
      git checkout master
      deep_summ > ../master
  )

  if diff master fixed-lib; then
      echo "SHALLOW MATCH!"
  fi

  (
      cd nixpkgs
      git checkout fixed-lib
      repl .types
  )
This commit is contained in:
Graham Christensen 2017-07-28 20:05:35 -04:00
parent 4d205eb044
commit 152c63c9ff
No known key found for this signature in database
GPG Key ID: 06121D366FE9435C
27 changed files with 200 additions and 118 deletions

View File

@ -1,11 +1,11 @@
{ lib }:
# Operations on attribute sets. # Operations on attribute sets.
let let
inherit (builtins) head tail length; inherit (builtins) head tail length;
inherit (import ./trivial.nix) and or; inherit (lib.trivial) and or;
inherit (import ./default.nix) fold; inherit (lib.strings) concatStringsSep;
inherit (import ./strings.nix) concatStringsSep; inherit (lib.lists) fold concatMap concatLists all deepSeqList;
inherit (import ./lists.nix) concatMap concatLists all deepSeqList;
in in
rec { rec {

View File

@ -1,6 +1,6 @@
{ lib }:
let let
lib = import ./default.nix;
inherit (builtins) attrNames isFunction; inherit (builtins) attrNames isFunction;
in in

View File

@ -1,4 +1,6 @@
let lib = import ./default.nix; { lib }:
let
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
isString isBool head substring attrNames; isString isBool head substring attrNames;

View File

@ -5,58 +5,127 @@
*/ */
let let
# often used, or depending on very little callLibs = file: import file { inherit lib; };
trivial = import ./trivial.nix;
fixedPoints = import ./fixed-points.nix;
# datatypes lib = rec {
attrsets = import ./attrsets.nix;
lists = import ./lists.nix;
strings = import ./strings.nix;
stringsWithDeps = import ./strings-with-deps.nix;
# packaging # often used, or depending on very little
customisation = import ./customisation.nix; trivial = callLibs ./trivial.nix;
maintainers = import ./maintainers.nix; fixedPoints = callLibs ./fixed-points.nix;
meta = import ./meta.nix;
sources = import ./sources.nix;
# module system # datatypes
modules = import ./modules.nix; attrsets = callLibs ./attrsets.nix;
options = import ./options.nix; lists = callLibs ./lists.nix;
types = import ./types.nix; strings = callLibs ./strings.nix;
stringsWithDeps = callLibs ./strings-with-deps.nix;
# constants # packaging
licenses = import ./licenses.nix; customisation = callLibs ./customisation.nix;
systems = import ./systems; maintainers = callLibs ./maintainers.nix;
meta = callLibs ./meta.nix;
sources = callLibs ./sources.nix;
# misc
debug = import ./debug.nix;
generators = import ./generators.nix;
misc = import ./deprecated.nix;
# domain-specific # module system
sandbox = import ./sandbox.nix; modules = callLibs ./modules.nix;
fetchers = import ./fetchers.nix; options = callLibs ./options.nix;
types = callLibs ./types.nix;
# Eval-time filesystem handling # constants
filesystem = import ./filesystem.nix; licenses = callLibs ./licenses.nix;
systems = callLibs ./systems;
in # misc
{ inherit trivial fixedPoints debug = callLibs ./debug.nix;
attrsets lists strings stringsWithDeps
customisation maintainers meta sources generators = callLibs ./generators.nix;
modules options types misc = callLibs ./deprecated.nix;
licenses systems # domain-specific
debug generators misc sandbox = callLibs ./sandbox.nix;
sandbox fetchers filesystem; fetchers = callLibs ./fetchers.nix;
# Eval-time filesystem handling
filesystem = callLibs ./filesystem.nix;
# back-compat aliases # back-compat aliases
platforms = systems.doubles; platforms = systems.doubles;
}
# !!! don't include everything at top-level; perhaps only the most inherit (builtins) add addErrorContext attrNames
# commonly used functions. concatLists deepSeq elem elemAt filter genericClosure genList
// trivial // fixedPoints getAttr hasAttr head isAttrs isBool isFunction isInt isList
// lists // strings // stringsWithDeps // attrsets // sources isString length lessThan listToAttrs pathExists readFile
// options // types // meta // debug // misc // modules replaceStrings seq stringLength sub substring tail;
// customisation inherit (trivial) id const concat or and boolToString mergeAttrs
flip mapNullable inNixShell min max importJSON warn info
nixpkgsVersion mod;
inherit (fixedPoints) fix fix' extends composeExtensions
makeExtensible makeExtensibleWithCustomName;
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
getAttrFromPath attrVals attrValues catAttrs filterAttrs
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
genAttrs isDerivation toDerivation optionalAttrs
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
recursiveUpdate matchAttrs overrideExisting getOutput getBin
getLib getDev chooseDevOutputs zipWithNames zip;
inherit (lists) singleton foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists
reverseList listDfs toposort sort take drop sublist last init
crossLists unique intersectLists subtractLists
mutuallyExclusive;
inherit (strings) concatStrings concatMapStrings concatImapStrings
intersperse concatStringsSep concatMapStringsSep
concatImapStringsSep makeSearchPath makeSearchPathOutput
makeLibraryPath makeBinPath makePerlPath optionalString
hasPrefix hasSuffix stringToCharacters stringAsChars escape
escapeShellArg escapeShellArgs replaceChars lowerChars upperChars
toLower toUpper addContextFrom splitString removePrefix
removeSuffix versionOlder versionAtLeast getVersion nameFromURL
enableFeature fixedWidthString fixedWidthNumber isStorePath
toInt readPathsFromFile fileContents;
inherit (stringsWithDeps) textClosureList textClosureMap
noDepEntry fullDepEntry packEntry stringAfter;
inherit (customisation) overrideDerivation makeOverridable
callPackageWith callPackagesWith addPassthru hydraJob makeScope;
inherit (meta) addMetaAttrs dontDistribute setName updateName
appendToName mapDerivationAttrset lowPrio lowPrioSet hiPrio
hiPrioSet;
inherit (sources) pathType pathIsDirectory cleanSourceFilter
cleanSource sourceByRegex sourceFilesBySuffices
commitIdFromGitRepo;
inherit (modules) evalModules closeModules unifyModuleSyntax
applyIfFunction unpackSubmodule packSubmodule mergeModules
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
pushDownProperties dischargeProperties filterOverrides
sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
mkOptionDefault mkDefault mkForce mkVMOverride mkStrict
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule doRename filterModules;
inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption getValues
getFiles optionAttrSetToDocList optionAttrSetToDocList'
scrubOptionValue literalExample showOption showFiles
unknownModule mkOption;
inherit (types) isType setType defaultTypeMerge defaultFunctor
isOptionType mkOptionType;
inherit (debug) addErrorContextToAttrs traceIf traceVal
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
traceValSeqN traceShowVal traceShowValMarked
showVal traceCall traceCall2 traceCall3 traceValIfNot runTests
testAllTrue strict 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;
};
in lib

View File

@ -1,11 +1,12 @@
let lib = import ./default.nix; { lib }:
let
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames; inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
in in
with import ./lists.nix; with lib.lists;
with import ./attrsets.nix; with lib.attrsets;
with import ./strings.nix; with lib.strings;
rec { rec {

View File

@ -1,4 +1,5 @@
# snippets that can be shared by multiple fetchers (pkgs/build-support) # snippets that can be shared by multiple fetchers (pkgs/build-support)
{ lib }:
{ {
proxyImpureEnvVars = [ proxyImpureEnvVars = [

View File

@ -1,3 +1,4 @@
{ lib }:
{ # haskellPathsInDir : Path -> Map String Path { # haskellPathsInDir : Path -> Map String Path
# A map of all haskell packages defined in the given path, # A map of all haskell packages defined in the given path,
# identified by having a cabal file with the same name as the # identified by having a cabal file with the same name as the

View File

@ -1,3 +1,4 @@
{ ... }:
rec { rec {
# Compute the fixed point of the given function `f`, which is usually an # Compute the fixed point of the given function `f`, which is usually an
# attribute set that expects its final, non-recursive representation as an # attribute set that expects its final, non-recursive representation as an

View File

@ -7,10 +7,11 @@
* Tests can be found in ./tests.nix * Tests can be found in ./tests.nix
* Documentation in the manual, #sec-generators * Documentation in the manual, #sec-generators
*/ */
with import ./trivial.nix; { lib }:
with (lib).trivial;
let let
libStr = import ./strings.nix; libStr = lib.strings;
libAttr = import ./attrsets.nix; libAttr = lib.attrsets;
flipMapAttrs = flip libAttr.mapAttrs; flipMapAttrs = flip libAttr.mapAttrs;
in in

View File

@ -1,7 +1,6 @@
{ lib }:
let let
lib = import ./default.nix;
spdx = lic: lic // { spdx = lic: lic // {
url = "http://spdx.org/licenses/${lic.spdxId}"; url = "http://spdx.org/licenses/${lic.spdxId}";
}; };
@ -408,7 +407,7 @@ lib.mapAttrs (n: v: v // { shortName = n; }) rec {
url = "https://raw.githubusercontent.com/raboof/notion/master/LICENSE"; url = "https://raw.githubusercontent.com/raboof/notion/master/LICENSE";
fullName = "Notion modified LGPL"; fullName = "Notion modified LGPL";
}; };
ofl = spdx { ofl = spdx {
spdxId = "OFL-1.1"; spdxId = "OFL-1.1";
fullName = "SIL Open Font License 1.1"; fullName = "SIL Open Font License 1.1";

View File

@ -1,6 +1,6 @@
# General list operations. # General list operations.
{ lib }:
with import ./trivial.nix; with lib.trivial;
rec { rec {

View File

@ -1,3 +1,4 @@
{ ...}:
/* List of NixOS maintainers. The format is: /* List of NixOS maintainers. The format is:
handle = "Real Name <address@example.org>"; handle = "Real Name <address@example.org>";

View File

@ -1,8 +1,7 @@
/* Some functions for manipulating meta attributes, as well as the /* Some functions for manipulating meta attributes, as well as the
name attribute. */ name attribute. */
let lib = import ./default.nix; { lib }:
in
rec { rec {

View File

@ -1,10 +1,12 @@
with import ./lists.nix; { lib }:
with import ./strings.nix;
with import ./trivial.nix; with lib.lists;
with import ./attrsets.nix; with lib.strings;
with import ./options.nix; with lib.trivial;
with import ./debug.nix; with lib.attrsets;
with import ./types.nix; with lib.options;
with lib.debug;
with lib.types;
rec { rec {

View File

@ -1,11 +1,10 @@
# Nixpkgs/NixOS option handling. # Nixpkgs/NixOS option handling.
{ lib }:
let lib = import ./default.nix; in with lib.trivial;
with lib.lists;
with import ./trivial.nix; with lib.attrsets;
with import ./lists.nix; with lib.strings;
with import ./attrsets.nix;
with import ./strings.nix;
rec { rec {

View File

@ -1,4 +1,5 @@
with import ./strings.nix; { lib }:
with lib.strings;
/* Helpers for creating lisp S-exprs for the Apple sandbox /* Helpers for creating lisp S-exprs for the Apple sandbox

View File

@ -1,6 +1,5 @@
# Functions for copying sources to the Nix store. # Functions for copying sources to the Nix store.
{ lib }:
let lib = import ./default.nix; in
rec { rec {

View File

@ -1,3 +1,4 @@
{ lib }:
/* /*
Usage: Usage:
@ -40,9 +41,9 @@ Usage:
[1] maybe this behaviour should be removed to keep things simple (?) [1] maybe this behaviour should be removed to keep things simple (?)
*/ */
with import ./lists.nix; with lib.lists;
with import ./attrsets.nix; with lib.attrsets;
with import ./strings.nix; with lib.strings;
rec { rec {

View File

@ -1,6 +1,6 @@
/* String manipulation functions. */ /* String manipulation functions. */
{ lib }:
let lib = import ./default.nix; let
inherit (builtins) length; inherit (builtins) length;

View File

@ -1,11 +1,12 @@
let inherit (import ../attrsets.nix) mapAttrs; in { lib }:
let inherit (lib.attrsets) mapAttrs; in
rec { rec {
doubles = import ./doubles.nix; doubles = import ./doubles.nix { inherit lib; };
parse = import ./parse.nix; parse = import ./parse.nix { inherit lib; };
inspect = import ./inspect.nix; inspect = import ./inspect.nix { inherit lib; };
platforms = import ./platforms.nix; platforms = import ./platforms.nix { inherit lib; };
examples = import ./examples.nix; examples = import ./examples.nix { inherit lib; };
# Elaborate a `localSystem` or `crossSystem` so that it contains everything # Elaborate a `localSystem` or `crossSystem` so that it contains everything
# necessary. # necessary.

View File

@ -1,8 +1,9 @@
{ lib }:
let let
lists = import ../lists.nix; inherit (lib) lists;
parse = import ./parse.nix; parse = import ./parse.nix { inherit lib; };
inherit (import ./inspect.nix) predicates; inherit (import ./inspect.nix { inherit lib; }) predicates;
inherit (import ../attrsets.nix) matchAttrs; inherit (lib.attrsets) matchAttrs;
all = [ all = [
"aarch64-linux" "aarch64-linux"

View File

@ -1,8 +1,8 @@
# These can be passed to nixpkgs as either the `localSystem` or # These can be passed to nixpkgs as either the `localSystem` or
# `crossSystem`. They are put here for user convenience, but also used by cross # `crossSystem`. They are put here for user convenience, but also used by cross
# tests and linux cross stdenv building, so handle with care! # tests and linux cross stdenv building, so handle with care!
{ lib }:
let platforms = import ./platforms.nix; in let platforms = import ./platforms.nix { inherit lib; }; in
rec { rec {
# #

View File

@ -1,6 +1,7 @@
with import ./parse.nix; { lib }:
with import ../attrsets.nix; with import ./parse.nix { inherit lib; };
with import ../lists.nix; with lib.attrsets;
with lib.lists;
rec { rec {
patterns = rec { patterns = rec {

View File

@ -4,14 +4,13 @@
# http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially # http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially
# Triple::normalize. Parsing should essentially act as a more conservative # Triple::normalize. Parsing should essentially act as a more conservative
# version of that last function. # version of that last function.
{ lib }:
with import ../lists.nix; with lib.lists;
with import ../types.nix; with lib.types;
with import ../attrsets.nix; with lib.attrsets;
with (import ./inspect.nix).predicates; with (import ./inspect.nix { inherit lib; }).predicates;
let let
lib = import ../default.nix;
setTypesAssert = type: pred: setTypesAssert = type: pred:
mapAttrs (name: value: mapAttrs (name: value:
assert pred value; assert pred value;

View File

@ -1,3 +1,4 @@
{ lib }:
rec { rec {
pcBase = { pcBase = {
name = "pc"; name = "pc";

View File

@ -1,3 +1,4 @@
{ lib }:
rec { rec {
/* The identity function /* The identity function
@ -55,7 +56,7 @@ rec {
isInt add sub lessThan isInt add sub lessThan
seq deepSeq genericClosure; seq deepSeq genericClosure;
inherit (import ./strings.nix) fileContents; inherit (lib.strings) fileContents;
# Return the Nixpkgs version number. # Return the Nixpkgs version number.
nixpkgsVersion = nixpkgsVersion =

View File

@ -1,15 +1,16 @@
# Definitions related to run-time type checking. Used in particular # Definitions related to run-time type checking. Used in particular
# to type-check NixOS configurations. # to type-check NixOS configurations.
{ lib }:
with lib.lists;
with lib.attrsets;
with lib.options;
with lib.trivial;
with lib.strings;
let
with import ./lists.nix; inherit (lib.modules) mergeDefinitions filterOverrides;
with import ./attrsets.nix; outer_types =
with import ./options.nix;
with import ./trivial.nix;
with import ./strings.nix;
let inherit (import ./modules.nix) mergeDefinitions filterOverrides; in
rec { rec {
isType = type: x: (x._type or "") == type; isType = type: x: (x._type or "") == type;
setType = typeName: value: value // { setType = typeName: value: value // {
@ -95,7 +96,6 @@ rec {
# When adding new types don't forget to document them in # When adding new types don't forget to document them in
# nixos/doc/manual/development/option-types.xml! # nixos/doc/manual/development/option-types.xml!
types = rec { types = rec {
unspecified = mkOptionType { unspecified = mkOptionType {
name = "unspecified"; name = "unspecified";
}; };
@ -291,7 +291,7 @@ rec {
submodule = opts: submodule = opts:
let let
opts' = toList opts; opts' = toList opts;
inherit (import ./modules.nix) evalModules; inherit (lib.modules) evalModules;
in in
mkOptionType rec { mkOptionType rec {
name = "submodule"; name = "submodule";
@ -395,5 +395,6 @@ rec {
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; }; addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
}; };
};
} in outer_types // outer_types.types