diff --git a/go.mod b/go.mod index 8e52e0dd73..9a172caa3f 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,6 @@ require ( github.com/go-openapi/strfmt v0.23.0 github.com/go-openapi/swag v0.23.0 github.com/go-test/deep v1.1.0 - github.com/goccy/go-yaml v1.11.3 github.com/golang/mock v1.6.0 github.com/google/go-github/v45 v45.2.0 github.com/hashicorp/vault-client-go v0.4.3 @@ -46,6 +45,7 @@ require ( github.com/mandelsoft/spiff v1.7.0-beta-5 github.com/mandelsoft/vfs v0.4.3 github.com/marstr/guid v1.1.0 + github.com/mikefarah/yq/v4 v4.43.1 github.com/mitchellh/copystructure v1.2.0 github.com/mittwald/go-helm-client v0.12.9 github.com/modern-go/reflect2 v1.0.2 @@ -70,6 +70,7 @@ require ( golang.org/x/net v0.24.0 golang.org/x/oauth2 v0.19.0 golang.org/x/text v0.14.0 + gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.4 k8s.io/api v0.30.0 @@ -106,6 +107,8 @@ require ( github.com/Microsoft/hcsshim v0.12.0-rc.3 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect + github.com/a8m/envsubst v1.4.2 // indirect + github.com/alecthomas/participle/v2 v2.1.1 // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect github.com/alibabacloud-go/cr-20181201 v1.0.10 // indirect @@ -163,6 +166,7 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/elliotchance/orderedmap v1.5.1 // indirect github.com/emicklei/go-restful/v3 v3.11.1 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect @@ -187,6 +191,8 @@ require ( github.com/go-openapi/validate v0.24.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-yaml v1.11.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -222,6 +228,7 @@ require ( github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect + github.com/jinzhu/copier v0.4.0 // indirect github.com/jinzhu/gorm v1.9.16 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect @@ -259,7 +266,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.19.0 // indirect @@ -300,6 +307,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xlab/treeprint v1.2.0 // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect github.com/zeebo/errs v1.3.0 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect go.opencensus.io v0.24.0 // indirect diff --git a/go.sum b/go.sum index ab6ce0c20c..97c9e3c82d 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,16 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/O github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E= github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR2E23+wTQe/MlE= +github.com/a8m/envsubst v1.4.2 h1:4yWIHXOLEJHQEFd4UjrWDrYeYlV7ncFWJOCBRLOZHQg= +github.com/a8m/envsubst v1.4.2/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= +github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= +github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= +github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= @@ -337,6 +345,8 @@ github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/elliotchance/orderedmap v1.5.1 h1:G1X4PYlljzimbdQ3RXmtIZiQ9d6aRQ3sH1nzjq5mECE= +github.com/elliotchance/orderedmap v1.5.1/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys= github.com/emicklei/go-restful/v3 v3.11.1 h1:S+9bSbua1z3FgCnV0KKOSSZ3mDthb5NyEPL5gEpCvyk= github.com/emicklei/go-restful/v3 v3.11.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/proto v1.12.1 h1:6n/Z2pZAnBwuhU66Gs8160B8rrrYKo7h2F2sCOnNceE= @@ -442,6 +452,8 @@ github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= @@ -581,6 +593,8 @@ github.com/hashicorp/vault-client-go v0.4.3 h1:zG7STGVgn/VK6rnZc0k8PGbfv2x/sJExR github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j4sB9cp0T7U6m4FzDY= github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE= github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef h1:A9HsByNhogrvm9cWb28sjiS3i7tcKCkflWFEkHfuAgM= github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -600,6 +614,8 @@ github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE= github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= @@ -695,6 +711,8 @@ github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mikefarah/yq/v4 v4.43.1 h1:1bCrQwVDhjGnPboQidy30hu6U2TCd8sUQTy1hKCHOGI= +github.com/mikefarah/yq/v4 v4.43.1/go.mod h1:jcSqtyUKbPWvwaa8cNw8Ej4rmPb3iWE8zYvpkTvM7oc= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -783,14 +801,16 @@ github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -984,6 +1004,8 @@ github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE= @@ -1258,6 +1280,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 h1:6D+BvnJ/j6e222UW8s2qTSe3wGBtvo0MbVQG/c5k8RE= +gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473/go.mod h1:N1eN2tsCx0Ydtgjl4cqmbRCsY4/+z4cYDeqwZTk6zog= gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM= gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/pkg/contexts/ocm/utils/localize/instantiate_test.go b/pkg/contexts/ocm/utils/localize/instantiate_test.go index 1117258fbf..09d86e0c27 100644 --- a/pkg/contexts/ocm/utils/localize/instantiate_test.go +++ b/pkg/contexts/ocm/utils/localize/instantiate_test.go @@ -130,7 +130,7 @@ values: fs := memoryfs.New() err := localize.Instantiate(rules, cv, nil, config, fs, RESOURCE_TYPE) Expect(err).To(Succeed()) - CheckFile("dir/manifest1.yaml", fs, ` + CheckYAMLFile("dir/manifest1.yaml", fs, ` manifest: value1: ghcr.io/mandelsoft/test:v1 value2: mine diff --git a/pkg/contexts/ocm/utils/localize/subst.go b/pkg/contexts/ocm/utils/localize/subst.go index b0c9a6f951..10ddb51078 100644 --- a/pkg/contexts/ocm/utils/localize/subst.go +++ b/pkg/contexts/ocm/utils/localize/subst.go @@ -5,8 +5,6 @@ package localize import ( - yaml "github.com/goccy/go-yaml" - "github.com/goccy/go-yaml/ast" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/errors" @@ -72,6 +70,10 @@ func SubstituteMappingsForData(subs ValueMappings, data []byte) ([]byte, error) return target.Content() } +/* +2024-04-28 Don't see any use of this in either ocm or ocm-controller +As it exposes the implementation detail of what YAML model we use +_and_ we're switching to yqlib from goccy comment it out. func Set(content *ast.File, path string, value *ast.File) error { p, err := yaml.PathString("$." + path) if err != nil { @@ -79,3 +81,4 @@ func Set(content *ast.File, path string, value *ast.File) error { } return p.ReplaceWithFile(content, value) } +*/ diff --git a/pkg/contexts/ocm/utils/localize/subst_test.go b/pkg/contexts/ocm/utils/localize/subst_test.go index 4a08a29f9a..292e3c491c 100644 --- a/pkg/contexts/ocm/utils/localize/subst_test.go +++ b/pkg/contexts/ocm/utils/localize/subst_test.go @@ -48,12 +48,12 @@ var _ = Describe("value substitution in filesystem", func() { err := localize.Substitute(subs, payloadfs) Expect(err).To(Succeed()) - CheckFile("dir/manifest1.yaml", payloadfs, ` + CheckYAMLFile("dir/manifest1.yaml", payloadfs, ` manifest: value1: config1 value2: orig2 `) - CheckFile("dir/manifest2.yaml", payloadfs, ` + CheckYAMLFile("dir/manifest2.yaml", payloadfs, ` manifest: value1: orig1 value2: config2 @@ -74,7 +74,7 @@ manifest: err := localize.Substitute(subs, payloadfs) Expect(err).To(Succeed()) - CheckFile("dir/manifest1.yaml", payloadfs, ` + CheckYAMLFile("dir/manifest1.yaml", payloadfs, ` manifest: value1: config1 value2: config2 @@ -93,7 +93,7 @@ manifest: err := localize.Substitute(subs, payloadfs) Expect(err).To(Succeed()) - CheckFile("dir/some.json", payloadfs, ` + CheckJSONFile("dir/some.json", payloadfs, ` {"manifest": {"value1": {"some": {"value": 1}}, "value2": "orig2"}} `) diff --git a/pkg/contexts/ocm/utils/localize/target_test.go b/pkg/contexts/ocm/utils/localize/target_test.go index c46ffbe808..b22fb86166 100644 --- a/pkg/contexts/ocm/utils/localize/target_test.go +++ b/pkg/contexts/ocm/utils/localize/target_test.go @@ -7,7 +7,6 @@ package localize_test import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - . "github.com/open-component-model/ocm/pkg/testutils" "github.com/mandelsoft/vfs/pkg/vfs" @@ -127,7 +126,7 @@ manifest: result, err := localize.SubstituteMappingsForData(subs, data) Expect(err).To(Succeed()) - Expect(string(result)).To(StringEqualTrimmedWithContext(` + Expect(string(result)).To(MatchYAML(` manifest: value1: config1 value2: config2 @@ -145,7 +144,7 @@ manifest: result, err := localize.SubstituteMappingsForData(subs, data) Expect(err).To(Succeed()) - Expect(string(result)).To(StringEqualTrimmedWithContext(` + Expect(string(result)).To(MatchYAML(` manifest: value1: some: diff --git a/pkg/contexts/ocm/utils/localize/utils_test.go b/pkg/contexts/ocm/utils/localize/utils_test.go index 2acb56337f..939e90bf47 100644 --- a/pkg/contexts/ocm/utils/localize/utils_test.go +++ b/pkg/contexts/ocm/utils/localize/utils_test.go @@ -5,9 +5,6 @@ package localize_test import ( - "fmt" - "strings" - . "github.com/onsi/gomega" "github.com/mandelsoft/vfs/pkg/vfs" @@ -52,9 +49,14 @@ func UnmarshalInstRules(data string) *localize.InstantiationRules { return &v } -func CheckFile(path string, fs vfs.FileSystem, content string) { +func CheckYAMLFile(path string, fs vfs.FileSystem, content string) { + data, err := vfs.ReadFile(fs, path) + ExpectWithOffset(1, err).To(Succeed()) + ExpectWithOffset(1, string(data)).To(MatchYAML(content)) +} + +func CheckJSONFile(path string, fs vfs.FileSystem, content string) { data, err := vfs.ReadFile(fs, path) ExpectWithOffset(1, err).To(Succeed()) - fmt.Printf("\n%s\n", string(data)) - ExpectWithOffset(1, strings.Trim(string(data), "\n")).To(Equal(strings.Trim(content, "\n"))) + ExpectWithOffset(1, string(data)).To(MatchJSON(content)) } diff --git a/pkg/utils/subst/subst.go b/pkg/utils/subst/subst.go index b89e7e9685..8eec669dc5 100644 --- a/pkg/utils/subst/subst.go +++ b/pkg/utils/subst/subst.go @@ -5,12 +5,18 @@ package subst import ( - "github.com/goccy/go-yaml" - "github.com/goccy/go-yaml/ast" - "github.com/goccy/go-yaml/parser" + "bytes" + "container/list" + "sync" + + mlog "github.com/mandelsoft/logging" "github.com/mandelsoft/vfs/pkg/vfs" + "github.com/mikefarah/yq/v4/pkg/yqlib" + glog "gopkg.in/op/go-logging.v1" + "gopkg.in/yaml.v3" "github.com/open-component-model/ocm/pkg/errors" + ocmlog "github.com/open-component-model/ocm/pkg/logging" "github.com/open-component-model/ocm/pkg/runtime" "github.com/open-component-model/ocm/pkg/utils" ) @@ -36,110 +42,156 @@ func ParseFile(file string, fss ...vfs.FileSystem) (SubstitutionTarget, error) { return s, nil } +var yqLibLogInit sync.Once + func Parse(data []byte) (SubstitutionTarget, error) { + yqLibLogInit.Do(func() { + var lvl glog.Level + switch ocmlog.Context().GetDefaultLevel() { + case mlog.None: + fallthrough + case mlog.ErrorLevel: + lvl = glog.ERROR + case mlog.WarnLevel: + lvl = glog.WARNING + case mlog.InfoLevel: + lvl = glog.INFO + case mlog.DebugLevel: + fallthrough + case mlog.TraceLevel: + lvl = glog.DEBUG + } + glog.SetLevel(lvl, "yq-lib") + }) + var ( - err error - content interface{} - fi fileinfo + err error + fi fileinfo ) fi.json = true - if err = runtime.DefaultJSONEncoding.Unmarshal(data, &content); err != nil { + rdr := bytes.NewBuffer(data) + jsnDcdr := yqlib.NewJSONDecoder() + + if err := jsnDcdr.Init(rdr); err != nil { + return nil, err + } + + if fi.content, err = jsnDcdr.Decode(); err != nil { fi.json = false - if err = runtime.DefaultYAMLEncoding.Unmarshal(data, &content); err != nil { - return nil, errors.Wrapf(err, "no yaml or json data") + ymlPrfs := yqlib.NewDefaultYamlPreferences() + ymlDcdr := yqlib.NewYamlDecoder(ymlPrfs) + rdr = bytes.NewBuffer(data) + if err := ymlDcdr.Init(rdr); err != nil { + return nil, err + } + if fi.content, err = ymlDcdr.Decode(); err != nil { + return nil, err } - data, err = runtime.DefaultYAMLEncoding.Marshal(content) - } else { - data, err = runtime.DefaultJSONEncoding.Marshal(content) - } - if err != nil { - return nil, errors.Wrapf(err, "cannor marshal data") } - // mixed json/yaml cannot be parsed, modified and marshalled again, correctly - // so try to come with pure yaml or pure json. - fi.content, err = parser.ParseBytes(data, 0) - if err != nil { - return nil, errors.Wrapf(err, "invalid YAML") - } + fi.content.SetDocument(0) + fi.content.SetFilename("substitution-target") + fi.content.SetFileIndex(0) + return &fi, nil } type fileinfo struct { - content *ast.File + content *yqlib.CandidateNode json bool } func (f *fileinfo) Content() ([]byte, error) { - data := []byte(f.content.String()) - + var enc yqlib.Encoder if f.json { - // TODO: the package seems to keep the file type json/yaml, but I'm not sure - var err error - data, err = yaml.YAMLToJSON(data) - if err != nil { - return nil, errors.Wrapf(err, "cannot marshal json") - } + prfs := yqlib.NewDefaultJsonPreferences() + prfs.ColorsEnabled = false + enc = yqlib.NewJSONEncoder(prfs) + } else { + prfs := yqlib.NewDefaultYamlPreferences() + enc = yqlib.NewYamlEncoder(prfs) } - return data, nil -} -func (f *fileinfo) SubstituteByData(path string, value []byte) error { - var m interface{} - err := runtime.DefaultYAMLEncoding.Unmarshal(value, &m) - if err != nil { - return err - } - if f.json { - value, err = runtime.DefaultJSONEncoding.Marshal(m) + buf := bytes.NewBuffer([]byte{}) + pw := yqlib.NewSinglePrinterWriter(buf) + p := yqlib.NewPrinter(enc, pw) + inptLst := list.New() + inptLst.PushBack(f.content) + + if err := p.PrintResults(inptLst); err == nil { + return buf.Bytes(), nil } else { - value, err = runtime.DefaultYAMLEncoding.Marshal(m) + return nil, err } - if err != nil { - return err - } - return f.substituteByData(path, value) } -func (f *fileinfo) substituteByData(path string, value []byte) error { - file, err := parser.ParseBytes(value, 0) +func (f *fileinfo) SubstituteByData(path string, value []byte) error { + m := &yaml.Node{} + err := yaml.Unmarshal(value, m) if err != nil { - return errors.Wrapf(err, "cannot unmarshal value") + return err } - p, err := yaml.PathString("$." + path) - if err != nil { - return errors.Wrapf(err, "invalid substitution path") + if !f.json { + var replaceFlowStyle func(*yaml.Node) + replaceFlowStyle = func(nd *yaml.Node) { + if nd.Style == yaml.FlowStyle { + nd.Style = yaml.LiteralStyle + } + for _, chld := range nd.Content { + replaceFlowStyle(chld) + } + } + replaceFlowStyle(m) } - return p.ReplaceWithFile(f.content, file) + nd := &yqlib.CandidateNode{} + nd.SetDocument(0) + nd.SetFilename("value") + nd.SetFileIndex(0) + + if err = nd.UnmarshalYAML(m.Content[0], map[string]*yqlib.CandidateNode{}); err != nil { + return err + } + return f.substituteByValue(path, nd) } func (f *fileinfo) SubstituteByValue(path string, value interface{}) error { - var ( - err error - data []byte - ) + var mrshl func(interface{}) ([]byte, error) + if f.json { - data, err = runtime.DefaultJSONEncoding.Marshal(value) + mrshl = runtime.DefaultJSONEncoding.Marshal } else { - data, err = runtime.DefaultYAMLEncoding.Marshal(value) + mrshl = runtime.DefaultYAMLEncoding.Marshal } + + if bval, err := mrshl(value); err != nil { + return err + } else { + return f.SubstituteByData(path, bval) + } +} + +func (f *fileinfo) substituteByValue(path string, value *yqlib.CandidateNode) error { + inptLst := list.New() + inptLst.PushBack(f.content) + + vlLst := list.New() + vlLst.PushBack(value) + + ctxt := yqlib.Context{MatchingNodes: inptLst} + ctxt.SetVariable("newValue", vlLst) + + yqlib.InitExpressionParser() + expr := "." + path + " |= $newValue" + + nd, err := yqlib.ExpressionParser.ParseExpression(expr) if err != nil { return err } - return f.substituteByData(path, data) - /* - node, err := yaml.ValueToNode(value) - if err != nil { - return errors.Wrapf(err, "cannot unmarshal value") - } - p, err := yaml.PathString("$." + path) - if err != nil { - return errors.Wrapf(err, "invalid substitution path") - } - return p.ReplaceWithNode(f.content, node) - */ + ngvtr := yqlib.NewDataTreeNavigator() + _, err = ngvtr.GetMatchingNodes(ctxt, nd) + return err } diff --git a/pkg/utils/subst/subst_test.go b/pkg/utils/subst/subst_test.go index 734a2e3880..2cecebb199 100644 --- a/pkg/utils/subst/subst_test.go +++ b/pkg/utils/subst/subst_test.go @@ -5,9 +5,6 @@ package subst import ( - "fmt" - "strings" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -33,14 +30,79 @@ data: result, err := content.Content() Expect(err).To(Succeed()) - Expect(strings.Trim(string(result), "\n")).To(Equal(strings.Trim(` + Expect(string(result)).To(MatchYAML(` data: value1: v1 value2: orig2 -`, "\n"))) +`)) + }) + + It("handles simple block value substitution on yaml", func() { + data := ` +data: + value1: null + value2: orig2 +` + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByValue("data.value1", `-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE-----`)).To(Succeed()) + + result, err := content.Content() + Expect(err).To(Succeed()) + + expected := ` +data: + value1: |- + -----BEGIN CERTIFICATE----- + MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh + MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 + d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH + MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT + MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j + b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG + 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI + 2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx + 1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ + q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz + tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ + vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP + BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV + 5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY + 1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 + NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG + Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 + 8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe + pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl + MrY= + -----END CERTIFICATE----- + value2: orig2 +` + Expect(string(result)).To(MatchYAML(expected)) }) - It("handles complex value substitution on yaml", func() { + It("handles complex value substitution on yaml 1", func() { data := ` data: value1: orig1 @@ -54,14 +116,13 @@ data: result, err := content.Content() Expect(err).To(Succeed()) - fmt.Printf("\n%s\n", string(result)) - Expect(strings.Trim(string(result), "\n")).To(Equal(strings.Trim(` + Expect(string(result)).To(MatchYAML(` data: value1: value1: v1 value2: "" value2: orig2 -`, "\n"))) +`)) }) }) @@ -80,14 +141,132 @@ data: result, err := content.Content() Expect(err).To(Succeed()) - Expect(strings.Trim(string(result), "\n")).To(Equal(strings.Trim(` + Expect(string(result)).To(MatchYAML(` data: value1: v1 value2: orig2 -`, "\n"))) +`)) + }) + + It("open-component-model/ocm-project issue 179 store object produces invalid yaml", func() { + value := `certificate_authority_url: https://example1.com/v1/pki/root/ca/pem +deployment: deveaws +deployment_size: xsmall +domain: example2.com +landscape_region: eu12 +org: deveaws +service_hostname_suffix: .example3.com +service_kubernetes_hostname_suffix: .example4.com +space: sac` + data := `dmi: + gcp_project_id: unset + orca_env_stable_values: {} + protect_persisted_data: ""` + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByData("dmi.orca_env_stable_values", []byte(value))).To(Succeed()) + + result, err := content.Content() + Expect(err).To(Succeed()) + + expected := `dmi: + gcp_project_id: unset + orca_env_stable_values: + certificate_authority_url: https://example1.com/v1/pki/root/ca/pem + deployment: deveaws + deployment_size: xsmall + domain: example2.com + landscape_region: eu12 + org: deveaws + service_hostname_suffix: .example3.com + service_kubernetes_hostname_suffix: .example4.com + space: sac + protect_persisted_data: ""` + Expect(string(result)).To(MatchYAML(expected)) + }) + + It("Converts json subtitution to yaml when destination is yaml doc", func() { + value := `{ + "certificate_authority_url": "https://example1.com/v1/pki/root/ca/pem", + "deployment": "deveaws", + "deployment_size": "xsmall", + "domain": "example2.com", + "landscape_region": "eu12", + "org": "deveaws", + "service_hostname_suffix": ".example3.com", + "service_kubernetes_hostname_suffix": ".example4.com", + "space": "sac" +}` + data := `dmi: + gcp_project_id: unset + orca_env_stable_values: {} + protect_persisted_data: ""` + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByData("dmi.orca_env_stable_values", []byte(value))).To(Succeed()) + + result, err := content.Content() + Expect(err).To(Succeed()) + + expected := `dmi: + gcp_project_id: unset + orca_env_stable_values: + certificate_authority_url: https://example1.com/v1/pki/root/ca/pem + deployment: deveaws + deployment_size: xsmall + domain: example2.com + landscape_region: eu12 + org: deveaws + service_hostname_suffix: .example3.com + service_kubernetes_hostname_suffix: .example4.com + space: sac + protect_persisted_data: ""` + Expect(string(result)).To(MatchYAML(expected)) + + Expect(string(result)).To(Not(ContainSubstring("{"))) + }) + + It("Store sequence in yaml", func() { + value := `- https://example1.com/v1/pki/root/ca/pem +- deveaws +- xsmall +- example2.com +- eu12 +- deveaws +- .example3.com +- .example4.com +- sac` + data := `dmi: + gcp_project_id: unset + orca_env_stable_values: [] + protect_persisted_data: ""` + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByData("dmi.orca_env_stable_values", []byte(value))).To(Succeed()) + + result, err := content.Content() + Expect(err).To(Succeed()) + + expected := `dmi: + gcp_project_id: unset + orca_env_stable_values: + - https://example1.com/v1/pki/root/ca/pem + - deveaws + - xsmall + - example2.com + - eu12 + - deveaws + - .example3.com + - .example4.com + - sac + protect_persisted_data: ""` + Expect(string(result)).To(MatchYAML(expected)) }) - It("handles complex value substitution on yaml", func() { + It("handles complex value substitution on yaml 2", func() { value := ` value1: v1 value2: "" @@ -105,17 +284,127 @@ data: result, err := content.Content() Expect(err).To(Succeed()) - fmt.Printf("\n%s\n", string(result)) - Expect(strings.Trim(string(result), "\n")).To(Equal(strings.Trim(` + Expect(string(result)).To(MatchYAML(` data: value1: value1: v1 value2: "" value2: orig2 -`, "\n"))) +`)) }) }) + It("handles differing string styles", func() { + value := `folded: > + foo + bar +folded_strip: >- + foo + bar +folded_keep: >+ + foo + bar +literal: | + foo + bar +literal_strip: |- + foo + bar +literal_keep: |+ + foo + bar +double: "foo\nbar" +single: 'foo\nbar'` + data := `data: + value1: origs1 + value2: orig2` + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByData("data.value1", []byte(value))).To(Succeed()) + + result, err := content.Content() + Expect(err).To(Succeed()) + + Expect(string(result)).To(MatchYAML(`data: + value1: + folded: > + foo + bar + folded_strip: >- + foo + bar + folded_keep: >+ + foo + bar + literal: | + foo + bar + literal_strip: |- + foo + bar + literal_keep: |+ + foo + bar + double: "foo\nbar" + single: 'foo\nbar' + value2: orig2`)) + }) + + It("handles non-string scalar", func() { + value := `2` + + data := `data: + value1: orig1 + value2: orig2` + + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByData("data.value1", []byte(value))).To(Succeed()) + + result, err := content.Content() + Expect(err).To(Succeed()) + expected := `data: + value1: 2 + value2: orig2` + + Expect(string(result)).To(MatchYAML(expected)) + }) + + It("handles multiple updates", func() { + value1 := `2` + value2 := `3` + + data := `data: + value1: orig1 + value2: orig2` + + content, err := Parse([]byte(data)) + Expect(err).To(Succeed()) + + Expect(content.SubstituteByData("data.value1", []byte(value1))).To(Succeed()) + + result1, err := content.Content() + Expect(err).To(Succeed()) + expected1 := `data: + value1: 2 + value2: orig2` + + Expect(string(result1)).To(MatchYAML(expected1)) + + Expect(content.SubstituteByData("data.value2", []byte(value2))).To(Succeed()) + + result2, err := content.Content() + Expect(err).To(Succeed()) + + expected2 := `data: + value1: 2 + value2: 3` + + Expect(string(result2)).To(MatchYAML(expected2)) + }) + It("handles complex value substitution on json", func() { value := ` value1: v1 @@ -135,11 +424,10 @@ value2: "" result, err := content.Content() Expect(err).To(Succeed()) - - fmt.Printf("\n%s\n", string(result)) - Expect(strings.Trim(string(result), "\n")).To(Equal(strings.Trim(` + expected := ` {"data": {"value1": {"value1": "v1", "value2": ""}, "value2": "orig2"}} -`, "\n"))) +` + Expect(string(result)).To(MatchJSON(expected)) }) /* @@ -198,13 +486,13 @@ data: { result, err := content.Content() Expect(err).To(Succeed()) - fmt.Printf("\n%s\n", string(result)) - Expect(strings.Trim(string(result), "\n")).To(Equal(strings.Trim(` + expected := ` data: value1: value1: v1 value2: "" value2: orig2 -`, "\n"))) +` + Expect(string(result)).To(MatchYAML(expected)) }) })