Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
4.9 kB · 153 lines
Nix
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154{ lib, pkgs }:let inherit (lib) types; inherit (types) attrsOf oneOf coercedTo str bool int float package ;in{ javaProperties = { comment ? "Generated with Nix", boolToString ? lib.boolToString, }: {
# Design note: # A nested representation of inevitably leads to bad UX: # 1. keys like "a.b" must be disallowed, or # the addition of options in a freeformType module # become breaking changes # 2. adding a value for "a" after "a"."b" was already # defined leads to a somewhat hard to understand # Nix error, because that's not something you can # do with attrset syntax. Workaround: "a"."", but # that's too little too late. Another workaround: # mkMerge [ { a = ...; } { a.b = ...; } ]. # # Choosing a non-nested representation does mean that # we sacrifice the ability to override at the (conceptual) # hierarchical levels, _if_ an application exhibits those. # # Some apps just use periods instead of spaces in an odd # mix of attempted categorization and natural language, # with no meaningful hierarchy. # # We _can_ choose to support hierarchical config files # via nested attrsets, but the module author should # make sure that problem (2) does not occur. type = let elemType = oneOf ([ # `package` isn't generalized to `path` because path values # are ambiguous. Are they host path strings (toString /foo/bar) # or should they be added to the store? ("${/foo/bar}") # The user must decide. (coercedTo package toString str)
(coercedTo bool boolToString str) (coercedTo int toString str) (coercedTo float toString str) ]) // { description = "string, package, bool, int or float"; }; in attrsOf elemType;
generate = name: value: pkgs.runCommand name { # Requirements # ============ # # 1. Strings in Nix carry over to the same # strings in Java => need proper escapes # 2. Generate files quickly # - A JVM would have to match the app's # JVM to avoid build closure bloat # - Even then, JVM startup would slow # down config generation. # # # Implementation # ============== # # Escaping has two steps # # 1. jq # Escape known separators, in order not # to break up the keys and values. # This handles typical whitespace correctly, # but may produce garbage for other control # characters. # # 2. iconv # Escape >ascii code points to java escapes, # as .properties files are supposed to be # encoded in ISO 8859-1. It's an old format. # UTF-8 behavior may exist in some apps and # libraries, but we can't rely on this in # general.
preferLocalBuild = true; passAsFile = [ "value" ]; value = builtins.toJSON value; nativeBuildInputs = [ pkgs.jq pkgs.libiconvReal ];
jqCode = let main = '' to_entries | .[] | "\( .key | ${commonEscapes} | gsub(" "; "\\ ") | gsub("="; "\\=") ) = \( .value | ${commonEscapes} | gsub("^ "; "\\ ") | gsub("\\n "; "\n\\ ") )" ''; # Most escapes are equal for both keys and values. commonEscapes = '' gsub("\\\\"; "\\\\") | gsub("\\n"; "\\n\\\n") | gsub("#"; "\\#") | gsub("!"; "\\!") | gsub("\\t"; "\\t") | gsub("\r"; "\\r") ''; in main;
inputEncoding = "UTF-8";
inherit comment;
} '' ( echo "$comment" | while read -r ln; do echo "# $ln"; done echo jq -r --arg hash '#' "$jqCode" "$valuePath" \ | iconv --from-code "$inputEncoding" --to-code JAVA \ ) > "$out" ''; };}