pkgs-lib.formats.xml: init (#342633)

authored by Silvan Mosberger and committed by GitHub 4fbf6bf1 77156bcc

+102
+15
nixos/doc/manual/development/settings-options.section.md
··· 343 343 and returning a set with TOML-specific attributes `type` and 344 344 `generate` as specified [below](#pkgs-formats-result). 345 345 346 + `pkgs.formats.xml` { format ? "badgerfish", withHeader ? true} 347 + 348 + : A function taking an attribute set with values 349 + and returning a set with XML-specific attributes `type` and 350 + `generate` as specified [below](#pkgs-formats-result). 351 + 352 + `format` 353 + 354 + : Input format. Because XML can not be translated one-to-one, we have to use intermediate formats. Possible values: 355 + - `"badgerfish"`: Uses [badgerfish](http://www.sklar.com/badgerfish/) conversion. 356 + 357 + `withHeader` 358 + 359 + : Outputs the xml with header. 360 + 346 361 `pkgs.formats.cdn` { } 347 362 348 363 : A function taking an empty attribute set (for future extensibility)
+60
pkgs/pkgs-lib/formats.nix
··· 577 577 '') {}; 578 578 }; 579 579 580 + xml = 581 + { 582 + format ? "badgerfish", 583 + withHeader ? true, 584 + }: 585 + if format == "badgerfish" then 586 + { 587 + type = let 588 + valueType = nullOr (oneOf [ 589 + bool 590 + int 591 + float 592 + str 593 + path 594 + (attrsOf valueType) 595 + (listOf valueType) 596 + ]) // { 597 + description = "XML value"; 598 + }; 599 + in valueType; 600 + 601 + generate = 602 + name: value: 603 + pkgs.callPackage ( 604 + { 605 + runCommand, 606 + python3, 607 + libxml2Python, 608 + }: 609 + runCommand name 610 + { 611 + nativeBuildInputs = [ 612 + python3 613 + python3.pkgs.xmltodict 614 + libxml2Python 615 + ]; 616 + value = builtins.toJSON value; 617 + pythonGen = '' 618 + import json 619 + import os 620 + import xmltodict 621 + 622 + with open(os.environ["valuePath"], "r") as f: 623 + print(xmltodict.unparse(json.load(f), full_document=${toString withHeader}, pretty=True, indent=" " * 2)) 624 + ''; 625 + passAsFile = [ 626 + "value" 627 + "pythonGen" 628 + ]; 629 + preferLocalBuild = true; 630 + } 631 + '' 632 + python3 "$pythonGenPath" > $out 633 + xmllint $out > /dev/null 634 + '' 635 + ) { }; 636 + } 637 + else 638 + throw "pkgs.formats.xml: Unknown format: ${format}"; 639 + 580 640 }
+27
pkgs/pkgs-lib/tests/formats.nix
··· 644 644 ''; 645 645 }; 646 646 647 + badgerfishToXmlGenerate = shouldPass { 648 + format = formats.xml { }; 649 + input = { 650 + root = { 651 + "@id" = "123"; 652 + "@class" = "example"; 653 + child1 = { 654 + "@name" = "child1Name"; 655 + "#text" = "text node"; 656 + }; 657 + child2 = { 658 + grandchild = "This is a grandchild text node."; 659 + }; 660 + nulltest = null; 661 + }; 662 + }; 663 + expected = '' 664 + <?xml version="1.0" encoding="utf-8"?> 665 + <root class="example" id="123"> 666 + <child1 name="child1Name">text node</child1> 667 + <child2> 668 + <grandchild>This is a grandchild text node.</grandchild> 669 + </child2> 670 + <nulltest></nulltest> 671 + </root> 672 + ''; 673 + }; 647 674 }