diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/default.nix | 3 | ||||
-rw-r--r-- | lib/generators.nix | 72 | ||||
-rw-r--r-- | lib/maintainers.nix | 8 | ||||
-rw-r--r-- | lib/modules.nix | 9 | ||||
-rw-r--r-- | lib/sources.nix | 26 | ||||
-rw-r--r-- | lib/tests.nix | 74 |
6 files changed, 175 insertions, 17 deletions
diff --git a/lib/default.nix b/lib/default.nix index cb9a9b0bd4d0..c0d7899b882a 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -27,6 +27,7 @@ let # misc debug = import ./debug.nix; + generators = import ./generators.nix; misc = import ./deprecated.nix; # domain-specific @@ -39,7 +40,7 @@ in customisation maintainers meta sources modules options types licenses platforms systems - debug misc + debug generators misc sandbox fetchers; } # !!! don't include everything at top-level; perhaps only the most diff --git a/lib/generators.nix b/lib/generators.nix new file mode 100644 index 000000000000..27d4142e8d9a --- /dev/null +++ b/lib/generators.nix @@ -0,0 +1,72 @@ +/* Functions that generate widespread file + * formats from nix data structures. + * + * They all follow a similar interface: + * generator { config-attrs } data + * + * Tests can be found in ./tests.nix + * Documentation in the manual, #sec-generators + */ +with import ./trivial.nix; +let + libStr = import ./strings.nix; + libAttr = import ./attrsets.nix; + + flipMapAttrs = flip libAttr.mapAttrs; +in + +rec { + + /* Generates an INI-style config file from an + * attrset of sections to an attrset of key-value pairs. + * + * generators.toINI {} { + * foo = { hi = "${pkgs.hello}"; ciao = "bar"; }; + * baz = { "also, integers" = 42; }; + * } + * + *> [baz] + *> also, integers=42 + *> + *> [foo] + *> ciao=bar + *> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10 + * + * The mk* configuration attributes can generically change + * the way sections and key-value strings are generated. + * + * For more examples see the test cases in ./tests.nix. + */ + toINI = { + # apply transformations (e.g. escapes) to section names + mkSectionName ? (name: libStr.escape [ "[" "]" ] name), + # format a setting line from key and value + mkKeyValue ? (k: v: "${libStr.escape ["="] k}=${toString v}") + }: attrsOfAttrs: + let + # map function to string for each key val + mapAttrsToStringsSep = sep: mapFn: attrs: + libStr.concatStringsSep sep + (libAttr.mapAttrsToList mapFn attrs); + mkLine = k: v: mkKeyValue k v + "\n"; + mkSection = sectName: sectValues: '' + [${mkSectionName sectName}] + '' + libStr.concatStrings (libAttr.mapAttrsToList mkLine sectValues); + in + # map input to ini sections + mapAttrsToStringsSep "\n" mkSection attrsOfAttrs; + + + /* Generates JSON from an arbitrary (non-function) value. + * For more information see the documentation of the builtin. + */ + toJSON = {}: builtins.toJSON; + + + /* YAML has been a strict superset of JSON since 1.2, so we + * use toJSON. Before it only had a few differences referring + * to implicit typing rules, so it should work with older + * parsers as well. + */ + toYAML = {}@args: toJSON args; +} diff --git a/lib/maintainers.nix b/lib/maintainers.nix index b15f4542fb55..b908a261b1fa 100644 --- a/lib/maintainers.nix +++ b/lib/maintainers.nix @@ -48,6 +48,7 @@ aske = "Kirill Boltaev <aske@fmap.me>"; asppsa = "Alastair Pharo <asppsa@gmail.com>"; astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>"; + asymmetric = "Lorenzo Manacorda <lorenzo@mailbox.org>"; aszlig = "aszlig <aszlig@redmoonstudios.org>"; auntie = "Jonathan Glines <auntieNeo@gmail.com>"; avnik = "Alexander V. Nikolaev <avn@avnik.info>"; @@ -88,6 +89,7 @@ chris-martin = "Chris Martin <ch.martin@gmail.com>"; chrisjefferson = "Christopher Jefferson <chris@bubblescope.net>"; christopherpoole = "Christopher Mark Poole <mail@christopherpoole.net>"; + ckampka = "Christian Kampka <christian@kampka.net>"; cko = "Christine Koppelt <christine.koppelt@gmail.com>"; cleverca22 = "Michael Bishop <cleverca22@gmail.com>"; cmcdragonkai = "Roger Qiu <roger.qiu@matrix.ai>"; @@ -129,6 +131,7 @@ doublec = "Chris Double <chris.double@double.co.nz>"; drets = "Dmytro Rets <dmitryrets@gmail.com>"; drewkett = "Andrew Burkett <burkett.andrew@gmail.com>"; + dtzWill = "Will Dietz <nix@wdtz.org>"; ebzzry = "Rommel Martinez <ebzzry@gmail.com>"; ederoyd46 = "Matthew Brown <matt@ederoyd.co.uk>"; eduarrrd = "Eduard Bachmakov <e.bachmakov@gmail.com>"; @@ -198,8 +201,10 @@ jagajaga = "Arseniy Seroka <ars.seroka@gmail.com>"; javaguirre = "Javier Aguirre <contacto@javaguirre.net>"; jb55 = "William Casarin <bill@casarin.me>"; + jbedo = "Justin Bedő <cu@cua0.org>"; jcumming = "Jack Cummings <jack@mudshark.org>"; jefdaj = "Jeffrey David Johnson <jefdaj@gmail.com>"; + jerith666 = "Matt McHenry <github@matt.mchenryfamily.org>"; jfb = "James Felix Black <james@yamtime.com>"; jgeerds = "Jascha Geerds <jascha@jgeerds.name>"; jgillich = "Jakob Gillich <jakob@gillich.me>"; @@ -273,6 +278,7 @@ mdaiter = "Matthew S. Daiter <mdaiter8121@gmail.com>"; meditans = "Carlo Nucera <meditans@gmail.com>"; meisternu = "Matt Miemiec <meister@krutt.org>"; + mguentner = "Maximilian Güntner <code@klandest.in>"; mic92 = "Jörg Thalheim <joerg@higgsboson.tk>"; michaelpj = "Michael Peyton Jones <michaelpj@gmail.com>"; michalrus = "Michal Rus <m@michalrus.com>"; @@ -285,6 +291,7 @@ mlieberman85 = "Michael Lieberman <mlieberman85@gmail.com>"; modulistic = "Pablo Costa <modulistic@gmail.com>"; mog = "Matthew O'Gorman <mog-lists@rldn.net>"; + montag451 = "montag451 <montag451@laposte.net>"; moosingin3space = "Nathan Moos <moosingin3space@gmail.com>"; moretea = "Maarten Hoogendoorn <maarten@moretea.nl>"; mornfall = "Petr Ročkai <me@mornfall.net>"; @@ -330,6 +337,7 @@ palo = "Ingolf Wanger <palipalo9@googlemail.com>"; pashev = "Igor Pashev <pashev.igor@gmail.com>"; pawelpacana = "Paweł Pacana <pawel.pacana@gmail.com>"; + periklis = "theopompos@gmail.com"; pesterhazy = "Paulus Esterhazy <pesterhazy@gmail.com>"; peterhoeg = "Peter Hoeg <peter@hoeg.com>"; peti = "Peter Simons <simons@cryp.to>"; diff --git a/lib/modules.nix b/lib/modules.nix index e66d6a6926cb..256d49ba27d8 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -375,10 +375,13 @@ rec { if def._type or "" == "merge" then concatMap dischargeProperties def.contents else if def._type or "" == "if" then - if def.condition then - dischargeProperties def.content + if isBool def.condition then + if def.condition then + dischargeProperties def.content + else + [ ] else - [ ] + throw "‘mkIf’ called with a non-Boolean condition" else [ def ]; diff --git a/lib/sources.nix b/lib/sources.nix index 156afaae5c98..f41abe1e1eae 100644 --- a/lib/sources.nix +++ b/lib/sources.nix @@ -12,19 +12,19 @@ rec { # Bring in a path as a source, filtering out all Subversion and CVS # directories, as well as backup files (*~). - cleanSource = - let filter = name: type: let baseName = baseNameOf (toString name); in ! ( - # Filter out Subversion and CVS directories. - (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) || - # Filter out backup files. - lib.hasSuffix "~" baseName || - # Filter out generates files. - lib.hasSuffix ".o" baseName || - lib.hasSuffix ".so" baseName || - # Filter out nix-build result symlinks - (type == "symlink" && lib.hasPrefix "result" baseName) - ); - in src: builtins.filterSource filter src; + cleanSourceFilter = name: type: let baseName = baseNameOf (toString name); in ! ( + # Filter out Subversion and CVS directories. + (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) || + # Filter out backup files. + lib.hasSuffix "~" baseName || + # Filter out generates files. + lib.hasSuffix ".o" baseName || + lib.hasSuffix ".so" baseName || + # Filter out nix-build result symlinks + (type == "symlink" && lib.hasPrefix "result" baseName) + ); + + cleanSource = builtins.filterSource cleanSourceFilter; # Get all files ending with the specified suffices from the given diff --git a/lib/tests.nix b/lib/tests.nix index c3b8839fda95..d59814987ed6 100644 --- a/lib/tests.nix +++ b/lib/tests.nix @@ -130,4 +130,78 @@ runTests { expected = false; }; + + /* Generator tests */ + # these tests assume attributes are converted to lists + # in alphabetical order + + testToINIEmpty = { + expr = generators.toINI {} {}; + expected = ""; + }; + + testToINIEmptySection = { + expr = generators.toINI {} { foo = {}; bar = {}; }; + expected = '' + [bar] + + [foo] + ''; + }; + + testToINIDefaultEscapes = { + expr = generators.toINI {} { + "no [ and ] allowed unescaped" = { + "and also no = in keys" = 42; + }; + }; + expected = '' + [no \[ and \] allowed unescaped] + and also no \= in keys=42 + ''; + }; + + testToINIDefaultFull = { + expr = generators.toINI {} { + "section 1" = { + attribute1 = 5; + x = "Me-se JarJar Binx"; + }; + "foo[]" = { + "he\\h=he" = "this is okay"; + }; + }; + expected = '' + [foo\[\]] + he\h\=he=this is okay + + [section 1] + attribute1=5 + x=Me-se JarJar Binx + ''; + }; + + /* right now only invocation check */ + testToJSONSimple = + let val = { + foobar = [ "baz" 1 2 3 ]; + }; + in { + expr = generators.toJSON {} val; + # trival implementation + expected = builtins.toJSON val; + }; + + /* right now only invocation check */ + testToYAMLSimple = + let val = { + list = [ { one = 1; } { two = 2; } ]; + all = 42; + }; + in { + expr = generators.toYAML {} val; + # trival implementation + expected = builtins.toJSON val; + }; + } |